Monitoring Resources by Using WMI Event Notifications

Microsoft® Windows® 2000 Scripting Guide

System administrators spend a great deal of their time fixing problems. Unfortunately, by the time a system administrator is alerted to a problem, the problem might already be disrupting the work of other employees. In turn, this can cost the organization money, in the form of lost productivity.

By using WMI event notifications, you can monitor the state of any WMI-managed resource and respond to an issue much earlier, perhaps before it is even noticed by your users.

For example, instead of waiting for a problem related to insufficient free disk space on a server to be brought to your attention, you can set up a WMI event notification that notifies you by e-mail when the free disk space on a server falls below a specified value. By knowing about the potential problem before it occurs, you can solve it before any productivity is lost - in this case, perhaps by archiving some of the data on the hard disk or by installing an additional hard disk.

If WMI event notifications did not exist, you could use a WMI script that retrieves the properties of a WMI-managed resource to monitor the state of that resource. In that case, you would need to repeatedly run a script that checks the amount of free space on a hard disk. The script would have to be scheduled to run whenever a given interval of time has elapsed. If you set too short an interval, the script will run very frequently and consume valuable computing resources. If you set too long an interval, the script might notify you of potential trouble only after this has already become an actual problem for users.

The WMI event notification mechanism was designed to overcome these issues, providing you with an efficient way of monitoring WMI-managed resources.

Scripts that monitor WMI-managed resources look similar to other WMI scripts. For example, the script in Listing 6.29 monitors the processes on a computer and displays a message if a process named Notepad.exe is started on that computer. As you can see, the script is only a few lines long and has a number of elements identical to scripts used to this point in the chapter.

If you run this script under CScript, you will likely notice that the script starts running but does not seem to finish; although it appears to have stopped running, you are not returned to the command prompt. This is the expected behavior; the script has started and is simply waiting for an instance of Notepad to be created.

Now start a new instance of Notepad. The script will display the following output and then end:

An instance of notepad.exe just started.

This is exactly what the script was designed to do. It waits until an instance of Notepad is created, it reports the fact that this instance was just created, and then it stops.

Listing 6.29 Monitoring the Notepad.exe Process

  
1
2
3
4
5
6
7
8
9
10
11
12
13
14
strComputer = "."
Set objSWbemServices = GetObject("winmgmts:" &_
 "{impersonationLevel=impersonate}!" &_
 "\\" & strComputer & "\root\cimv2")
Set objEventSource = objSWbemServices.ExecNotificationQuery( _
 "SELECT * FROM __InstanceCreationEvent " &_
 "WITHIN 10 " &_
 "WHERE TargetInstance " &_
 "ISA 'Win32_Process' " &_
 "AND TargetInstance.Name = 'notepad.exe'")
Set objEventObject = objEventSource.NextEvent()
Wscript.Echo "An instance of notepad.exe just started."

Lines 1 through 4 of the script are typical of most WMI scripts. They establish a connection to the root\cimv2 namespace on the computer specified in the strComputer variable.

In lines 6 through 11, a notification query is made using the ExecNotificationQuery method. The WMI Query Language (WQL) for the query is built up in lines 7 through 11. The WQL is similar to the WQL used to retrieve instances of CIM classes, but two new keywords are used: WITHIN and ISA. These keywords are discussed in more detail later in this chapter.

In line 13, the NextEvent method is used to pause the script and wait for the event described by the notification query to occur.

Line 14 displays a message after the event has occurred. The script then automatically terminates.

The script in Listing 6.29 might look a little complicated, at least at first glance. However, like other WMI scripts in this chapter, this script can be modified to work with a different WMI-managed resource by making only a few modifications.

For example, the script in Listing 6.30 monitors the services on a computer and displays a message if the state of the Alerter service changes. Enter and run the script in the same way you did the script shown in Listing 6.29. Start or stop the Alerter service by typing net start alerter or net stop alerter in a command window. The following message should be displayed:

The status of the alerter service just changed.

Listing 6.30 Monitoring the Alerter Service

  
1
2
3
4
5
6
7
8
9
10
11
12
13
14
strComputer = "."
Set objSWbemServices = GetObject("winmgmts:" &_
 "{impersonationLevel=impersonate}!" &_
 "\\" & strComputer & "\root\cimv2")
Set objEventSource = objSWbemServices.ExecNotificationQuery( _
 "SELECT * FROM __InstanceModificationEvent " &_
 "WITHIN 10 " &_
 "WHERE TargetInstance " &_
 "ISA 'Win32_Service' " &_
 "AND TargetInstance.Name = 'alerter'")
Set objEventObject = objEventSource.NextEvent()
Wscript.Echo "The status of the alerter service just changed."

Compare this script with the one in Listing 6.29. The elements that differ between the two scripts are highlighted in Listing 6.30. There are four differences between the two scripts:

  1. The type of event monitored.

    __InstanceCreationEvent was changed to __InstanceModificationEvent on line 7. The script in Listing 6.29 displays a message when a new instance of Notepad is created. To do this, it registers to receive events of type __InstanceCreationEvent. This event occurs whenever a new instance of a managed object is created. The script in Listing 6.30 displays a message when the state of the Alerter service is modified. To do this, it registers to receive events of type __InstanceModificationEvent. This event occurs whenever an existing instance of a managed object is modified.

  2. The WMI class of the resource being monitored.

    Win32_Process was changed to Win32_Service on line 10. The script in Listing 6.29 monitors a process, so it requires a reference to the Win32_Process WMI class. The script in Listing 6.30 monitors a service and therefore requires a reference to Win32_Service.

  3. The value of the Name property specifying the instance of interest.

    notepad.exe was changed to alerter on line 11. The Win32_Process and Win32_Service WMI classes each include a Name property. In the script in Listing 6.29, the name of the process monitored is notepad.exe; in Listing 6.30, the name of the service monitored is alerter. The values of properties other than the Name property could have been used instead. For example, suppose you want to know only whether a service that is currently stopped has been modified in some way. In that case, you would use this code:

    TargetInstance.State = 'Stopped'
    
  4. The message displayed when the specified event is received.

    "An instance of notepad.exe just started." was changed to "The status of the alerter service just changed." on line 14.