Hey, Scripting Guy! Question

Hey, Scripting Guy! How can I be notified any time a service goes down?

-- RN

SpacerHey, Scripting Guy! AnswerScript Center

Hey, RN. As usual, there are a couple different ways you can do this, but perhaps the simplest approach is to create a script that monitors WMI events. We don’t have time to do a detailed explanation of WMI events in this column, but the basic idea is that you can ask WMI to notify you when certain things happen. For example, you might request notification when hard disk space drops below a specified amount, or when CPU consistently spikes above a pre-determined level. Likewise, you can request notification any time a service changes state; that is, any time a service that was running is stopped, or any time a service that was stopped is re-started. If a service goes down, you can ask WMI to tell you about it.

The following script checks for changes in service status; every 30 seconds it looks to see if any services have changed state. The script is set up in an endless loop, which means that, once started, it will continue to run forever and ever, or at least until you reboot the machine or terminate the script process.

strComputer = "."
Set objWMIService = GetObject("winmgmts:" _
    & "{impersonationLevel=impersonate}!\\" & strComputer & "\root\cimv2")
Set colServices = objWMIService. _ 
    ExecNotificationQuery("Select * from __InstanceModificationEvent " _ 
        & "within 30 where TargetInstance isa 'Win32_Service'")
i = 0
Do While i = 0
    Set objService = colServices.NextEvent
    If objService.TargetInstance.State <> _ 
        objService.PreviousInstance.State Then
        Wscript.Echo objService.TargetInstance.Name _ 
            &  " is " & objService.TargetInstance.State _
                & ". The service previously was " & objService.PreviousInstance.State & "."
    End If
Loop

As you can see, pretty easy. Any time a service is modified in any way, an instance of the __InstanceModificationEvent class is created. The script compares the current state of the modified service (TargetInstance.State) with the previous state of the service (PreviousInstance.State). What if the two are the same; that is, what if the service is currently running, and was previously running? In that case, we just ignore the event; that means that some other property of the service was modified. (For example, you might have changed the service password, or maybe switched the service from Manual start to Autostart.) If the two states differ - that is, if the service used to be running but now is stopped - a message box pops up telling us the name of the service, its current state, and its previous state. Cool, huh?

WMI events can be incredibly useful to system administrators; for more information check out this Tales from the Script column.