监视事件

系统管理员可以使用 WMI 监视网络上的事件。 例如:

  • 服务意外停止。
  • 服务器变得不可用。
  • 磁盘驱动器的已用容量已达到 80%。
  • 安全事件将报告给 NT 事件日志。

WMI 支持事件检测和传递给事件使用者,因为某些 WMI 提供程序是事件提供程序。 有关详细信息,请参阅接收 WMI 事件

事件使用者是特定的应用程序或脚本,它们请求事件通知,然后在发生特定事件时执行任务。 可以创建事件监视脚本或应用程序,用于在事件发生时进行临时监视。 WMI 还提供一组预安装的永久事件提供程序和永久使用者类,使你能够永久监视事件。 有关详细信息,请参阅借助标准使用者监视和响应事件

本主题包括以下部分:

使用临时事件使用者

临时事件使用者是脚本或应用程序,它们返回与事件查询或筛选器匹配的事件。 临时事件查询通常在 C++ 应用程序中使用 IWbemServices::ExecNotificationQuery,在脚本和 Visual Basic 中使用 SWbemServices.ExecNotificationQuery

事件查询请求指定特定事件类型的事件类的实例,例如 Win32_ProcessTraceRegistryKeyChangeEvent

以下 VBScript 代码示例在创建 Win32_ProcessTrace 实例时请求通知。 启动或停止进程时,会生成此类的实例。

若要执行脚本,请将其复制到名为 event.vbs 的文件,然后使用以下命令行:cscript event.vbs。 可以通过启动 Notepad.exe 或任何其他进程来查看脚本的输出。 在五个进程已启动或停止后,脚本停止。

此脚本调用 SWbemServices.ExecNotificationQuery,这是方法的半同步版本。 有关通过调用 SWbemServices.ExecNotificationQueryAsync 设置异步临时事件订阅的示例,请参阅下一个脚本。 有关详细信息,请参阅调用方法。 此脚本调用 SWbemEventSource.NextEvent 来获取和处理每个事件,因为它到达。 将脚本保存在扩展名为 .vbs 的文件中,并使用 CScript 在命令行上运行脚本:cscript file.vbs。

strComputer = "." 
Set objWMIService = GetObject("winmgmts:\\" _
    & strComputer & "\root\CIMV2") 
Set objEvents = objWMIService.ExecNotificationQuery _
    ("SELECT * FROM Win32_ProcessTrace")

Wscript.Echo "Waiting for events ..."
i = 0
Do Until i=5
    Set objReceivedEvent = objEvents.NextEvent
    'report an event
    Wscript.Echo "Win32_ProcessTrace event occurred" & VBNewLine _
        & "Process Name = " _
            & objReceivedEvent.ProcessName & VBNewLine _
        & "Process ID = " _
            & objReceivedEvent.Processid & VBNewLine _
        & "Session ID = " & objReceivedEvent.SessionID 
i = i+ 1
Loop

必须手动启动临时事件使用者,并且不得在 WMI 重启或操作系统重启之间保留。 临时事件使用者只能在运行时处理事件。

以下过程介绍了如何创建临时事件使用者类。

创建临时事件使用者

  1. 确定要使用的编程语言。

    编程语言确定要使用的 API。

  2. 按照与启动 WMI 应用程序相同的方式开始对临时事件使用者应用程序进行编码。

    编码的第一步取决于编程语言。 通常需要登录到 WMI 并设置安全设置。 有关详细信息,请参阅创建 WMI 应用程序或脚本

  3. 定义要使用的事件查询。

    若要获取某些类型的性能数据,可能需要使用高性能提供程序提供的类。 有关详细信息,请参阅监视性能数据确定要接收的事件的类型使用 WQL 进行查询

  4. 决定进行异步调用或半同步调用,并选择 API 方法。

    通过异步调用,可以避免轮询数据的开销。 但是,半同步调用提供类似的性能和更高的安全性。 有关详细信息,请参阅调用方法

  5. 进行异步或半同步方法调用,并作为 strQuery 参数包含事件查询。

    对于 C++ 应用程序,请调用以下方法:

    对于脚本,请调用以下方法:

  6. 编写代码以处理返回的事件对象。

    对于异步事件查询,将代码放入对象接收器的各种方法或事件中。 对于半同步事件查询,当 WMI 获取每个对象时,将返回每个对象,因此代码应位于处理每个对象的循环中。

