Learn about Windows PowerShell
Summary: Learn how to create permanent WMI events using VBScript in this foundational blog post that provides a basis for a monitoring solution.
Hey, Scripting Guy! Over the years, I have read many Hey Scripting Guy! Blog posts. They are usually humorous, easy to read, and possess a certain amount of value. One area you tend to focus on, however, that I think is rather impractical is the posts about WMI events. I mean, I can see that the scripts (either VBScript or Windows PowerShell it really does not matter) make awesome demos, but they are pretty much useless. I am talking about the fact that it might look really cool to copy a file when a USB drive is inserted, but unless the script is actually running the event does not happen. In other words, it is impractical to have a script running all the time. All your WMI event scripts are not a management technique; they are more or less management snake oil. It looks good, it feels good, but is of no practical value. If there was a way to make the WMI events permanent without having to have a script running all the time, that would be a different story, but alas, it seems to not be the case.
Hello TS, Microsoft Scripting Guy Ed Wilson here. I just had a flash back to the early 1970’s. The blond haired girl across the playground is toting a boombox the size of a Volkswagen, and the volume is cranked up so loud it makes the fillings in my teeth vibrate. The song lyrics float above the tetherball pit.
“I don’t like spiders and snakes …” Therefore, I doubt if I would like snake oil either. However, I do like eels, such as the one seen in the following figure, whose picture I took while scuba diving off the coast of Key Largo, Florida a few years ago. The trick with eels is to avoid getting too close to them. As with all sea creatures, one should not harass them but eels have unique ways of expressing their displeasure. Of course, eels are not really snakes, but are actually a kind of fish. They smile when they see scuba divers and therefore, are very photogenic. Eels are one of my favorite underwater photography subjects. They always make interesting pictures.
As an eel seems to be a snake, but in reality is a fish, a Windows Management Instrumentation (WMI) event script is useful and not merely management theatre. The usefulness of the WMI event script lies in its application. Most examples of WMI event driven scripts use a temporary event consumer. That is,, they are not intended to run for a long-term application. In the example that you gave of copying files when a USB drive is inserted, I wrote that script to enable me to quickly copy a selection of files to a large number of USB drives. Therefore, all I needed to do was to insert the USB drive, and it would copy the selection. This is not a behavior I would want to replicate on a long-term basis.
Portions of today’s post are adapted from my WMI book, Microsoft Windows Scripting with WMI: Self-Paced Learning Guide, that was published by Microsoft Press in 2006.
On the other hand, many WMI event driven scripts possess management functionality that would be nice to have operating regularly; a script that monitors a particular service that sends an email message when the service stops is an example of such a script. To handle long-term monitoring tasks, one has to create a permanent event consumer.
I am using VBScript in today’s post to document these procedures for VBScripters. Tomorrow, I will use Windows PowerShell to perform the same tasks. If you write code in Windows PowerShell, you should still read today’s post because it explains fundamental WMI techniques.
Permanent event consumers function like services. They start when the computer starts, and they stop when the computer shuts down. When the permanent event consumer is running, nothing indicates that it is actually doing so. There is no special process visible in Task Manager, and no graphical user interface is exposed. Permanent event consumers are part of WMI and therefore they require no special setup, nor do they require special installation. They are used by many management applications and therefore you can have one or more permanent event consumers already setup and responding to events on your computer.
Event consumers are classes that already know how to respond to certain events that are triggered in response to certain activities. You can create an instance of one of these consumers, and use the class to execute certain actions when the specified event occurs. When you work with the standard event consumers, there are always some common elements that must be put into place. These include the following:
The first step in working with a permanent event consumer is to create an instance of the consumer. You can do this in one of several methods. You can use a MOF file, you can use the WMI tools, or you can use a script. There are three essential ingredients to creating an instance of the consumer: use of get, use of spawnInstance_ () and use of put_. Each of the consumers will have its own peculiarities; generally, when you use VBScript, you will use some code that resembles the following.
' create the active script consumer
set objConsumerClass=objActiveScriptConsumer.get _ ("ActiveScriptEventConsumer")
set consumerpath = objconsumer.put_
To create an event filter, we have to specify an event driven query that will be used to drive the subscription. This is the same kind of query that is mentioned in the earlier Hey, Scripting Guy! Blog posts. We specify the event system class we want to monitor, and target class properties we are interested in tracking. After we have the query defined, we get an __EventFilter, call spawninstance_, and finally put_ the filter into the appropriate namespace. The VBScript code here shows this procedure.
'Create the event filter
eClass = "__instanceModificationEvent" 'type of event to obtain
tClass = "'win32_service'" 'wmi class to monitor
tName = "'Schedule'" 'name property of target class
qQuery ="select * from " & eClass & " within 10 where targetInstance isa "_
& tClass & " and targetinstance.name=" & tNameset objfilterclass=objActiveScriptConsumer.get("__EventFilter")
set filterpath = objfilter.put_
objfilter.EventNameSpace = “root\cimv2”
After we have created an instance of the desired consumer, crafted our event driven query and put our event filter into the appropriate WMI namespace, it is time to bind the filter to the consumer. This may seem disappointingly simple after struggling through the two previous code samples. First we get the __filterToConsumerBinding system class. We assign the returned object to the objBindingClass variable. Next we create a new instance of the objbindingclass by using the spawnInstance_ command. Now we wire up the connections by specifying the filter and the consumer. After you do this, we use the put_ command to write the binding back to WMI. The VBScript code that does this is seen here.
'Do the binding
FTCB = "__filterToConsumerBinding"
TS, that is all there is to using WMI Permanent event consumer scripts. Permanent event consumer week will continue tomorrow when I will talk about how to use Windows PowerShell to create Permanent event consumer scripts.
I invite you to follow me on Twitter or Facebook. If you have any questions, send email to me at email@example.com or post them on the Official Scripting Guys Forum. See you tomorrow. Until then, peace.
Ed Wilson, Microsoft Scripting Guy
This is much easier to do with PowerEvents: powerevents.codeplex.com
Hope it helps!
@Matt, You are correct, we will feature PowerEvents on Wed anbd Thursday this week. Trevor has written a couple of awesome posts explaining how he came to write PowerEvents and using it. I am just laying the foundation today and tomorrow leading up to his posts. Of course there are still some folks who do not use Windows PowerShell and they will not be able to use PowerEvents, but the techniques in todays post will help them to use this powerful technique.
Now I see where this is going :D
When you say "They start when the computer starts, and they stop when the computer shuts down." does this mean that the consumer will launch using the same service account as the Winmgmt service? Normally the Local System account. Does this prevent interaction with a logged on user? For example, launching of IE interactively would be prevented as the consumer is running under the Local System account instead of the currently logged on user account?