Monitoring Multiple Simular Windows Services with one Script

by techpilot007 8. May 2012 16:44

 

One of the first things I was asked to monitor with Nagios was the running state of a few Windows services.  I could use NRPE to accomplish this but I found that I also needed to monitor the status of a few different versions of Tomcat for out Business Object servers. 

 

The built in NRPE checks with Nagios and NSClient++ require you to use the exact name of the service when you make the call for the service’s status.  The name of the Tomcat service varies with the different versions of B.O., ex. BOEXI40Tomcat, BOE120Tomcat. Because of the different names with the versions we have I liked the idea of only having one service definition in Nagios to check on the various Tomcat Services.  This is where my custom wsf (vbScript) came into play. 

 

WMI queries allow you to use a SELECT statement that matches on a LIKE condition.  When matching with a LIKE condition you can use a variable in the value you are querying for.  It’s very similar to using a LIKE query in MS SQL Server.  The variable operator to use in this case would be the percent symbol ‘%’.  This allows you to make a WMI query that looks like this:

"SELECT * FROM Win32_Service WHERE Name Like 'BOE%Tomcat'

 

As with most of the scripts I create I like to make them flexible enough to use for more than just one purpose. With that in mind I setup the script to accept a command line variable (s:/Service_Name).

cscript check_services.wsf /s:BOE%Tomcat

The output from the script gives Nagios not only a string of information but also an exit status/code. The string that the script outputs uses the service states as documented by MSDN. Below are those service states and the exit status(es)/code(s) that I've associated with them.
         "Start Pending" Exit Status = 1
         "Running" Exit Status = 0
         "Stop Pending" Exit Status = 1
         "Stopped" Exit Status = 2
         "Pause Pending" Exit Status = 1
         "Paused" Exit Status = 2
         "Continue Pending" Exit Status = 1
         "Unknown" Exit Status =3

The output also included performance data for Nagios so we can use our graphing tool to visualize the stability of the service. (Graphing seems to be easier on the eyes for many) An example of the output produced by the script is:

Service: BOEXI40Tomcat : Running | service_running=2;1;0

The complete script is below. As with every script I've created I'm sure there are better ways of accomplishing the same task but this is what I came up with.

'
'***********************************************************************
' "check_service.wsf"
' Checks for service status on a Windows platform.
'************************************************************************
' Copyright (c) 2012 Jeremy McEachron (techpilot007)
' All rights reserved.
'
' Redistribution and use in source and binary forms, with or without
' modification, are permitted provided that the following conditions
' are met:
' 1. Redistributions of source code must retain the above copyright
'    notice, this list of conditions and the following disclaimer.
' 2. Redistributions in binary form must reproduce the above copyright
'    notice, this list of conditions and the following disclaimer in the
'    documentation and/or other materials provided with the distribution.
'
' THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
' ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
' IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
' ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
' FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
' DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
' OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
' HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
' LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
' OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
' SUCH DAMAGE.
'

<job>
<runtime>
  <description>

check_services (nrpe_nt-plugin) 1.5
This nrpe_nt plugin come with ABSOLUTELY NO WARRANTY. You may redistribute
copies of the plugins under the terms of the GNU General Public License.

  </description>
    <named
      name="h"
      helpstring="Help"
      type="simple"
      required="false" 
    />
  />

  <example>
         
  You need to provide a string for this plugin.
         	
  This script checks the current status of a specified service. If using a wildcard character 
  for the name of your service then you need to use the percent symbol (%).
    
  Usage: command[check_services]=c:\Windows\system32\cscript.exe //nologo //T:60 check_services.wsf "$ARG1$"
  cscript check_services.wsf /s:explorer

  </example>

</runtime>

<script language="VBScript">


'*******************************************************************
' Help
'*******************************************************************
If Wscript.Arguments.Named.Exists("h") Then
      Wscript.Echo "Plugin help screen:"
      Wscript.Arguments.ShowUsage()
      Wscript.Quit(3)
End If

'*******************************************************************
' Main
'*******************************************************************