以下脚本代码示例是 Win32_ProcessTrace 脚本的异步版本。 由于异步操作会立即返回,因此对话框在脚本等待事件时保持活动状态。

脚本具有 SWbemSink OnObjectReady 事件的事件处理程序,而不是调用 SWbemEventSource.NextEvent 来接收每个事件。

strComputer = "." 
Set objWMIService = GetObject("winmgmts:\\" & _
    strComputer & "\root\CIMV2") 
Set EventSink = WScript.CreateObject( _
    "WbemScripting.SWbemSink","SINK_")

objWMIservice.ExecNotificationQueryAsync EventSink, _
    "SELECT * FROM Win32_ProcessTrace WITHIN 10"
WScript.Echo "Waiting for events..."

i = 0
While (True)
    Wscript.Sleep(1000)
Wend

Sub SINK_OnObjectReady(objObject, objAsyncContext)
    Wscript.Echo "Win32_ProcessTrace event has occurred."
    i = i+1
    If i = 3 Then WScript.Quit 0 
End Sub

注意

异步回调(例如由 SINK_OnObjectReady 子例程处理的回调)允许未经身份验证的用户向接收器提供数据。 为了提高安全性,请使用半同步通信或同步通信。 有关详情,请参阅以下主题:

 

使用永久事件使用者

永久事件使用者将一直运行,直到其注册被显式取消,然后在 WMI 或系统重启时启动。

永久事件使用者是系统上 WMI 类、筛选器和 COM 对象的组合。

以下列表标识创建永久事件使用者所需的部分:

  • 包含实现永久使用者的代码的 COM 对象。
  • 新的永久使用者类。
  • 永久使用者类的实例。
  • 包含事件查询的筛选器。
  • 使用者与筛选器之间的链接。

有关详细信息,请参阅随时接收事件

WMI 提供多个永久使用者。 已预安装包含代码的使用者类和 COM 对象。 例如,可以创建并配置 ActiveScriptEventConsumer 类的实例,以便在事件发生时运行脚本。 有关详细信息,请参阅借助标准使用者监视和响应事件。 有关使用 ActiveScriptEventConsumer 的示例,请参阅基于事件运行脚本

以下过程介绍了如何创建永久事件使用者。

创建永久事件使用者

  1. 将事件提供程序注册到正在使用的命名空间。

    某些事件提供程序只能使用特定的命名空间。 例如,__InstanceCreationEvent 是一个内在事件,Win32 提供程序 支持此事件,并且默认向 \root\cimv2 命名空间注册注册此事件。

    注意

    可以使用注册中使用的 __EventFilter 的 EventNamespace 属性来创建跨命名空间订阅。 有关详细信息,请参阅实现跨命名空间永久事件订阅

     

  2. 将事件使用者提供程序注册到事件类所在的命名空间。

    WMI 使用事件使用者提供程序来查找永久的事件使用者。 永久事件使用者是 WMI 在收到事件时启动的应用程序。 要注册事件使用者,提供程序会创建 __EventConsumerProviderRegistration 实例。

  3. 创建表示要使用的永久事件使用者的类的实例。

    事件使用者类派生自类 __EventConsumer。 设置事件使用者实例所需的属性。

  4. 使用 regsvr32 实用工具向 COM 注册使用者。

  5. 创建事件过滤器类 __EventFilter 的实例。

    设置事件筛选器实例的必填字段。 __EventFilter 的必填字段为“Name”、“QueryLanguage”和“Query”。 Name 属性可以是此类实例的任何唯一名称。 QueryLanguage 属性始终设置为“WQL”。 Query 属性是包含事件查询的字符串。 当永久事件使用者的查询失败时,将生成事件。 事件的源为 WinMgmt,事件 ID 为 10,事件类型为“错误”。

  6. 创建 __FilterToConsumerBinding 类的实例,以将逻辑事件使用者与事件筛选器相关联。

    WMI 使用关联查找与事件筛选器中指定的条件匹配的事件关联的事件使用者。 WMI 使用事件使用者提供程序来查找要启动的永久事件使用者应用程序。