Ваш гид по работе с событиями Windows WMI и PowerShell

Вы знали, что вы можете отслеживать практически каждое действие в Windows? Нет, вам не нужно покупать какое-то фантазийное программное обеспечение. Инфраструктура отслеживает события, такие как запуск и остановка служб, создание файла или папки и многое другое, уже доступно через события Windows Management Instrumentation (WMI).

События WMI не являются функцией, специфичной только для PowerShell, но одним из самых простых способов использовать события WMI и создавать удобные инструменты является PowerShell. В этом пошаговом руководстве вы узнаете, как воспользоваться событиями WMI с помощью PowerShell и получите навыки построения некоторых удобных инструментов мониторинга!

Давайте начнем!

Предварительные требования

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

  • Windows 7+ или Windows Server 2012+ – В этом руководстве будет использоваться Windows Server 2019.
  • Войдите в систему как пользователь в группе локальных администраторов.
  • Windows PowerShell 5.1 или PowerShell 6+ – В этом руководстве будет использоваться PowerShell v7.1.2.

Понимание WMI и CIM

Прежде чем приступить к событиям WMI, важно сначала понять инфраструктуру, на которой они построены. Хотя это руководство не будет углубляться в WMI, вы всегда можете обратиться к документации WMI от Microsoft, чтобы узнать больше.

ВМИ и связанная с ним модель данных Общая информационная модель (CIM) встроены в Windows и хранят практически любую информацию в хранилище, связанную с внутренней работой Windows и тем, что на ней запущено.

ВМИ и CIM – мощные инструменты, которые администраторы используют для управления Windows как локально, так и удаленно. С использованием ВМИ или CIM администраторы могут запрашивать информацию о системе Windows, такую как установленные приложения, статус служб, файлы в файловой системе и многое другое.

ВМИ и CIM – это способы, с помощью которых многие решения для мониторинга предприятий собирают информацию об операционной системе и состоянии приложений. Но вам не нужно покупать дорогой инструмент мониторинга, чтобы использовать ВМИ; у вас есть PowerShell!

Давайте начнем с двух основных элементов, и по мере продвижения вы узнаете о других необходимых элементах:

  • Классы: Классы – это события и свойства, которые приложение, такое как PowerShell, может вызывать для чтения и обновления данных. Классы находятся внутри пространства имен.
  • Пространство имен: Пространство имен – это контейнер для классов, связанных с ВМИ. Думайте о нем как о папке “Мои изображения”, содержащей контент, связанный с изображениями. Есть несколько пространств имен, и наиболее распространенным из них является CIMv2, которое содержит большинство классов ОС. Но все пространства имен находятся под одним большим пространством имен Root.
WMI Architecture

ВМИ против CIM

WMI и CIM – это оба способа взаимодействия с репозиторием на системе Windows, содержащим огромное количество информации, и работы с событиями WMI (о них будет рассказано позже). Однако, у обоих методов есть несколько отличий, главным образом в способе удаленного взаимодействия администраторов.

WMI начался с Windows NT4 и был первоначальным (и единственным) способом взаимодействия с репозиторием. При управлении системой Windows с помощью WMI, Windows использует распределенную объектную модель компонентов (DCOM). DCOM – это протокол удаленного доступа, который WMI использует для предоставления информации внутри репозитория данных на компьютере с Windows.

Для работы через сеть DCOM использует удаленный вызов процедур (RPC). Для обмена данными по сети RPC использует динамический диапазон портов, что иногда является проблемой для брандмауэров и устройств сетевого адреса (NAT).

Если у вас возникли проблемы с RPC, ознакомьтесь со статьей Тестирование соединений RPC с динамическими портами.

Microsoft решила использовать CIM для обеспечения более современного подхода к взаимодействию с репозиторием данных в Windows. Вместо RPC CIM использует протокол HTTP WS-MAN (Web-Service for Management), который намного лучше подходит для удаленного управления.

В этой и других статьях термины WMI и CIM могут использоваться взаимозаменяемо. Репозиторий данных, с которым взаимодействуют оба метода управления, обычно называется репозиторием WMI. Почти все термины относятся к WMI, в то время как CIM обычно используется в командных сценариях PowerShell.

