Получение события WMI

WMI содержит инфраструктуру событий, которая создает уведомления об изменениях в данных и службах WMI. Классы событий WMI предоставляют уведомление при возникновении определенных событий.

В этом разделе рассматриваются следующие разделы:

Запросы событий

Вы можете создать полусинхронный или асинхронный запрос для отслеживания изменений журналов событий, создания процессов, состояния службы, доступности компьютера или свободного места на диске, а также других сущностей или событий. При написании скриптов метод SWbemServices.ExecNotificationQuery используется для подписки на события. В C++используется IWbemServices::ExecNotificationQuery . Дополнительные сведения см. в разделе "Вызов метода".

Уведомление об изменении стандартной модели данных WMI называется встроенным событием. __InstanceCreationEvent или __NamespaceDeletionEvent являются примерами встроенных событий. Уведомление об изменении, которое поставщик делает для определения события поставщика, называется экстринсическим событием. Например, поставщик системных реестров, поставщик событий управления питанием и поставщик Win32 определяют собственные события. Дополнительные сведения см. в разделе "Определение типа события для получения".

Например, .

Следующий пример кода скрипта — это запрос встроенного __InstanceCreationEvent класса событий Win32_NTLogEvent. Вы можете запустить эту программу в фоновом режиме и при наличии события появится сообщение. Если закрыть диалоговое окно " Ожидание событий ", программа перестает ожидать событий. Имейте в виду, что seSecurityPrivilege должен быть включен.

Sub SINK_OnObjectReady(objObject, objAsyncContext)
    WScript.Echo (objObject.TargetInstance.Message)
End Sub

Set objWMIServices = GetObject( _
    "WinMgmts:{impersonationLevel=impersonate, (security)}") 

' Create the event sink object that receives the events
Set sink = WScript.CreateObject("WbemScripting.SWbemSink","SINK_")
 
' Set up the event selection. SINK_OnObjectReady is called when
' a Win32_NTLogEvent event occurs
objWMIServices.ExecNotificationQueryAsync sink,"SELECT * FROM __InstanceCreationEvent " & "WHERE TargetInstance ISA 'Win32_NTLogEvent' "

WScript.Echo "Waiting for events"

# Define event Query
$query = "SELECT * FROM __InstanceCreationEvent 
          WHERE TargetInstance ISA 'Win32_NTLogEvent' "

<# Register for event - also specify an action that
displays the log event when the event fires.#>

Register-WmiEvent -Source Demo1 -Query $query -Action {
                Write-Host "Log Event occured"
                $global:myevent = $event
                Write-Host "EVENT MESSAGE"
                Write-Host $event.SourceEventArgs.NewEvent.TargetInstance.Message}
<# So wait #>
"Waiting for events"

В следующем примере кода VBScript показано событие extrinsic __RegistryValueChangeEvent , которое определяет поставщик реестра. Скрипт создает временный потребитель с помощью вызова SWbemServices.ExecNotificationQueryAsync и получает события только при запуске скрипта. Следующий скрипт выполняется неограниченное время, пока компьютер не перезагрузится, WMI будет остановлен или скрипт остановлен. Чтобы остановить скрипт вручную, используйте диспетчер задач, чтобы остановить процесс. Чтобы остановить его программным способом, используйте метод Terminate в классе Win32_Process. Дополнительные сведения см. в разделе "Настройка безопасности для асинхронного вызова".

strComputer = "."

Set objWMIServices=GetObject( _
    "winmgmts:{impersonationLevel=impersonate}!\\" & strComputer & "\root\default")

set objSink = WScript.CreateObject("WbemScripting.SWbemSink","SINK_")


objWMIServices.ExecNotificationQueryAsync objSink, _
    "Select * from RegistryValueChangeEvent Where Hive = 'HKEY_LOCAL_MACHINE' and KeyPath = 'SYSTEM\\ControlSet001\\Control' and ValueName = 'CurrentUser'"

WScript.Echo "Waiting for events..."

