Anda di halaman 1dari 26

Art of Shell wbemtest

http://powershell.artofshell.com/tag/wbemtest/

Skip to content Skip to menu

Art of Shell
Windows PowerShell code as an art form Search

search...

Home About Trevor Site Map Nov 16 2009

PowerShell: Getting started with WMI Events


Category: powershell,scripting,tools,wmi pcgeek86 @ 6:36 am

Introduction

PowerShell version 1 provided good integration with WMI using the Get-WmiObject cmdlet, allowing you to easily retrieve and modify WMI instances, and call WMI methods, but PowerShell v2 has taken it, and many other things, a lot farther. One of those areas is eventing, and not just WMI eventing, but responding to WMI events is what Id like to discuss in this article. Because WMI contains a large repository of information regarding a systems hardware and software state, it is useful to understand WMI events, so that you can determine where they can t into your environment. This topic is mostly geared towards systems administrators or engineers that are looking to do some advanced monitoring of their systems.

1 of 26

06/10/2011 03:29 PM

Art of Shell wbemtest

http://powershell.artofshell.com/tag/wbemtest/

To get started with WMI events in PowerShell v2, Im going to show you an example of how to use WMI events to detect DHCP lease changes. DHCP renewals occur infrequently, relative to the frequency of many other event types, however forcing a DHCP renewal is easy, and therefore makes for a good development example. Also, it seems like every other article out there uses Win32_Process instance creations or deletions for their WMI eventing examples, so I gured I would try something a little bit dierent. Keep in mind that DHCP lease updates are only one of thousands of potential uses for WMI events; I am simply attempting to convey the concept to you, so that you can gure out other methods of using it for your own needs.

About WMI Event Queries

For those of you who may be unfamiliar with WMI event queries (aka. notication queries), they use a syntax similar to this:

SELECT <Properties> FROM <EventClass> WITHIN <Seconds> WHERE TargetInstance ISA '<WmiClass>' AND <OtherCriteria>

Now, writing an event query is a little bit dierent from a standard select query. Why, you ask? Well, the system event classes youll work with respond to WMI instance events for all of the built-in WMI classes. In other words, they are responsible for a very large number of events. Because of this, you will need to write a query that provides extensive lters in order to avoid some inherent limitations of WMI. The main event classes of which I speak are as follows:

__InstanceCreationEvent occurs when a WMI instance is created (eg. a Win32_Process being instantiated) __InstanceDeletionEvent occurs when a WMI instance is deleted (eg. a Win32_Process terminating) __InstanceModicationEvent occurs when a WMI instance is modied (eg. a Win32_Process uses additional memory, or deallocates some) __InstanceOperationEvent occurs when a WMI instance is created, deleted, or modied (any of the above)

These are the main WMI event classes youll work with, unless you have another specic need, for example: monitoring a 3rd party piece of software, or are looking to monitor installation or deletion of WMI classes (as opposed to instances of classes).

If you would like to test out writing an event query, you can use the Wbemtest utility, that is included with Windows 2000 and up (XP 2003, Vista, 2008, 7, 2008 R2). Simply type wbemtest at the run prompt, or from a command prompt, then , use the Connect button to connect to the root\cimv2 namespace, and you should be presented with a window that looks similar to the below screenshot. Make sure that you select the Asynchronous method invocation option, as that will enhance wbemtests GUI performance during event queries; If you leave it at the default of Semisynchronous, you will

2 of 26

06/10/2011 03:29 PM

Art of Shell wbemtest

http://powershell.artofshell.com/tag/wbemtest/

probably nd the GUI frustrating to work with, as it hangs during the polling interval.

WbemTest Utility (connected to root\cimv2)

To test out an event query select the Notication Query button, and youll be presented with a box to type your query into. For now, just to get you started, an easy query to type here would be:
SELECT * FROM __InstanceModificationEvent WITHIN 3 WHERE TargetInstance ISA 'Win32_Process'

3 of 26

06/10/2011 03:29 PM

Art of Shell wbemtest

http://powershell.artofshell.com/tag/wbemtest/

Notication Query Window (wbemtest)

Once youve written your query, select Apply, wait the interval you specied (in the WITHIN clause), and you will start to see WMI event instances start to populate in the Query Result window. This window will remain open (and subscribed to events) until you close it. You can double-click on these event instances to open them, and then close the Query Result window if youd like to stop polling for events.

Event Query Results (wbemtest)

4 of 26

06/10/2011 03:29 PM

Art of Shell wbemtest

http://powershell.artofshell.com/tag/wbemtest/

Here is what youll see when you double-click on one of these events:

WMI Event Instance (wbemtest) As you can see, the event instance contains a few useful properties: TIME_CREATED When the event occurred (well talk about how to interpret this later) SECURITY_DESCRIPTOR Not sure what this is used for, but it appears to be NULL typically PreviousInstance The WMI instance in its state, prior to the event TargetInstance The WMI instance in its state, after the event occurred