Сравнение WMI и CIM с PowerShell

К счастью, у вас есть несколько вариантов взаимодействия с репозиторием данных с помощью WMI и CIM в PowerShell. PowerShell поддерживает оба способа взаимодействия. При выполнении команды Get-Command в PowerShell вы можете заметить различные командлеты Wmi, такие как Get-WmiObjectInvoke-WmiMethodRemove-WmiObjectRegister-WmiEvent и Set-WmiInstance.

Если вы используете Windows PowerShell 3 или более позднюю версию (что вам лучше делать!), вы также увидите несколько похожих по названию командлетов, таких как Get-CimInstance, Get-CimClass и Remove-CimInstance.

Какие командлеты PowerShell следует использовать? Ответ прост – командлеты CIM. CIM – это новый стандарт, на который сосредоточена Microsoft. Командлеты WMI даже не доступны в PowerShell Core!

Запрос WMI: Основы

Прежде чем приступить к событиям WMI, необходимо понять, как выполнять запросы WMI с помощью PowerShell. Запрос информации из репозитория WMI – самое распространенное использование данных WMI.

Для выполнения запросов данных WMI в мире PowerShell вашим другом является Get-CimInstance cmdlet. У этой cmdlet есть несколько способов запроса данных WMI. Однако этот учебник сосредоточится на параметре Query. Параметр Query позволяет вам предоставить язык запросов Windows (WQL) для выполнения запросов WMI.

Например, возможно, вам хочется найти все экземпляры WMI в классе Win32_Service. Аналогично SQL, вы бы использовали запрос Select * from Win32_Service, как показано ниже. Звездочка (*) говорит WMI вернуть все свойства каждого найденного экземпляра.

Get-CimInstance -Query 'Select * from Win32_Service'
Getting Windows Services using WMI Query

В приведенном выше примере вы нашли все экземпляры каждого сервиса в классе Win32_Service, но что, если вам нужны только несколько? В этом случае вы бы использовали WHERE clause. Оператор WHERE создает фильтр, чтобы возвращать только экземпляры, соответствующие определенному условию.

`WHERE` оператор сообщает `Get-CimInstance` вернуть только те экземпляры, где свойство экземпляра соответствует определенному значению. Например, возможно, вам нужно найти только экземпляры служб, где свойство `State` равно `Running`. Если это так, вы бы определили оператор `WHERE` как `Where State=’Running’`, как показано ниже.

Get-CimInstance -Query "Select * from Win32_Service Where State='Running'"

Вы можете видеть ниже, что `Get-CimInstance` вернул только экземпляры служб, где свойство `State` было равно `Running`.

Returning only service that are in Running state

События WMI: Действия WMI

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

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

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

Создание сценария мониторинга служб с помощью PowerShell

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

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

Вместо покупки дорогостоящего средства мониторинга простой сценарий PowerShell может быть отличным инструментом бедного человека для мониторинга! Если вы готовы, откройте консоль PowerShell и давайте начнем!

Поиск CIM-класса

Внутри WMI, как и статические экземпляры, события содержатся в классах. Эти классы содержат всю статическую информацию, которую вы запросили выше, и там, где вызываются изменения этих экземпляров. Вы можете найти список всех классов CIM в документации Microsoft.

Чтобы найти все классы CIM, выполните Get-CimClass cmdlet без параметров. Cmdlet Get-CimClass по умолчанию возвращает все классы в пространстве имен ROOT/cimv2. Пространство имен ROOT/cimv2 – это “основное” пространство имен, в котором хранятся почти все интересные классы Windows.

Get-CimClass

Однако вы можете видеть ниже, что возвращается много классов.

Finding the CIM Class

Возможно, вы уже занимались изучением и, наконец, поняли, что службы Windows хранятся в Win32_Service. Так что, когда вы знаете имя класса, используйте параметр ClassName, чтобы указать имя, как показано ниже.

Get-CimClass -ClassName Win32_Service
Get CimClass Parameter

