Status check of service is failing

0

I am working on Windows 2008 Server R2. I found this VBScript that should be checking the whether a service is either started or stopped.

Here is the script:

'Declare Variables
Dim objWMIService, objProcess, colProcess, Status, strComputer, strService

'Assign Arguments
strComputer = WScript.Arguments(0)
strService = WScript.Arguments(1) 
Status = False

'Check For Arguments - Quit If None Found
If Len(strService) < 1 Then
    Wscript.echo "No Arguments Entered - Exiting Script"
    WScript.Quit
End If

'Setup WMI Objects
Set objWMIService = GetObject("winmgmts:"& "{impersonationLevel=impersonate}!\\" & strComputer & "\root\cimv2") 
Set colProcess = objWMIService.ExecQuery ("SELECT DisplayName, Status, State FROM Win32_Service WHERE DisplayName = '" & strService & "'")

'Check For Running Service
For Each objProcess In colProcess
    If InStr(objProcess.DisplayName, strService) > 0 And objProcess.State = "Running" Then
        Status = True
    End If
Next

If Status = True Then
    WScript.Echo "Service: " & UCase(strComputer) & " " & strService & " Running"
Else
    WScript.Echo "Service: " & UCase(strComputer) & " " & strService & " Not Running"
End If

Via the command line I call the script like this

CSCRIPT ServiceCheckScript.vbs LOCALHOST "Print Spooler"

Response from the command line is

...\ServiceCheckScript.vbs(20, 1) (null): 0x80041017

I see that the 0x80041017 error refers to result of a query returning a null value, but I am not sure as to why that may be.

service
command-line
vbscript
wmi
windows-server-2008-r2
asked on Stack Overflow Dec 29, 2015 by wellmannered • edited Dec 30, 2015 by Ansgar Wiechers

1 Answer

0

A few issues with the above code:

  1. Verify you got results from your WMI query so you don't attempt to use a null. Wrap the use of the results in if colProcess.count > 0 then.

  2. Remove the extra .quit by enclosing your code in the parameters verification. Its cheaper/cleaner to do this with an argument count than a string function wscript.arguments.count = 2 since you were only checking to ensure they were not empty. If you need a more sophisticated validation, then more logic would be required.

  3. There isn't any reason to use instr(objProcess.Displayname, strService) because your WMI query already specified that the results are equal to the service display name in this, where DisplayName = strService.

  4. It's simpler/clearer to perform the conditional inspection of service status all inside the loop.

Here is my example.

'Declare Variables
Dim objWMIService, objProcess, colProcess, Status, strComputer, strService

'Verify arguments were passed
if WScript.Arguments.Count = 2 then
   'Assign Arguments
   strComputer = WScript.Arguments(0)
   strService = WScript.Arguments(1) 

   'Setup WMI Objects
   Set objWMIService = GetObject("winmgmts:"& "{impersonationLevel=impersonate}!\\" & _
                       strComputer & "\root\cimv2") 
   Set colProcess = objWMIService.ExecQuery ("SELECT DisplayName, Status, State FROM " & _
                    "Win32_Service WHERE DisplayName = '" & strService & "'")

   'Ensure there were results returned
   if colProcess.count > 0 then
      'Check For Running Service
      For Each objProcess In colProcess
         If objProcess.State = "Running" Then
            WScript.Echo "Service: " & UCase(strComputer) & " " & strService & " Running"
         else
            WScript.Echo "Service: " & UCase(strComputer) & " " & strService & " Not Running"
         End If
      Next
   else
      WScript.Echo "Service: " & UCase(strComputer) & " " & strService & " Does not exist"
   end if
end if

edit: Just adding that I validated the above code in both Win 8.1 and Server 2012R2, using both valid and invalid service names. However, I would add more error checking, like verifying the computer parameter is valid to ensure your WMI query doesn't fail unnecessarily/inexplicably.

answered on Stack Overflow Jan 3, 2016 by RLH

User contributions licensed under CC BY-SA 3.0