Dim OutputCode, objWMIService, colItems, ComputerName, strOutput, ServiceFound

' Default to an UNKNOWN error
OutputCode = 3

' Have we found this service yet?
ServiceFound = 0

args = WScript.Arguments.Count

If args < 1 Then
   WScript.Echo "Usage:  check_services.vbs [service name]"
   WScript.Echo ""
   WScript.Echo "Note:  The service name is the name listed in the properties of the"
   WScript.Echo "       service and is case sensitive."
   WScript.Echo ""
   WScript.Quit( OutputCode )
End If

'*******************************************************************
' load args
'*******************************************************************
Set colNamedArguments = WScript.Arguments.Named
intServiceName = colNamedArguments.Item("s")

ComputerName = "."

Set objWMIService = GetObject("winmgmts:{impersonationLevel=impersonate}!\\" & ComputerName & "\root\cimv2")
Set colItems = objWMIService.ExecQuery("SELECT * FROM Win32_Service WHERE Name Like '" & intServiceName & "'",,48) 
	
' Attempt to enumerate the IIS sites.  However, if IIS is not installed on this
' host, it will give us a runtime error with GetObject.  Skip the error if we
' get it with 'On Error Resume Next', and then we can trap the problem below
Err.Clear

' Work our way through the list of sites and find the one we're looking at, if 
' possible.  I'm sure there is a better way to do this.
For Each objItem in colItems
         ServiceFound = 1
         strOutput = "Service: " & objItem.Name
         '
		 ' Services States, per MSDN
		 ' 
		 ' "Start Pending"
		 ' "Running"
		 ' "Stop Pending"
		 ' "Stopped"
		 ' "Pause Pending"
		 ' "Paused"
		 ' "Continue Pending"
		 ' "Unknown"

         Select Case objItem.State
            Case "Start Pending"
               strOutput = strOutput & " : Start Pending | service_running=1;1;0"
               OutputCode = 1
            Case "Running"
               strOutput = strOutput & " : Running | service_running=2;1;0"
               OutputCode = 0
            Case "Stop Pending"
               strOutput = strOutput & " : Stop Pending | service_running=1;1;0"
               OutputCode = 1
            Case "Stopped"
               strOutput = strOutput & " : Stopped | service_running=0;1;0"
               OutputCode = 2
            Case "Pause Pending"
               strOutput = strOutput & " : Pause Pending | service_running=1;1;0"
               OutputCode = 1
            Case "Paused"
               strOutput = strOutput & " : Paused | service_running=0;1;0"
               OutputCode = 2
            Case "Continue Pending"
               strOutput = strOutput & " : Continue Pending | service_running=1;1;0"
               OutputCode = 1
            Case else
                    strOutput = strOutput & " : UNKNOWN STATE " & objItem.State & " | service_running=0;1;0"
         End Select
Next

' If we didn't find a Service, error out
If ServiceFound <> 1 Then
   strOutput = "UNKNOWN: Service " & intServiceName & " not found | service_running=0;1;0"
   OutputCode = 3
End If

WScript.Echo strOutput
WScript.Quit( OutputCode )
'*******************************************************************
</script>
</job>

 

 

Comments are closed

Jeremy

Welcome to the blog of an Configuration Manager. This blog is meant to share my thoughts, ideas, and the story of my ever expanding journey to acquire knowledge. It may, at times, include rants about or an expression of excitement over something in the computer realm. The majority of my work is with Windows servers. However, it has started to also include Linux machines. Lately I’ve become the Nagios “expert” within our company as I work towards creating culture of being proactive vs. reactive in regards to Application/Configuration Management.

 

(The information in this blog is provided “AS IS” with no warranties, and confers no rights implied or otherwise. The views, opinions, and ideas, expressed here are my own, and may not necessarily represent the views and opinions of my employer, past, current, or future.)

 

Calendar

<<  December 2017  >>
MoTuWeThFrSaSu
27282930123
45678910
11121314151617
18192021222324
25262728293031
1234567

View posts in large calendar