Поиск свойств CIM-класса

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

Чтобы найти это свойство, изучите свойство объекта PowerShell CimClassProperties на экземпляре класса CIM, который вы запросили в предыдущем разделе.

(Get-CimClass -ClassName win32_Service).CimClassProperties

Обратите внимание, что одним из этих свойств является свойство State.

Some of the Win32_Service Properties

Теперь, когда вы знаете, какой CIM-класс и свойство вы хотите отслеживать, пришло время подписаться на событие WMI!

Создание подписки на событие WMI: Общий обзор

Создание подписки на событие WMI может быть запутанной задачей, если вы никогда раньше не создавали ее. Чтобы помочь вам держать действия в порядке, давайте сначала рассмотрим лес перед деревьями и опишем основные шаги.

Создание подписки на событие WMI требует четырех приблизительных шагов:

  1. Создание запроса WQL – Точно так же, как при запросе статических данных, вам нужно создать запрос WQL, который будет соответствовать типу события WMI, которое вы хотели бы увидеть. Однако, в отличие от запроса хранилища данных, вам придется использовать несколько более сложных компонентов в запросе, таких как системные классы и проверка циклов (о них позже).
  2. Создание фильтра событий – После создания запроса WQL вам нужно создать фильтр событий. Фильтр событий регистрирует запрос WQL в CIM.
  3. Создание потребителя – Потребитель определяет действие, которое будет выполнено, когда запрос фильтра событий вернет изменение класса. Например, когда статус службы запускается, останавливается, создается или удаляется, потребитель инициирует действие.
  4. Привязка фильтра событий к потребителю – Связующее звено, которое соединяет запрос Windows WMI с потребителем. Привязка сообщает потребителю, когда фильтр событий получил совпадение.

Когда вы объединяете каждый из этих элементов, вы создаете подписку.

Basic example of a WMI event subscription

Создание запроса WQL

A WQL query for a WMI event looks a bit different than performing a simple query with Get-CimInstance. Below you’ll find a typical WMI event query.

Select * from <system class> within <checking cycle> where TargetInstance ISA '<class name>'

Поскольку запрос WQL может показаться вам сложным сначала, давайте разберемся и поймем, как работает каждый компонент.

Системный класс

В примере Get-CimInstance вы обнаружили, что хотите получать уведомления о изменениях в экземпляре класса Win32_Service. Вам все еще нужен этот класс, но вместо запроса WQL, который выглядит так:

Select * from Win32_Service

Вместо этого, запрос будет начинаться так, как показано ниже. Основным классом, на который вы делаете запрос, не является класс, содержащий экземпляр, на котором вы хотите получить уведомление. Вместо этого, это системный класс.

Select * from <system class>

Системные классы – это внутренний класс, представляющий тип изменений, вызываемых событием. В событии WMI есть четыре типа системных классов:

  • InstanceModificationEvent Проверяет любые изменения значений свойств экземпляра в классе. Именно этот класс вы будете использовать, потому что вы хотите отслеживать значение свойства Status на экземпляре (службе) класса Win32_Service.
  • InstanceCreationEvent – Проверяет создание новых экземпляров. Например, если вы хотите отслеживать создание новых служб, вы будете использовать этот системный класс.
  • InstanceDeletionEvent – Проверяет удаление экземпляров. Например, если вы хотите отслеживать удаление служб, вы будете использовать этот системный класс.
  • InstanceOperationEvent – Этот системный класс проверяет все типы событий: изменение, создание и удаление.

Для нашего скрипта мониторинга начало запроса WQL будет выглядеть следующим образом:

Select * from __InstanceModificationEvent

Имена классов системы WMI всегда начинаются с двух подчеркиваний (__) перед именем класса.

Цикл проверки

Далее идет цикл проверки. Цикл проверки включает ключевое слово within и значение, представляющее интервал опроса, выраженный в секундах.

within <checking cycle>

События WMI не являются мгновенными, поэтому вы должны определить определенный интервал для вашей подписки на проверку изменений. Если, например, вы установите цикл проверки равным 10, подписка будет проверять изменение с последнего цикла опроса каждые 10 секунд. Если изменение обнаружено, оно вызывает действие потребителя.

