欢迎光临 Enjoy IT (ITECN.NET) 登录 | 注册 | 帮助

联合

公告

注意:本人的所有文档均可以引用,但引用必须说明出处。
跟我从头学WMI(四)--事件

使用事件

在你的脚本中,你可以利用由WMI提供的事件系统的优点,使用WMI事件架构允许系统管理员为任何注册的条件接收通知。

一.WMI事件架构

作为管理员,重要的是,你必须当出现某些问题出现时发出通知, 你可以自动响应这些问题加以补救。传统的做法是安装专用的代理,在自己狭窄的范围内报告事件。WMI基于修改模型的基础上,提供了一个单一的事件机制。无需专有的本地代理。 (这是第一单元介绍的内容)

使用的WMI ,当事件发生时,您可以得到通知。此外,当需要时,您还可以设定管理脚本运行来响应这些事件。

Windows Management Service包含一个事件服务,来支持过滤和事件报告。

 

1.在WMI中的事件

Subscriber Builder

Subscriber Builder可以是一个人或一个应用程序,事件由你管理的系统的任何感兴趣的事件来定义,它们由系统类_Event的实例来表示。

Subscriptions

Subscription是一个subscriber builder感兴趣的特定事件,一个Subscription是一个请求,WMI执行一个特殊的操作来回应一个个别的事件的发生。

事件用WMI注册,使用一个一个Event Query Select语句。它们被送到Windows Management Service,其中注注册了事件和消费者。

你的订阅应尽可能具体。泛泛的订购可能导致WMI处理不必要的数据。

下面的示例显示对MaryP用户的改变事件感兴趣:

SELECT * FROM __InstanceModificationEvent WITHIN 10 _

WHERE TargetInstance ISA ’Win32_userAccount’ _

AND TargetInstance.Name = ’MaryP’

Event Consumer

Event Consumer是通知发送的end-point代码或脚本。一个event consumer可以被描述为临时或永久的。

Event Provider

Event Providers使用WMI来注册。Event Providers是生成事件信息的软件,并且负责管理它们所支持的对象。当他们检测到事件,它们报告给WMIEvent provider可以在报告中使用过滤器,或则,它们可以将事件过滤留给WMI,而报告它们的所有事件。

为了防止系统过载,WMI可以被设置为根据在Win32 WMISetting class中设置的整个系统特定的属性来维护内存。下表表示了这些属性:

LowThresholdOnEvents:当排队交付给WMI的每秒发生的事件超过这个值。它会减慢自动交付。

HighThresholdOnEvents:当排队交付给WMI的每秒发生的事件超过这个值。,它会停止从provider那里接受新的事件

MaxWaitOnEvents: 在队列的事件等待的最大时间,超过这个时间,这个事件将被丢弃。

 

2WMI事件提供者

事件可以被分类为内在的,外在的或计时器事件,它们来自_Event class.当一个应用程序comsumer发生一个事件时,将收到这个类型的一个对象。最为常见的是内在事件和外在事件。

内在事件

内在事件发生在对下列改变的回应:在Common Information Model中的名称空间,类或实例被创建、编辑或删除。WMI有一个内部Provider,它可以自动报告关联到静态数据的内在事件。

报告关联到动态数据的内在事件,通常由动态provider来负责。当动态provider没有指定怎么做,你可以使用内部WMIprovider。然而,必须指示采用within参数来获得调查数据。

第一个例子显示WMI provider如何在CIM_Setting被编辑的时候创建一个事件,这表明,该系统有很多的设置已经被修改。

SELECT * FROM __ClassModificationEvent _

WHERE TargetInstance ISA ’CIM_Setting’

下面的示例显示WMI provider10秒报告关联到动态类的事件,Win32_userAccount。这个写数据进该类的provider不能报告事件。

SELECT * FROM __ClassModificationEvent _

WITHIN 10 WHERE TargetInstance ISA ’Win32_userAccount’