By double-clicking on the PreviousInstance and TargetInstance properties (and then clicking the View Embedded

5 of 26

06/10/2011 03:29 PM

Art of Shell wbemtest

http://powershell.artofshell.com/tag/wbemtest/

button), we can view the WMI instance, and its properties, both before the event occurred, and after the event occurred. Because we have access to both of these states in an __InstanceModicationEvent, we can do a comparison to see which properties actually changed, and which ones didnt. The __InstanceCreationEvent, __InstanceDeletionEvent, and __InstanceOperationEvent classes do not have the PreviousInstance property, because they are only dealing with a WMI instance in a single state, not a before/after state.

Property Editor for TargetInstance (wbemtest)

6 of 26

06/10/2011 03:29 PM

Art of Shell wbemtest

http://powershell.artofshell.com/tag/wbemtest/

Object Editor for TargetInstance (wbemtest)

The above screenshot is a representation of the WMI instance after it was modied. Had we gone through and opened the PreviousInstance property, we would have seen a similar screen for it as well. On top of that, you can click the Show MOF button, which generates the Managed Object Format (MOF) syntax that represents that object. This is great for development and troubleshooting, because you can copy/paste both the MOF syntax for both PreviousInstance and TargetInstance into a text editor, and compare all of the dierent property values that changed. In fact, to save even having to do that, you can go all the way back to the __InstanceModicationEvent screen, click Show MOF there, and it will include the sub-instances (embedded objects).

7 of 26

06/10/2011 03:29 PM

Art of Shell wbemtest

http://powershell.artofshell.com/tag/wbemtest/

__InstanceModicationEvent MOF Syntax (wbemtest)

For now, this concludes the section about WMI event queries, and how to test them using the wbemtest utility. If you have other questions regarding WMI Events, please review the resources available on MSDN.

Building Our DHCP Lease WMI Event Query

In this section, lets talk a little bit more deeply about the WMI event query we need to create in order to detect DHCP lease changes. Remember, the goal of this article is to show you how to detect and respond to WMI events that indicate a change in the DHCP lease time. At any point, we can invoke a DHCP lease renewal by issuing the command:
ipconfig /renew

or (from PowerShell):
([wmiclass]"Win32_NetworkAdapterConfiguration").RenewDHCPLeaseAll()

Granted, the PowerShell method is a little longer, but its also more understandable, as were directly calling the WMI API to initiate the DHCP renewal, rather than going through a software utility. I just wanted to make sure you understood that,

8 of 26

06/10/2011 03:29 PM

Art of Shell wbemtest

http://powershell.artofshell.com/tag/wbemtest/

without ipcong, there is still an easy way to do this through PowerShell. Thats the beauty of PowerShell simple access to .NET and WMI objects! Anyway, were getting o-topic here.

Now that we know how to initiate a DHCP renewal, we can talk about how to write our event query in such a way that we can pick up on this event. It so happens that there is a WMI class called Win32_NetworkAdapterConguration in the root\cimv2 WMI namespace, which contains information about the network adapters in a computer (not restricted to only physical adapters). This class has some useful properties:

Win32_NetworkAdapterConguration WMI Class (wbemtest)

The DHCPLeaseObtained property is pretty self-explanatory, and contains the date & time that the DHCP lease was obtained on a particular network adapter. Now, keep in mind that you will typically see a number of instances of the

9 of 26

06/10/2011 03:29 PM

Art of Shell wbemtest

http://powershell.artofshell.com/tag/wbemtest/

Win32_NetworkAdapterConguration, but normally only the real network interfaces (eg. wired, wireless, or VPN) will actually have a non-null value for DHCPLeaseObtained. This will be helpful information for writing our WMI event query. For our rst attempt at writing an event query, we might come up with something as simple as this:

SELECT * FROM __InstanceModificationEvent WITHIN 3 WHERE TargetInstance ISA 'Win32_NetworkAdapterConfiguration'

After all, that query will return any changed instances of network adapter congurations, but what is the problem with that? Well, the problem is that well get back events for a whole lot more than just DHCP lease changes. So then, how do we zero in the information we need? If you check out my (albeit high-level) original denition of a WMI event query, youll notice the AND <OtherCriteria> part at the end. Thankfully, we can dig deeper into objects properties, as part of our query, to determine a restricted set of returned instances. Because we already know that: 1) there is a DHCPLeaseObtained property, and 2) we have access to both a PreviousInstance and TargetInstance, we can construct a query that looks like this:

SELECT * FROM __InstanceModificationEvent WITHIN 3 WHERE TargetInstance ISA 'Win32_NetworkAdapterConfiguration' AND TargetInsta