Если экземпляр изменен, создан или удален в пределах интервала опроса, изменение не будет обнаружено! Рассмотрите необходимую частоту, но убедитесь, что она не нагружает процессор и память!

Для примера мониторинга службы в учебнике давайте установим цикл проверки равным 10 для опроса WMI каждые 10 секунд для изменения службы Windows. Запрос WQL растет!

Select * from __InstanceModificationEvent within 10

Фильтр

Наконец, чтобы завершить запрос WQL, вы должны определить фильтр, чтобы ограничить возвращаемые экземпляры из системного класса. Вы должны определить этот фильтр в форме ниже. В этом случае класс CIM, который вы хотите отслеживать, называется TargetInstance.

where Targetinstance ISA '<class name>'

ISA – это оператор, который применяет запрос к подклассам указанного класса.

Поскольку в учебнике создается подписка для отслеживания служб Windows, вы создадите фильтр, как показано ниже:

where Targetinstance ISA 'Win32_Service'

Как есть, фильтр ищет все вхождения Win32_Service. Если вы хотите отслеживать только одно свойство, возможно, конкретный сервис, используйте оператор AND.

where Targetinstance ISA 'win32_Service' AND Targetinstance.name='bits'

Операторы AND или OR добавляют другие условия для получения более точных результатов.

Фильтр учебного пособия (и вся запрос) теперь завершен в виде следующего фрагмента кода.

Select * from __InstanceModificationEvent within 10 where Targetinstance ISA 'win32_Service' AND Targetinstance.name='bits'

Создание фильтра событий

Теперь, когда у вас есть фильтр запроса, остальная часть процесса становится намного понятнее! Теперь вам нужно создать фильтр событий для использования этого запроса. Фильтр событий на самом деле является еще одним экземпляром CIM, который является частью класса __EventFilter в пространстве имен Root/subscription.

Ниже вы можете увидеть фрагмент кода со всем необходимым. Нижеследующий скрипт присваивает запрос WQL переменной $FilterQuery. Затем он создает хеш-таблицу, содержащую каждое из необходимых свойств и значений, необходимых для фильтра событий. Затем запускается New-CimInstance cmdlet для создания фильтра событий.

Результирующий объект CIM-экземпляра затем сохраняется в переменной ($CIMFilterInstance) для последующего использования.

$FilterQuery="Select * from __InstanceModificationEvent within 10 where TargetInstance ISA 'Win32_Service'"
$CIMEventFilterProperties = @{
	## Название фильтра событий. Это может быть что угодно связанное.
	Name="MyServiceFilter"
	## Пространство имен для целевого класса, например, целевой класс для
	## **Win32_Service** является Root/CIMv2
	EventNameSpace="Root/CIMV2"
	## Язык запросов, обычно **WQL**.
	QueryLanguage="WQL"
	## Запрос для использования.
	Query=$FilterQuery
}

$CIMFilterInstance=New-CimInstance -ClassName __EventFilter -Namespace "Root/SubScription" -Property $CIMEventFilterProperties

Теперь запустите Get-CimInstance, чтобы проверить, что новый CIM-экземпляр __EventFilter был создан.

Get-CimInstance -Namespace root/subscription -ClassName __EventFilter
Event Filter Created Successfully and registered the Windows WMI Query

Создание Консьюмера

Теперь пришло время создать консьюмера или действие, которое произойдет, когда Windows запустит событие WMI. При создании консьюмера у вас есть несколько вариантов в зависимости от типа действия, которое вы хотели бы вызвать.

Убедитесь, что права доступа к исполняемому файлу определены правильно, чтобы предотвратить замену файла EXE вредоносным двоичным файлом.

Для этого урока давайте использовать тип потребителя LogFileEventConsumer для записи в журнал файлов, когда изменяется служба, соответствующая запросу WQL.

