PowerShell WMI: Автоматизация задач Windows

Средство управления Windows (WMI) существует в Windows уже долгое время. Многие специалисты в области информационных технологий использовали WMI напрямую или воспользовались инструментами, которые считывают информацию из WMI. Знали ли вы, что встроенные в PowerShell WMI-кмлеты?

WMI – это фактическое место для получения информации о компьютере под управлением Windows и управления различными службами внутри Windows. Благодаря обширной информации WMI, вы можете использовать PowerShell WMI. Использование PowerShell для опроса WMI позволяет автоматизировать тысячи задач на компьютерах под управлением Windows.

К счастью, одной из первых систем в Windows, для которой были созданы команды PowerShell, была WMI. Поскольку у вас есть встроенные кмлеты PowerShell WMI, это означало, что IT-администратор мог использовать легко читаемый синтаксис глагол/существительное PowerShell для взаимодействия с WMI, и, как вы увидите, опытные пользователи также могут вызывать события и классы WMI непосредственно, просто используя стандартные команды PowerShell.

Кмлеты PowerShell WMI против CIM

Существует два “набора” команд при использовании WMI в PowerShell. Некоторые люди называют эти “наборы” “старым” способом взаимодействия с WMI и кмлетами CIM. При запросе информации из WMI оба возвращают одну и ту же информацию, но подходят к ней немного по-разному. “Старый” способ считывания информации из WMI заключается в использовании команды Get-WmiObject. Другие кмлеты WMI включают Invoke-WmiMethod, Register-WMIEvent и так далее, но мы не будем рассматривать их в нашей статье.

Командлет PowerShell WMI Get-WmiObject работает, но имеет серьезный недостаток. При запросе к удаленным компьютерам он зависит от DCOM, который исторически был вектором атак для злоумышленников. DCOM обычно блокируется различными брандмауэрами. Поскольку это “старый” способ, мы не будем рассматривать этот метод. Вместо этого мы сосредоточимся на командлетах CIM, прежде всего, Get-CimInstance.

DCOM Component Services

Основное различие между Get-WmiObject и Get-CimInstance заключается в том, что вместо использования DCOM для доступа к удаленным компьютерам, Get-CimInstance использует протокол WSMAN, который является транспортом для знакомой функции удаленного выполнения PowerShell.

Командлеты CIM PowerShell

Допустим, вы хотите получить информацию о версии Windows на удаленном компьютере. В этом случае я бы хотел увидеть некоторую информацию с компьютера с именем DC. Вы можете сделать это, указав класс WMI, содержащий информацию, и имя компьютера, которое вы хотели бы запросить.

Как видно ниже, поскольку Get-CimInstance по умолчанию не отображает все атрибуты внутри класса, мне пришлось направить вывод на команду Select-Object, чтобы вернуть все свойства.

PS> Get-CimInstance -ClassName Win32_OperatingSystem -ComputerName DC | Select *
Status                                    : OK
Name                                      : Microsoft Windows 10 Pro|C:\WINDOWS|\Device\Harddisk0\Partition2
FreePhysicalMemory                        : 1802336
FreeSpaceInPagingFiles                    : 800308
FreeVirtualMemory                         : 1472916
Caption                                   : Microsoft Windows 2016
Description                               :
InstallDate                               : 7/5/2018 6:04:09 PM
CreationClassName                         : Win32_OperatingSystem
CSCreationClassName                       : Win32_ComputerSystem
--snip-

Не только можно собирать информацию через свойства, но также можно вызывать методы WMI/CIM для классов. Хорошим примером этого является остановка процесса на удаленном компьютере. Встроенным образом это невозможно сделать с помощью команды Stop-Process в PowerShell. Однако это можно сделать с помощью запроса WMI. Чтобы завершить удаленные процессы, сначала нужно определить, какой процесс вы хотите завершить. Мы можем перечислить все выполняющиеся процессы на удаленном компьютере, рассматривая класс Win32_Process.

PS> Get-CimInstance -ClassName CIM_Process -ComputerName DC

ProcessId Name                                      HandleCount WorkingSetSize VirtualSize   PSComputerName
--------- ----                                      ----------- -------------- -----------   --------------
0         System Idle Process                       0           4096           65536         DC
4         System                                    631         212992         3465216       DC
232       smss.exe                                  52          823296         4325376       DC
328       csrss.exe                                 258   om      3346432        49483776      DC
392       csrss.exe                                 87          2789376        44507136      DC
400       wininit.exe                               80          3072000        2199065096192 DC
428       winlogon.exe                              119         4431872        2199079510016 DC

Как только вы определите процесс для завершения, вы можете передать его имя методу Terminate() класса Win32_Process. Для этого вам нужно захватить экземпляр процесса, который вы хотите завершить.

Обратите внимание, что ниже я использую параметр Filter, чтобы удостовериться, что я получаю только процесс ccmexec.exe. Это важно!

После того как вы захватили экземпляр, вы можете вызвать метод Terminate() для завершения процесса с использованием команды Invoke-CimMethod, как показано ниже.

PS> $instance = Get-CimInstance -ClassName CIM_Process -ComputerName DC -Filter 'Name = "ccmexec.exe"'
PS> $instance

ProcessId Name        HandleCount WorkingSetSize VirtualSize PSComputerName
--------- ----        ----------- -------------- ----------- --------------
3528      CcmExec.exe 878         34246656       158261248   DC


PS> Invoke-CimMethod -InputObject $instance -MethodName Terminate

ReturnValue PSComputerName
----------- --------------
          0 DC

Итог

Если вы хотите узнать больше о использовании WMI в PowerShell, особенно о использовании cmdlet PowerShell WMI Get-WmiObject, о чем здесь не было упомянуто, я предлагаю ознакомиться с Get-WmiObject: Запрос WMI на локальных и удаленных компьютерах, где я более подробно рассматриваю WMI и использую cmdlet Get-WmiObject.

Для полного разбора всех CIM-командлетов и их работы в PowerShell обратитесь к статье Введение в CIM-командлеты на Technet. Там вы увидите все различные CIM-командлеты и как они могут быть использованы в ваших сценариях.

Source:
https://adamtheautomator.com/powershell-wmi/