If you examine the above query, youll see that were further restricting the query, by only returning instances where the target instances DHCPLeaseObtained property does not match the previous instances DHCPLeaseObtained property. What this eectively gives us, is only events where the DHCP renewal time has changed, and nothing else! So, for the remainder of this article, the query directly above this paragraph is what well use to detect DHCP lease time changes. Before we go on, and now that we have identied the query to use, lets test it out using wbemtest:

10 of 26

06/10/2011 03:29 PM

Art of Shell wbemtest

http://powershell.artofshell.com/tag/wbemtest/

1. Open wbemtest, connect to rootcimv2, select Asynchronous, and click Notication Query

2. Paste your notication query and click Apply

11 of 26

06/10/2011 03:29 PM

Art of Shell wbemtest

http://powershell.artofshell.com/tag/wbemtest/

3. Use PowerShell to initiate a DHCP renewal

12 of 26

06/10/2011 03:29 PM

Art of Shell wbemtest

http://powershell.artofshell.com/tag/wbemtest/

4. Double-click the resulting event

13 of 26

06/10/2011 03:29 PM

Art of Shell wbemtest

http://powershell.artofshell.com/tag/wbemtest/

5. Click the Show MOF button

14 of 26

06/10/2011 03:29 PM

Art of Shell wbemtest

http://powershell.artofshell.com/tag/wbemtest/

6. Check out the PreviousInstance and TargetInstance values for the DHCPLeaseObtained property!

This completes the current section, on determining the WMI event query to identify DHCP lease changes. Next, well look at how to use all of this with PowerShell.

PowerShell WMI Event Cmdlets

Now that weve talked about WMI event queries, how to test them out by themselves rst, and how to build our DHCP lease event query, we are ready to talk about the PowerShell cmdlets that allow us to easily put those queries to good use. The easiest way to get started with PowerShell and events, is to simply issue the command:
help *event*

15 of 26

06/10/2011 03:29 PM

Art of Shell wbemtest

http://powershell.artofshell.com/tag/wbemtest/

Help *event* Command

From this commands output, youll see that there are a number of event-related Cmdlets as well as a HelpFile to get us started. Well concern ourselves with just a few of these cmdlets however:

Register-WmiEvent Registers an event subscription and allows you to specify a PowerShell ScriptBlock to respond to the event Get-EventSubscriber Retrieves a list of all current event subscriptions (not just WMI ones) Unregister-Event Unregisters event subscriber(s) (not just WMI ones)

Remember, for any PowerShell cmdlets, simply type the following to get full documentation on how to use it:
help <cmdletname> -full help Register-WmiEvent -full

16 of 26

06/10/2011 03:29 PM

Art of Shell wbemtest

http://powershell.artofshell.com/tag/wbemtest/

Register-WmiEvent Help

If you type Register-WmiEvent without any parameters, youll be prompted for a WMI class name. Unfortunately, for our purposes, this can be deceiving, because as we talked about above, we dont actually want to register for all event instances, only certain ones. Because of this, well need to specify the -Query parameter on the Register-WmiEvent cmdlet, which lets us set the event / notication query we want to use. Your event query can be stored in a PowerShell string variable also, but for the sake of this article, well just keep it in-line with the cmdlet. Now technically, we could run this cmdlet using only the -Query parameter like this:

17 of 26

06/10/2011 03:29 PM

Art of Shell wbemtest

http://powershell.artofshell.com/tag/wbemtest/

Register-WmiEvent without an action

Running this command yields a new event subscription, but what happens when an event is actually triggered? You guessed it, nothing by default. Actually, what this does is puts events into an event queue, so they can be retrieved using the Get-Event cmdlet, but for now we want an immediate response to our event. So, lets un-register the event subscription we created and try again.

18 of 26

06/10/2011 03:29 PM

Art of Shell wbemtest

http://powershell.artofshell.com/tag/wbemtest/

Unregistering PowerShell event handlers

If we want something to actually happen in response to these events we are subscribing to, well need to specify an action using the -Action parameter on the Register-WmiEvent cmdlet. The action parameter allows us to specify a PowerShell script block to respond to events. This could be as simple as a quick Write-Host command, or we could call a pre-dened function as our event handler (eg. function DhcpLeaseChangeHandler). Lets stick with a simple Write-Host for now though, and then call a DHCP renewal to test it out. Ill talk about some more advanced options in the next section.

19 of 26

06/10/2011 03:29 PM

Art of Shell wbemtest

http://powershell.artofshell.com/tag/wbemtest/

Our completed sample!

So thats it! If youve made it this far, youve gured out how to register for WMI events and respond to them using a PowerShell script block! If youre interested, stick around, and Ill show you how to do some even cooler stu in the next section.

Advanced WMI Event Handling