下面的示例显示一个内在事件由外部的provider创建,(NTEventLog provider

SELECT * FROM __ClassModificationEvent

WHERE TargetInstance ISA ’Win32_NTLogEvent’

下面的表描述了所有可用的内在事件类型:

Instance Of                       Description

__ClassCreationEvent              Notifies a consumer when a class is created

__ClassDeletionEvent              Notifies a consumer when a class is deleted

__ClassModificationEvent          Notifies a consumer when a class is modified

__InstanceCreationEvent           Notifies a consumer when a class instance is created

__InstanceDeletionEvent           Notifies a consumer when an instance is deleted

__InstanceModificationEvent       Notifies a consumer when an instance is modified

__NamespaceCreationEvent          Notifies a consumer when a namespace is created

__NamespaceDeletionEvent          Notifies a consumer when a namespace is deleted

__NamespaceModificationEvent      Notifies a consumer when a namespace is modified

注意,内在事件对象是系统对象,不能被编辑或扩展。

外在事件

外在事件源于CIM之外。只有根据某些目的书写的event provider可以报告它们到WMI。报告的事

件可以是被管理对象域的任何东西,因此,供应商必须在CIM中创建自己的事件类。比如,我们

可以创建一个外在事件provider,报告给基于WMI的“火警”系统.

SELECT * FROM FireAlarmEvent WHERE

TargetInstance ISA ’fireAlarm’

AND targetinstance.room = ’data center’

WMI SDK有两个外在事件providers

SNMPSimple Network Management Protocoltrap provider 报告给WMI,当接收到一个SNMP trap的时候。

Registry event provider当注册表被修改时通知WMI

注意,registry event providerregistry provider的一部分,registry provider不仅仅支持内在事件,也支持在注册表检索和编辑数据。

Time Events

计时器事件在具体的某天某时或周期性的发生,与内在或外在事件不同,计时器事件必须建立明确的消费指示。

 

3WMI事件的消费者

WMI Event Consumers
有两种类型的event consumer,临时消费者和常驻消费者

临时事件消费者的订阅只能存在于当消费者应用程序运行时,当应用程序终止,这个订阅也就被

取消了。WMI在内存中持有注册信息。一个临时消费者可以通过异步或同步的方式接收通告。建

议所有临时消费者注册为异步通知。异步通知消除不需要的通知状态,可以改善投递性能。

典型的临时消费者应用程序是用户界面应用程序。需要接收所管理对象改变的通告。比如,脚本

可以在它们执行的时候作为临时消费者被写入。

在脚本中你可以创建一个临时订阅:

ExecNotificationQuery ExecNotificationQueryAsync

常驻事件消费者

常驻事件消费者应用程序从WMI接收事件通知,不管它们在事件发生时是否运行。常驻事件订阅

存储在CIM中,将跨应用程序的启动停止或操作系统重新启动。

常驻订阅不自动删除,所以必须明确取消。当事件发生时,WMI检查消费应用程序是否运行,如

果没有,使用系统注册表中的信息启动。

常驻时间消费者可以被设置为同步或一部接收它们的事件通告。在使用异步事件通知时,在等待

消费者应用程序回应事件时,WMIevent Provider都不会被终止。

 

4WMI SDK Event tools

WMI SDK中有两个工具支持事件:

WMI Event Registration Tool

WMI事件注册工具为同一事件提供了一个图形界面功能,也可完成编程。通过使用这个工具,开发者和系统管理员可以做下列事情:

    察看被定义的消费者的属性,过滤器和计时器系统类和实例

    创建和删除事件消费者实例

    创建和删除事件过滤实例

    创建和删除事件计时器实例

    创建实例属性

    通过绑定消费者和过滤器为事件注册消费者。

WMI Event Viewer Tool

WMI事件观察器 是一个常驻事件消费者的示例。它是一个从WMI接收事件通告并发布到一个窗口的应用程序。用一种可视确认方法,对验证事件被正常创建和通知是非常有用的。

 

二.WMI中的事件脚本编程

1.  创建WMI事件查询

不论是临时还是常驻事件消费者都使用时间查询来指定它们所需要的事件。事件查询是基于select语句的。

Select语句

临时事件消费者使用SWbemServices对象的ExecNotificationQuery方法或ExecNotificationQueryAsync方法来注册它们的事件。下面是示例:

Set WbemEventSource = services.ExecNotificationQuery _

("SELECT * FROM __instanceCreationEvent" & _

"WHERE TargetInstance ISA ’Win32_NTLogEvent’")

常驻事件消费者创建适当的类和实例,长期存在在CIM中,每一个需要的类是_EventFilter,

查询属性使用事件查询规范。

无论在什么情况下,select语句都应该使用where语句来指定所需要的事件。事件消费者如果没有指定适当的查询,就可能因为太多的事件而造成过载。

ISA操作符

ISA操作符允许事件查询来指定一类class,代替一个一个的指定类,下面是示例:

SELECT * FROM __InstanceModificationEvent _

WITHIN 10 WHERE TargetInstance ISA ’Win32_Account’

这个查询包括Win32_SystemAccount, Win32_GroupWin32_UserAccount,它们的类型都是Win32_Account

WITHIN

如果被要求的事件所基于的类没有自己的事件提供者,该通知要求产生一个内在事件,通过内部WMI提供pollingWithin指定两个intervals:

1. The polling interval.

2. 如果使用Group语句,在聚合发生之前,必须先经过interval的时间。

Group(By)

Group语句可以节省处理时间。它要求在一个polling间隔中的所有的事件被聚合,并且像一个事件那样的被报告。Group语句可以使用by语句进行过滤,使得只有符合要求的才聚合:

SELECT * FROM __InstanceModificationEvent _

WITHIN 300 WHERE TargetInstance ISA ’Win32_PrintJob’_

GROUP WITHIN 600 BY TargetInstance.Owner

这个示例每300秒检查一次是否有新的打印作业被创建,并且每600秒发送一个单独通知。

The HAVING Clause

HAVING语句用于GroupWithin语句,它指定一个通知发生之前必须在轮询间隔被分组的最低数量的事件。

SELECT * FROM __InstanceModificationEvent _

WITHIN 10 WHERE TargetInstance ISA ’Win32_PrintJob’ _

GROUP WITHIN 30 BY TargetInstance.Owner _

HAVING NumberOfEvents > 5

这个例子每10秒检查一个人是否拥有创造超过5打印作业(在30秒内),并传送一个单一事件

通知。

 

2.  创建临时事件消费者

你可以使用SWbemSErvices对象的ExecNotificationQueryExecNotificationQueryAsync方法创

建临时消费者。这些方法返回一个SWbemEventSource对象,下面是使用ExecNotificationQuery

的示例:

Set events = GetObject("WinMgmts:").ExecNotificationQuery _

("SELECT * FROM __InstanceCreationEvent" & _

"WITHIN 10 WHERE TargetInstance isa ’Win32_userAccount’")

SWbemEvent对象的NextEvent方法取符合select语句的下一个事件。在这个例子里,如果在活动

目录里创建一个新的用户,一个新的Win32_UserAccount对象实例也被在CIM中创建。创建新实例

的激发需要的事件。NextEvent方法返回一个标准SWbemObject.下面是示例:

Set AccountEvent = events.NextEvent

在前面的示例中,SWbemObject代表一个内部事件对象实例名字叫__InstanceCreationEvent。所有内在事件对象有一个单一属性名叫TargetInstance,这是一个嵌入式对象。The embedded object is the object whose creation fired this event – in this case, Win32_UserAccount.

因此,你可以使用下列代码来检索该对象的属性。

WScript.Echo AccountEvent.TargetInstance.Name

WScript.Echo AccountEvent.TargetInstance.SID

3.  常驻事件消费者

常驻消费者要求一个事件消费提供者服务,在windows 2000中提供两个:

! The SMTP event consumer provider

! The ActiveScripting event consumer provider

另一个提供者,EventViewer事件消费者provider,由WMI SDK提供。这个题目集中在SMTP 事件

消费者provider,但结构上和其他的providers都一样。

Event Notification序列

WMI从所有来源接收和处理所有事件通知而无论最终消费者的打算。

1.WMI通过和一个或多个EventFilter的实例比较一个通告。

2.WMI分析匹配EventFilterFilterToConsumerBinding实例。

3.WMI定位和启动合适的EventConsumerProvider

4.WMI执行event consumer provider的方法来发送通告。

常驻事件消费者的创建

使用MOF文件,SMTP event consumer provider是被注册在CIM中的。这个SMTPEventConsumer

,基于系统__EventConsumer类被创建。这需要做一次,下面的示例显示MOF文件的一个片段:

class SMTPEventConsumer : __EventConsumer

{[key]string Name;

string Subject;

string Message;

string ToLine;

string SMTPServer;};

instance of __Win32Provider as $P

{ Name = "SMTPEventConsumer";

Clsid = "{C7A3A54B-0250-11d3-9CD1-00105A1F4801}";};

这个MOF文件创建Logical Consumer实例(基于在SMTPEventConsumer类):

instance of SMTPEventConsumer

{ Name = "student99@classroom.com";

Subject = "Print Job Created";

Message = "%TargetInstance.Document% has been printed";

ToLine = " student99@classroom.com ";

SMTPServer = "smtp.classroom.com";};

最后,MOF创建像FilterToConsumerBinding instances一样多的Logical Consumers:

instance of __FilterToConsumerBinding

{Consumer = _

"SMTPEventConsumer.name=\"student99@classroom.com\"";

Filter = "__EventFilter.name =\"prntJobFilter\"";

DeliverSynchronously=FALSE;};

所有这些对象常驻在CIM中,并且继续支持当事件发生时的通告。要取消一个常驻订阅,删除

BindingLogical Consumer实例,最后,这个事件过滤器可以被删除。

4.  创建时间事件

时间事件的生成和系统时钟相关,它们提供和闹钟或煮蛋器一样的功能,一个订阅者可以设置时间事件在一天的特定时间发生或在之后选择周期性发生。不行外部和内部事件,计时器事件由consumer provider指定的_TimerInstruction类中分离出来的实例创建

绝对时间实例The AbsoluteTimer Instance

要使用一个特定时间触发事件,subscriber builder必须首先创建一个AbsoluteTimer类的实例,这个类只有两个需要的属性:实例的unique ID和事件要触发的WMI Date\time,下面是实例:

instance of __AbsoluteTimerInstruction

{ EventDateTime = "20020224091000.953000+000";

TimerId = "02-24-2002-at-09.10";};

周期性计时器实例IntervalTimer Instance

要创建周期性触发的计时器,subscriber builder必须首先创建IntervalTimer类的实例,订阅者指定unique ID,周期间隔的milliseconds,下面是示例:

instance of __IntervalTimerInstruction

{ IntervalBetweenEvents = 5000;

TimerId = "intervalTimer";};

5.  最佳实践

当设置临时和常驻消费者时,我们可以通过关注某些点来获得最佳性能。

polling

使用Within语句,指定多久WMI应该检查一次事件是否发生。很明显,越是频繁的检查变化,就

越会影响WMI。另外要关注的是,有些事件是建立在很大的实例上的,比如,Win32_Account,

Win32_DirectoryCIM_DataFile将会引发在每次都例举所有的实例,WMI在每次在polling间隔

的时候都执行一个快照‘snap-shot’

Gropuing

大多数事件情景依据组来组织比用单个孤立事件更有价值。一次失败的登录可能仅仅是一个意外

,但在20秒之内的10次失败登录尝试,则更像是安全攻击。一个单一的打印作业表示打印机在正

常使用,大量的打印作业活动集中在一个打印机上,就有可能说明打印作业没有处理中。这可能

据此提供 早期打印故障警报。

selection

select查询语法中,允许对事件做出非常具体细致的指定。providers可以优化检索操作,使

得只有符合要求的实例而非所有实例被选取。

"SELECT * FROM __InstanceCreationEvent WITHIN 300 _

WHERE TargetInstance ISA ’Win32_PrintJob’ _

AND TargetInstance.Owner=’MaryP’_

GROUP WITHIN 600 HAVING NumberOfEvents >4"

AggregateEvent

当事件被分组,被返回的单个事件是系统类__AggregateEvent的一个实例。在胶片的举例中,这

个序列如下:

1.WMI使用合适的provider,来polling打印机。

2.当打印作业达到打印机,一个Win32_printJob类的实例被创建。

3.当作业进程数量(HAVING NumberOfEvents >4)存在 在指定的时间内(GROUP WITHIN 600),并

且所有者是MaryP,那么一个aggregate event被出发。

4.SWbenObject被返回,代表__AggregateEvent类的一个实例。

5.这个实例有两个属性,NumberOfEvents属性是一个无符号整数,代表引发该事件的单个事件总

数。Representative属性是一个嵌入对象,代表一个instanceCreationEvent对象。

6.instanceCreationEvent有一个单一属性TargetInstance.这个属性是一个内嵌对象,代表由

affregate event触发的win32_printjobs的一个例子。

 

WScript.Echo obj.Representative.TargetInstance.size

WScript.Echo obj.NumberOfEvents

 

 

已发表 2009年4月8日 13:18 作者 qiqinghua

评论

尚无任何评论

禁止匿名发表评论