Поделиться через


Получение события 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 показано внешнее событие __RegistryValueChangeEvent, которое определяет поставщик реестра. Скрипт создает временного потребителя с помощью вызова SWbemServices.ExecNotificationQueryAsyncи получает события только тогда, когда скрипт выполняется. Следующий скрипт выполняется неограниченное время, пока компьютер не перезагружается, WMI останавливается или скрипт останавливается. Чтобы остановить скрипт вручную, используйте диспетчер задач для остановки процесса. Чтобы остановить его программным способом, используйте метод Stop в классе 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 включает уникальный интерфейс, который используется для задания событий, отправляемых клиентскому приложению. Временный потребитель событий считается временным, так как он работает только при конкретной загрузке пользователем. Чтобы получить дополнительную информацию, см. раздел Получение событий на протяжении работы вашего приложения.

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

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

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

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

Проведение мероприятий

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

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

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

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

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

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

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

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

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

Итого/На пользователя Квота
ОбщаяВременнаяПодписка
Временные подписки на пользователя
10,000
1,000
Общее количество постоянных подписок
Постоянные подписки на пользователя
10 000
1,000
Общие инструкции по голосованию
ИнструкцииПоОпросуДляПользователя
10 000
1,000
ОбщийОбъемПамятиДляОпроса
ОпросMemoryPerUser
10 000 000 (0x989680) байт
5 000 000 (0x4CB40) байт

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

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