December 9th, 2010

Use the PowerShell WMI Event Module to Quickly Monitor Events

 

Summary: Learn how to use a Windows PowerShell WMI module to create permanent event monitors.

 

Hey, Scripting Guy! QuestionHey, Scripting Guy! Can you provide some concrete examples of using the Windows PowerShell permanent event consumer module?

— TS

 

Hey, Scripting Guy! AnswerHello TS, Microsoft Scripting Guy Ed Wilson here. Today Trevor Sullivan is back to finish out the week on his permanent event consumer module.

 

Introduction

Hello. Yesterday we introduced the new PowerEvents module, and explained how it helps you monitor information in Windows Management Instrumentation (WMI). In today’s blog post, we will look at a few examples of useful things we can monitor.

Examples

Active Directory User Accounts

One useful thing to monitor, and respond to, could be the creation of Active Directory user accounts. For example, after a user has been created, you could fire off a script to automatically create a home folder with appropriate permissions, an Exchange mailbox, and some other tasks.

On an Active Directory domain controller, there is a WMI namespace that does not exist on other systems, called root\directory\ldap. There exists a class named ds_user that represents user accounts in Active Directory. By monitoring for new instances of ds_user, we can effectively determine when a new user has been created.

 

Filter

First, we create an event filter to capture the creation events:

$MyFilter = New-WmiEventFilter –Name ADUserCreated –Query “select * from __InstanceCreationEvent within 5 where TargetInstance ISA ‘ds_user’” –EventNamespace root\directory\ldap

 

As you will see, we introduced a new Windows PowerShell parameter on the New-WmiEventFilter function called EventNamespace. By default, the function assumes that the events that you want to capture are in root\cimv2, and a lot of the time this will be true. However, because the class (ds_user) we are targeting exists in root\directory\ldap, we must specify that namespace.

We set the Name parameter to something self-describing, and pass in our event query to the Query parameter. The New-WmiEventFilter function writes the filter to the pipeline , so we store it in a variable called $MyFilter for later use. Now we are ready to set up a consumer!

 

Consumer

For the consumer, we’ll just log the event to a file, to inform us that a user has been created. We can do that using the LogFile event consumer type. There are only a handful of parameters we have to set in order to configure a LogFile event consumer. Here is an example:

$MyConsumer = New-WmiEventConsumer –ConsumerType LogFile –Name ADUserCreated –FileName c:\temp\Users.txt –Text “Active Directory user has been created: %TargetInstance.DS_distinguishedName%“

 

In our call to New-WmiEventConsumer, we first specify the ConsumerType as “LogFile.” This tells the function to log events to a text file. Next, we give the consumer a useful name that describes its purpose in the Name parameter. The FileName parameter is used to specify the file path which you would like a message logged to. Finally, the Text property determines the text that will be logged to the file. You can use a variable, known as a WMI “standard string template” to create dynamic messages that contain specific information about the event that was fired. This way, instead of being informed that *some* user was created, you know exactly which one it was, and where it is located in the directory.

 

Binding

Finally, now that we’ve created the filter and consumer (the “meat” of the whole process), we just have to create a binding in WMI, that tells it which filter we’d like to match up to which consumer. For this, we use the New-WmiFilterToConsumerBinding function. There are two parameters we have to specify: the Filter and the Consumer — that’s it! Here’s an example:

New-WmiFilterToConsumerBinding –Filter $MyFilter –Consumer $MyConsumer

 

That is all there is to it! When you create a new user account on your domain controller, you should now see these events being logged to the file path that is specified in the consumer. This is shown in the following figure.

Note: This example will only work on an Active Directory domain controller, with the root\directory\ldap WMI namespace available. It has not been tested with Active Directory Lightweight Directory Services (LDS).

Detect ConfigMgr Software Updates

Consider that you want to be notified when new software updates are assigned to a workstation in Microsoft System Center Configuration Manager. Perhaps you want to investigate the situation, or you want to perform some action when software updates are detected, such as closing down certain programs. You can do this with a WMI permanent event Registration.

