使用标准使用者监视和响应事件
可以使用已安装的标准使用者类根据操作系统中的事件执行操作。 标准使用者是已注册的简单类,它们可定义永久使用者类。 每个标准使用者在收到事件通知后都会执行特定操作。 例如,可以定义 ActiveScriptEventConsumer 的实例,以便在计算机上的可用磁盘空间与指定大小不同时执行脚本。
WMI 将标准使用者编译为依赖于操作系统的默认命名空间,例如:
- 在 Windows Server 2003 中,所有标准使用者默认编译为“Root\Subscription”命名空间。
注意
有关特定于每个 WMI 类的默认命名空间和操作系统,请参阅每个类主题的“备注和要求”部分。
下表列出并描述了 WMI 标准使用者。
标准使用者 | 说明 |
---|---|
ActiveScriptEventConsumer | 在收到事件通知时执行脚本。 有关详细信息,请参阅基于事件运行脚本。 |
LogFileEventConsumer | 在收到事件通知时,将自定义字符串写入文本日志文件。 有关详细信息,请参阅基于事件写入日志文件。 |
NTEventLogEventConsumer | 将特定消息记录到应用程序事件日志。 有关详细信息,请参阅日志记录到基于事件的 NT 事件日志。 |
SMTPEventConsumer | 每次向其传递事件时,使用 SMTP 发送电子邮件。 有关详细信息,请参阅基于事件发送电子邮件。 |
CommandLineEventConsumer | 在事件传递到本地系统时启动进程。 可执行文件必须位于安全位置,或者使用强访问控制列表 (ACL) 进行保护,以防止未经授权的用户将你的可执行文件替换为其他可执行文件。 有关详细信息,请参阅基于事件从命令行运行程序。 |
以下过程介绍如何通过标准使用者监视和响应事件。 请注意,对于托管对象格式 (MOF) 文件、脚本或应用程序,该过程相同。
标准使用者监视和响应事件
使用 MOF 预处理器命令 #pragma namespace 指定 MOF 文件中的命名空间。 在脚本或应用程序中,在连接到 WMI 的代码中指定命名空间。
以下 MOF 代码示例演示如何指定 root\subscription 命名空间。
#pragma namespace ("\\\\.\\root\\subscription")
大多数内部事件都与 root\cimv2 命名空间中的类实例的更改相关联。 但是,注册表事件(如 RegistryKeyChangeEvent)由系统注册表提供程序在 root\default 命名空间中触发。
通过在事件的 __EventFilter 查询的 EventNamespace 属性中指定命名空间,使用者可以包括位于其他命名空间中的事件类。 内部事件类(如 __InstanceOperationEvent)在每个命名空间中都可用。
创建并填充标准使用者类的实例。
此实例在 Name 属性中可能具有唯一值。 可以通过重用同一名称来更新现有使用者。
InsertionStringTemplates 包含要在事件中插入的文本,该事件在 EventType 中指定。 可以使用文本字符串或直接引用属性。 有关详细信息,请参阅使用标准字符串模板和用于事件查询的 SELECT 语句。
将现有源用于支持不带关联文本的插入字符串的事件日志。
以下 MOF 代码示例演示如何使用 WSH 的现有源和 EventID 值 8。
instance of NTEventLogEventConsumer as $Consumer { Name = "RunKeyEventlogConsumer"; SourceName = "WSH"; EventID = 8; // Warning EventType = 2; // One string supplies the entire message NumberOfInsertionStrings = 1; // the %Hive% and %KeyPath% are properties of // the RegistryKeyChangeEvent instance InsertionStringTemplates = {"The key %Hive%\\%RootPath% has been modified." "Check if the change is intentional"}; };
创建 __EventFilter 实例并定义事件查询。
在以下示例中,筛选器监视注册启动程序的注册表项。 监视此注册表项可能很重要,因为未经授权的程序可以在该注册表项下注册自己,这会导致它在计算机启动时启动。
instance of __EventFilter as $Filter { Name = "RunKeyFilter"; QueryLanguage = "WQL"; Query = "Select * from RegistryTreeChangeEvent" " where (Hive = \"HKEY_LOCAL_MACHINE\" and " "RootPath = \"Software\\\\Microsoft\\\\Windows" "\\\\CurrentVersion\\\\Run\")"; // RegistryTreeChangeEvents only fire in root\default namespace EventNamespace = "root\\default"; };
标识要监视的事件并创建事件查询。
可以检查是否存在使用的内部事件或外部事件。 例如,使用注册表提供程序的 RegistryTreeChangeEvent 类监视对系统注册表的更改。
如果不存在描述需要监视的事件的类,则必须创建自己的事件提供程序,并定义新的外部事件类。 有关详细信息,请参阅编写事件提供程序。
在 MOF 文件中,可以为筛选器和使用者定义别名,这提供了一种描述实例路径的简单方法。
以下示例演示如何为筛选器和使用者定义别名。
instance of __EventFilter as $FILTER instance of LogFileEventConsumer as $CONSUMER
创建 __FilterToConsumerBinding 实例以关联筛选器和使用者类。 此实例确定,当发生与指定筛选器匹配的事件时,使用者指定的操作必须发生。 __EventFilter、__EventConsumer 和 __FilterToConsumerBinding 必须在 CreatorSID 属性中具有相同的单独安全标识符 (SID)。 有关详细信息,请参阅将事件筛选器与逻辑使用者绑定。
以下示例演示如何通过对象路径标识实例,或使用别名作为对象路径的速记表达式。
instance of __EventFilter as $FILTER instance of NTEventLogEventConsumer as $CONSUMER
以下示例使用别名将筛选器绑定到使用者。
instance of __FilterToConsumerBinding { Filter = $FILTER; Consumer = $CONSUMER; };
可以将一个筛选器绑定到多个使用者,表明发生匹配事件时,必须执行多个操作;或者,可以将一个使用者绑定到多个筛选器,表明在发生与其中一个筛选器匹配的事件时必须执行该操作。
根据使用者和事件的条件执行以下操作:
- 如果其中一个永久使用者失败,请求事件的其他使用者会收到通知。
- 如果删除事件,WMI 将触发 __EventDroppedEvent。
- 如果订阅此事件,它将返回已删除的事件,对 __EventConsumer 的引用表示失败的使用者。
- 如果使用者失败,WMI 将触发 __ConsumerFailureEvent,其中可能包含 ErrorCode、ErrorDescription 和 ErrorObject 属性中的详细信息。
有关详细信息,请参阅将事件筛选器与逻辑使用者绑定。
示例
以下示例演示 NTEventLogEventConsumer 实例的 MOF。 编译此 MOF 后,尝试在注册表路径 HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\Run 中创建、删除或修改值的任何操作都会在源“WSH”下的应用程序事件日志中记录一个条目。
#pragma namespace ("\\\\.\\root\\subscription")
instance of __EventFilter as $Filter
{
Name = "RunKeyFilter";
QueryLanguage = "WQL";
Query = "Select * from RegistryTreeChangeEvent"
" where (Hive = \"HKEY_LOCAL_MACHINE\" and "
"KeyPath = \"Software\\\\Microsoft\\\\Windows"
"\\\\CurrentVersion\\\\Run\")";
// RegistryTreeChangeEvents only fire
// in root\default namespace
EventNamespace = "root\\default";
};
instance of NTEventLogEventConsumer as $Consumer
{
Name = "RunKeyEventlogConsumer";
SourceName = "WSH";
EventID = 8;
EventType = 2; // Warning
Category = 0;
NumberOfInsertionStrings = 1;
// the %Hive% and %KeyPath% are properties
// of the RegistryKeyChangeEvent instance
InsertionStringTemplates = {"The key %Hive%\\%RootPath% "
"has been modified. Check if the change is intentional"};
};
// Bind the filter to the consumer
instance of __FilterToConsumerBinding
{
Filter = $Filter;
Consumer = $Consumer;
};
相关主题