Alright, so youve made it far enough to gure out how to register WMI event handlers, but you want a bit more. Maybe youre asking yourself: Can I see information about the event from the script, like I did using wbemtest? If so, then youll be glad to hear that the answer is yes! To start o, lets look at the help for the -Action parameter of Register-WmiEvent:

20 of 26

06/10/2011 03:29 PM

Art of Shell wbemtest

http://powershell.artofshell.com/tag/wbemtest/

-Action <scriptblock> Specifies commands that handle the events. The commands in the Action parameter run when an event is raised ins tead of sending the event to the event queue. Enclose the commands in braces ( { } ) to create a script block.

The value of the Action parameter can include the $Event, $EventSubscriber, $Sender, $SourceEventArgs, and $Sou rceArgs automatic variables, which provide information about the event to the Action script block. For more inf ormation, see about_Automatic_Variables.

When you specify an action, Register-WmiEvent returns an event job object that represents that action. You can use the cmdlets that contain the Job noun (the Job cmdlets) to manage the event job. Required? Position? Default value Accept pipeline input? Accept wildcard characters? false 102 The event is added to the event queue. false false

From this, we see that there are a few built-in variables that enable us to capture event information, with a reference over to the about_Automatic_Variables help le. The $Event variable sounds pretty promising, doesnt it? Lets take a look at that (in the aforementioned help le):
$Event Contains a PSEventArgs object that represents the event that is being processed. This variable is populated only within the Action block of an event registration command, such as Register-ObjectEvent. The value of this variable is the same object that the Get-Event cmdlet returns. Therefore, you can use the properties of the $Event variable, such as $Event.TimeGenerated , in an Action script block.

That sounds like what were after: information about the event that gets created. So lets replace our -Action script block with the following: { $Global:MyEvent = $Event }. This way, when an event gets created, it will assign the event to the global $MyEvent variable, so we can play with it.

21 of 26

06/10/2011 03:29 PM

Art of Shell wbemtest

http://powershell.artofshell.com/tag/wbemtest/

Checking out the contents of $Event

As we can see, the $Event variable (which we reassigned to $MyEvent) contains a PSEventArgs object. If we issue a few more commands to the PowerShell console, we can discover the underlying WMI event object, so we can retrieve relevant information from it.

22 of 26

06/10/2011 03:29 PM

Art of Shell wbemtest

http://powershell.artofshell.com/tag/wbemtest/

The underlying WMI event object

Finally! Weve gotten to the bottom of our WMI event object, and can now check out the WMI properties that we wanted to compare, in order to determine the dierences between the dierent instances of Win32_NetworkAdapterConguration. Lets take a look at the DHCPLeaseObtained property on both our TargetInstance and PreviousInstance. Also, lets look at the .NET API to take the TIME_CREATED property and convert it to a readable DateTime format; Its simple, trust me.

23 of 26

06/10/2011 03:29 PM

Art of Shell wbemtest

http://powershell.artofshell.com/tag/wbemtest/

The underlying WMI Event Object

There they are the two CIM_DATETIME values that represent our DHCPLeaseObtained values before and after the event occurred (that we triggered)! The TIME_CREATED property is a 64-bit integer that represents the number of 100 nano-second intervals that have occurred between 12:00:00 AM January 1st, 1601 and the time that the event was generated. Dont ask.

This example shows that you can dynamically retrieve event information on-the-y from a PowerShell WMI event subscription. This information could be used in other ways, such as sending an e-mail alert to an administrator, calling an executable, or just about anything else you could think of.

Conclusion

This article stemmed from my interest in learning about event support in PowerShell version 2.0. I hope that by portraying my experiences with PowerShell events, you are able to learn something as well.

Please pass any feedback you may have on to me via pcgeek86@gmail.com or in the comments of this article.

24 of 26

06/10/2011 03:29 PM

Art of Shell wbemtest

http://powershell.artofshell.com/tag/wbemtest/

Did you like this? Share it:


2
Like One person likes this. Be the first of your friends.

Tags: automation, callback, cim, cimom, cmdlet, dmtf, eventing, microsoft, powershell, scripting, wbem, wbemtest, windows management instrumentation Comments (5)

Pages: About Trevor Site Map Categories: .NET Active Directory Apple congmgr CongMgr vNext xes Intel vPro People powershell scripting tools Uncategorized vbscript wmi Archives: November 2010 October 2010 September 2010 August 2010

25 of 26

06/10/2011 03:29 PM

Art of Shell wbemtest

http://powershell.artofshell.com/tag/wbemtest/

June 2010 May 2010 April 2010 March 2010 December 2009 November 2009 October 2009 September 2009 August 2009 July 2009 June 2009 May 2009 April 2009 Meta: Log in RSS Comments RSS Valid XHTML XFN WP top Powered by WordPress and Stardust Created by Tommaso Baldovino

26 of 26

06/10/2011 03:29 PM

Anda mungkin juga menyukai