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

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

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

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

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

Уведомление об изменении стандартной модели данных WMI называется встроенным событием. __InstanceCreationEvent или __NamespaceDeletionEvent являются примерами встроенных событий. Уведомление об изменении, которое поставщик вносит для определения события поставщика, называется событием extrinsic. Например, поставщик системного реестра, поставщик событий управления питанием и поставщик 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 показаны __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 , расположенном в пространстве имен \root. Эти квоты являются глобальными, а не для каждого пространства имен. Невозможно изменить квоты.

В настоящее время 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