On a Configuration Manager (ConfigMgr) client, updates deployments (“Deployment Management” objects) are seen as instances of the CCM_UpdateCIAssignment class in the root\ccm\policy\machine\actualconfig namespace. Therefore, we know that we can detect new software updates deployments by creating an event filter that detects new instances of this class.

Filter

First, we create a filter to capture the software updates deployments:

$MyFilter = New-WmiEventFilter –Name NewSoftwareUpdatesAssignment –Query “select * from __InstanceCreationEvent within 5 where TargetInstance ISA ‘CCM_UpdateCIAssignment’” –EventNamespace root\ccm\policy\machine\actualconfig

 

We give the filter a name that self-describes the kind of events we are trying to capture. Next, we specify our event query that looks for new instances (a.k.a., creation events) of the CCM_UpdateCIAssigment class. Finally, because the class does not exist in the root\cimv2 namespace, we specify the namespace where it does exist, which is root\ccm\policy\machine\actualconfig.

The next part is optional, but goes a little deeper into WMI eventing. If you are not interested, please skip to the Consumer heading.

We can test the event query before using it in our filter, by leveraging the notification query button on wbemtest.exe. Here’s how to do that step-by-step:

  1. Start wbemtest.
  2. Connect to the root\ccm\policy\machine\actualconfig namespace.
  3. Select the “asynchronous” option in the main wbemtest window.
  4. Click Notification Query.
  5. Paste the event query from above (quotes may not copy correctly).
  6. Click Apply.

Now, go to your ConfigMgr console, and create a new updates deployment targeting the computer you just performed the above steps on. You should see an event appear in the query window. Double-click it, and you’ll see something like what is shown in the following figure.

This screenshot represents what you would see if you drilled down into the WMI event using wbemtest . Basically, the event you receive is an instance of __InstanceCreationEvent. This event object has a TargetInstance property, which contains an embedded WMI object. This embedded object is the instance of CCM_UpdateCIAssignment that we were looking to capture. We can now explore the details of the new object that was just created!

 

Consumer

Now that we’ve got our filter created, let’s go ahead and create a consumer (responder) for the events. Let’s say that we want to terminate certain programs when an updates assignment is received. We can do that using a VBscript. To run a VBscript in response to an event, we use the Script consumer type. Here’s an example that assumes that you have already developed the VBscript file that you want to execute:

$MyConsumer = New-WmiEventConsumer –ConsumerType Script –Name NewSoftwareUpdatesAssignment –ScriptFile c:\scripts\NewSoftwareUpdatesAssignment.vbs

 

First we instruct New-WmiEventConsumer to create a consumer of type “Script.” Next, we give the consumer a self-describing name so that it is easy to recall its purpose in the future. Finally, we specify the script file we want to execute in response to the event. Pretty simple!

 

Binding

Now that we’ve created our filter and consumer, all we have to do is bind them together. Like the first example, call New-WmiFilterToConsumerBinding as follows:

New-WmiFilterToConsumerBinding –Filter $MyFilter –Consumer $MyConsumer

 

That’s all there is to it! Now when a new software updates assignment is published to your computer, your script will execute!

 

Conclusion

In today’s article, we’ve looked at an example of how to use PowerEvents to create WMI event filters, consumers, and bindings to respond to creation of Active Directory user accounts, and deployment of software updates to a Configuration Manager client. Although these may be niche situations, consider that you can apply the same event detection & response concepts to a lot of other information in WMI.

For more information about the PowerEvents module for Windows PowerShell, and to learn more about WMI permanent event registrations, please visit http://powerevents.codeplex.com .

 

TS, that is all there is to using the Windows PowerShell WMI event module to simplify monitoring. This also wraps up the permanent event consumer week. I want to thank you Trevor for your hard work on writing the module, and for your contributions to the blog. Tomorrow I reach into the virtual mail bag for Quick-Hits Friday.

I invite you to follow me on Twitter or Facebook . If you have any questions, send email to me at scripter@microsoft.com or post them on the Official Scripting Guys Forum . See you tomorrow. Until then, peace.

 

Ed Wilson, Microsoft Scripting Guy

Author

0 comments

Discussion are closed.