Recipe 7.15. Script: Service MonitorHave you ever had a pesky service that would stop for apparently no reason? Well, if you can't afford to buy a service monitoring application, you can write one yourself using WMI and event notifications. The following code monitors the state of all services and reports any changes: ' This code displays the changes in state for the services on a computer. Option Explicit ' ------ SCRIPT CONFIGURATION ------ Dim strComputer : strComputer = "." ' ------ END CONFIGURATION --------- Dim objWMI : set objWMI = GetObject("winmgmts:\\" & strComputer _ & "\root\cimv2") Dim colServices : set colServices = objWMI.ExecNotificationQuery( _ "select * from _ _instanceModificationEvent " _ & "within 2 where TargetInstance ISA 'Win32_Service'") Do Dim objSvc : set objSvc = colServices.NextEvent If objSvc.TargetInstance.State <> objSvc.PreviousInstance.State Then Wscript.Echo objSvc.TargetInstance.Name & _ " is " & objSvc.TargetInstance.State & _ " -- it was previously " & _ objSvc.PreviousInstance.State end If Loop The main method to note in this script is ExecNotificationQuery. This method executes a WQL query and receives events that result from it. Let's break the query down. The select statement pulls all _ _instanceModificationEvent objects: "select * from _ _instanceModificationEvent " So what is a _ _instanceModificationEvent object? Anytime an instance of a WMI object changes, it registers the change as an instanceModificationEvent. This is incredibly powerful. Whenever a service changes, whether it is a property of a service or service state, that event is registered as a modification event in WMI. That select statement matches all modification events, which isn't quite what we want. This is where the next statement comes into play: " within 2 where TargetInstance ISA 'Win32_Service'" TargetInstance ISA 'Win32_Service' filters all modification events to only those of class Win32_Service. The within 2 statement informs WMI how often to check the system (in seconds) to see if the anything new matches this query. After we've called ExecNotificationQuery, we are ready to enter a loop to start retrieving events. I used a do loop, which will make this script run until you kill it (i.e., type Ctrl-C). The first line in the do loop is the call to NextEvent. This is a synchronous call that waits until an event occurs before the script continues. If no services change, the script won't move beyond this step. If it does catch a service changing in some way, it next checks to see if the state of the service changed (instead of a property being modified). As I mentioned previously, someone could modify another property of a service which would create an instanceModificationEvent. All Win32_Service instanceModificationEvents have a State property. |