While (True) 
     WScript.Sleep (1000)
Wend

 
WScript.Echo "Listening for Registry Change Events..." & vbCrLf 

While(True) 
    WScript.Sleep 1000 
Wend 

Sub SINK_OnObjectReady(wmiObject, wmiAsyncContext) 
    WScript.Echo "Received Registry Value Change Event" & vbCrLf & wmiObject.GetObjectText_() 
End Sub

потребители событий

События можно отслеживать или использовать с помощью следующих потребителей во время выполнения скрипта или приложения:

  • Временные потребители событий

    Временный потребитель — это клиентское приложение WMI, которое получает событие WMI. WMI включает уникальный интерфейс, который используется для указания событий для WMI для отправки в клиентское приложение. Временный потребитель события считается временным, так как он работает только при конкретной загрузке пользователем. Дополнительные сведения см. в разделе "Получение событий для длительности приложения".

  • Постоянные потребители событий

    Постоянный потребитель — это COM-объект, который всегда может получать событие WMI. Постоянный потребитель событий использует набор постоянных объектов и фильтров для записи события WMI. Как и временный потребитель событий, вы настраиваете ряд объектов WMI и фильтров, которые захватывают событие WMI. При возникновении события, соответствующего фильтру, WMI загружает объект-получатель постоянного события и уведомляет его о событии. Так как постоянный потребитель реализуется в репозитории WMI и является исполняемым файлом, зарегистрированным в WMI, постоянный потребитель событий работает и получает события после его создания и даже после перезагрузки операционной системы до тех пор, пока WMI запущен. Дополнительные сведения см. в разделе "Получение событий в любое время".

Сценарии или приложения, получающие события, имеют особые рекомендации по безопасности. Дополнительные сведения см. в разделе "Защита событий WMI".

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

Предоставление событий

Поставщик событий — это com-компонент, который отправляет событие в WMI. Вы можете создать поставщик событий для отправки события в приложении C++ или C#. Большинство поставщиков событий управляют объектом для WMI, например приложением или аппаратным элементом. Дополнительные сведения см. в разделе "Написание поставщика событий".

Событие времени или повторения — это событие, которое происходит в определенное время.

WMI предоставляет следующие способы создания временных или повторяющихся событий для приложений:

  • Стандартная инфраструктура событий Майкрософт.
  • Специализированный класс таймера.

Дополнительные сведения см. в разделе "Получение события по времени" или "Повторяющееся". При написании поставщика событий учитывайте сведения о безопасности, определенные в разделе "Безопасное предоставление событий".

Рекомендуется скомпилировать постоянные подписки на события в пространство имен \root\subscription. Дополнительные сведения см. в разделе "Реализация подписок на постоянные события между пространствами имен".

Квоты подписки

Опрос событий может снизить производительность поставщиков, поддерживающих запросы к огромным наборам данных. Кроме того, любой пользователь, имеющий доступ на чтение к пространству имен с динамическими поставщиками, может выполнить атаку типа "отказ в обслуживании" (DoS). WMI поддерживает квоты для всех пользователей, объединенных и для каждого потребителя событий в одном экземпляре __ArbitratorConfiguration , расположенном в корневом пространстве имен. Эти квоты являются глобальными, а не для каждого пространства имен. Нельзя изменить квоты.

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

Total/PerUser Quota
TemporarySubscriptionsTotal
TemporarySubscriptionsPerUser
10 000
1000
PermanentSubscriptionsTotal
PermanentSubscriptionsPerUser
10 000
1000
PollingInstructionsTotal
PollingInstructionsPerUser
10 000
1000
PollingMemoryTotal
PollingMemoryPerUser
10 000 000 (0x989680) байт
5 000 000 (0x4CB40) байт

Администратор или пользователь с разрешением FULL_WRITE в пространстве имен может изменить одноэлементный экземпляр __ArbitratorConfiguration. WMI отслеживает квоту на пользователя.

Использование WMI