$CIMCOnsumerProperties = @{
	## Имя, под которым сценарий будет зарегистрирован в пространстве имен **Root/Subscription**
	Name="MyServiceConsumer"
	## Путь и имя файла, в который будет записано сообщение при срабатывании события.
	FileName="C:\\MyCIMMonitoring.txt"
	## Текст, который будет записан в журнале. Вы можете добавить переменную, используя
	## %TargetInstance.WMIProperty%. В этом примере используются **Caption** и **State**.
	## Примеры других потребителей
	Text = "The Service %TargetInstance.Caption% has been Changed: %TargetInstance.State%"
}
$CIMEventConsumer=New-CimInstance -ClassName LogFileEventConsumer -Namespace 'ROOT/subscription' -Property $CIMCOnsumerProperties

## Примеры других потребителей
######################
## Потребитель NTEventLog
######################
## $Template = @(
##	'Служба %TargetInstance.Caption% была изменена: %TargetInstance.State%'
##)
##$CIMCOnsumerProperties=@{
## ## Имя потребителя
##	Name="МойПотребительЖурналаСобытий"
## ## Идентификатор события для использования
##	EventID =[UInt32] 7040
##  ТипСобытия может принимать одно из следующих значений
##    ## - **0**: Успешное событие
##    ## - **1**: Ошибка
##    ## - **2**: Предупреждение
##    ## - **4**: Информация
##    ## - **8**: Успешная проверка безопасности
##    ## - **16**: Ошибка проверки безопасности
##  EventType=[UInt32] 1 #Информация
## ## Имя источника события.
##  SourceName="МенеджерУправленияСлужбами"
##  Category=[UInt16] 0
##  ## Количество строк **InsertionStringTemplates**
##  NumberOfInsertionStrings =[UInt32] $Template.Length
##  ## Сообщение для записи в журнал событий Windows.
##  InsertionStringTemplates = $Template
##}
## $CIMEventConsumer=New-CimInstance -ClassName NTEventLogEventConsumer -Namespace 'ROOT/subscription' -Property $CIMCOnsumerProperties

######################
## Потребитель CommandLine
######################
## $CIMCOnsumerProperties=@{
##  ## Уникальное имя потребителя.
##	Name="МойПотребительЗапускПриложения"
##  ## Путь и параметры запуска приложения при срабатывании события.
##	CommandLineTemplate ='pwsh.exe c:\\myscript.ps1 -ServiceName %TargetInstance.name% -NewState %TargetInstance.State%'
##  ## (По выбору) Завершение работы приложения после заданного количества секунд. Это полезно для защиты ресурсов сервера.
##  ## KillTimeout = 5 
##}
##$CIMEventConsumer=New-CimInstance -ClassName CommandLineEventConsumer  -Namespace 'ROOT/subscription' -Property $CIMCOnsumerProperties

######################
## Потребитель SMTP
######################
## Текст сообщения электронной почты
## $Message= 'Файловый сервер изменен %Targetinstance.Name% , %TargetInstance.Status%'

## $CIMCOnsumerProperties=@{
##	Name="МойСервис-ПотребительЭлектроннойПочты"
##	## Адрес электронной почты отправителя.
##	FromLine ='[email protected]'
##	## Адрес электронной почты получателя.
##	ToLine = 'МояПочта@МояКомпания.com'
##	## SMTP-сервер для отправки сообщения.
##	SMTPServer = 'МойSMTPСервер.МойДомен.com'
##	## Тема сообщения
##	Subject = 'Файловый сервер изменен…'
##	Message= $Message
##}
##$CIMEventConsumer=New-CimInstance -ClassName SMTPEventConsumer   -Namespace 'ROOT/subscription' -Property $CIMCOnsumerProperties

Каждый класс потребителя имеет свои собственные параметры, поэтому проверьте CimClassProperties для получения более подробной информации о каждом классе, например, (Get-CimClass -ClassName __NTEventLogEventConsumer).CimClassProperties.

После создания потребителя снова проверьте его существование с помощью Get-Ciminstance.

Get-CimInstance -Namespace Root/Subscription -ClassName LogFileEventConsumer
Consumer Registered with the required parameters

Привязка фильтра событий и потребителя вместе

Наконец, пришло время завершить эту подписку и связать фильтр событий и потребителя вместе! Как вы могли догадаться, создание привязки означает создание еще одного экземпляра CIM. На этот раз вам необходимо создать новый экземпляр в классе __FilterToConsumerBinding.

Приведенный ниже фрагмент кода использует два ранее созданных экземпляра (фильтр и потребитель) в качестве хэш-таблицы, которая определяет необходимые свойства для создания нового экземпляра. Затем он передается New-CimInstance, как и раньше, для создания привязки.

$CIMBindingProperties=@{
	Filter = [Ref]$CIMFilterInstance
	Consumer = [Ref]$CIMEventConsumer
}

$CIMBinding = New-CimInstance -ClassName __FilterToConsumerBinding -Namespace "root/subscription" -Property $CIMBindingProperties

Как всегда, убедитесь, что привязка была создана, запустив Get-CimInstance снова.

Get-CimInstance -Namespace Root/Subscription -ClassName __FilterToConsumerBinding

Как видите, привязка содержит информацию как о Filter, так и о Consumer.

Binding Details

Тестирование подписки

Вы наконец-то закончили! Пришло время протестировать плоды вашего труда! Единственное, что вам нужно сделать сейчас, это изменить статус службы BITS, чтобы увидеть, пишет ли PowerShell запись в журнальный файл по адресу C:\MyCIMMonitoring.txt.

В зависимости от статуса службы BITS либо остановите ее, либо запустите ее снова, или просто перезапустите с помощью командлета Restart-Service.

Get-Service -Name BITS | Restart-Service

Подождите около 10 секунд и проверьте C:\MyCIMMonitoring.txt. Теперь вы должны увидеть Текст в журнальном файле, который вы определили при создании потребителя.

Get-Content -Path C:\MyCIMMonitoring.txt
Service Changes are detected

Чтобы отслеживать всю активность событий WMI, проверьте журнал событий Windows по пути Приложения и сервисы\Log\Microsoft\Windows\WMI-Activity\Operational.

Остановка и очистка подписки

Как только вы закончили с подпиской, пришло время ее очистить. Чтобы остановить и удалить подписку на события WMI, необходимо удалить экземпляры фильтра событий, потребителя и привязки.

Удалите фильтр событий, сначала найдя экземпляр с помощью Get-CimInstance.

Get-CimInstance -Namespace Root/Subscription -ClassName __EventFilter | Remove-CimInstance

## Для более чем одного экземпляра
Get-CimInstance -Namespace Root/Subscription -ClassName __EventFilter | where {$.name -like "MyServiceFilter"} | Remove-CimInstance
Registered EventFilter

Затем удалите потребителя таким же образом.

Get-CimInstance -Namespace Root/Subscription -ClassName LogFileEventConsumer | Remove-CimInstance

## Для более чем одного экземпляра
Get-CimInstance -Namespace Root/Subscription -ClassName LogFileEventConsumer | where {$_.Name -like "MyServiceConsumer"} | Remove-CimInstance
Getting Consumer from the LogFileEventConsumer Class

Наконец, удалите привязку. Свойство для поиска привязки немного отличается. Вместо свойства Name экземпляр привязки имеет свойство Filter, которое на самом деле является объектом с свойством Name.

Get-CimInstance -Namespace Root/Subscription -ClassName __FilterToConsumerBinding | Where-Object {$_.Filter.Name -like "MyServiceFilter"} | Remove-CimInstance
Getting the Binding information.

Заключение

WMI/CIM – это удобная и мощная система для получения информации о Windows и мониторинга ее с помощью событий WMI. Мониторинг изменений с помощью событий WMI обеспечивает отличную видимость и более быструю реакцию на возможные проблемы, что облегчает автоматизацию ответа на каждое событие.

Для прекрасного примера из реальной жизни ознакомьтесь с Как отслеживать изменения в Active Directory с помощью событий WMI.

Source:
https://adamtheautomator.com/your-goto-guide-for-working-with-windows-wmi-events-and-powershell/