'''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''' ' ' NAME: check_microsoft_cluster.vbs ' VERSION: 1.0 ' AUTHOR: Herbert Stadler (hestadler@gmx.at) ' ' COMMENT: Script for Checking MSCS Cluster resources ' for use with Nagios and NSClient++ ' ' Modification History: ' 2010-04-15 Creation ' ' ' License Information: ' This program is free software; you can redistribute it and/or modify ' it under the terms of the GNU General Public License as published by ' the Free Software Foundation; either version 3 of the License, or ' (at your option) any later version. ' ' This program is distributed in the hope that it will be useful, ' but WITHOUT ANY WARRANTY; without even the implied warranty of ' MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ' GNU General Public License for more details. ' ' You should have received a copy of the GNU General Public License ' along with this program; if not, see . ' ' ' '''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''' ' NAGIOS DEFINITIONS: ' ' ### command definition ### ' ' define command { ' command_name check_mscs ' command_line $USER1$/check_nrpe -H $HOSTADDRESS$ -p 5666 -t 30 -c check_mscs -a "$ARG1$" "$ARG2$" ' } ' ### service definition ### ' define service{ ' use generic-service ' host_name CLUSTERPPCL ' service_description Microsoft Cluster Resources ' process_perf_data 0 ' check_command check_mscs!CLRES!"SQL Server,Disk S:" ' } ' ' or ' ' check_command check_mscs!"CLRES" ' check_command check_mscs!"CLRESP" ' check_command check_mscs!"CLNODE" ' Option explicit Dim strArglist Dim strWmiQuery Dim strResName Dim strNodeName Dim strResultCritical Dim strResultWarning Dim strStatus Dim arrResNames Dim arrNodeNames Dim objArgs Dim objItem Dim objWMIService Dim colItems Dim i Dim strArg, objArg Dim strCommand Dim CheckedElement Dim objCluster 'RC to NAGIOS Const intOK = 0 Const intWarning = 1 Const intCritical = 2 Const intUnknown = 3 ' if someone want's to switch off checking of "not defined" preferred cluster node of resource groups Const strCHECK_EMPTY_PREFERREDNODE = "ON" strResultCritical = "" strResultWarning = "" Set objArgs = WScript.Arguments if objArgs.Count = 0 then Display_Usage() end if for Each objArg In objargs strArg = LCase(objArg) Select Case strArg Case "-h" Display_Usage() Case "--help" Display_Usage() Case "-help" Display_Usage() Case "-?" Display_Usage() Case "/?" Display_Usage() Case "/h" Display_Usage() End Select Next strCommand=UCase(objArgs(0)) strArglist="" if strCommand = "CLRES" or strCommand = "CLNODE" or strCommand = "CLRESP" Then If objArgs.Count > 1 Then for i = 1 to objArgs.Count - 1 if objArgs(i) = "$ARG2$" or _ objArgs(i) = "$ARG3$" or _ objArgs(i) = "$ARG4$" then else If strArglist = "" Then strArglist = objArgs(i) Else strArglist = strArglist & " " & objArgs(i) End If end if next End if End if Set objCluster = CreateObject("MSCluster.Cluster") objCluster.Open "" Set objWMIService = GetObject("winmgmts:{impersonationLevel=impersonate}!\\.\root\mscluster") Select Case strCommand Case "CLRES" Check_CLRES(strCommand) Case "CLRESP" Check_CLRES(strCommand) Case "CLNODE" arrNodeNames = Split(strArglist, ",") strWmiQuery = "Select * from MSCluster_Node" Set colItems = objWMIService.ExecQuery(strWmiQuery) if Entered_Values_Wrong(colItems,arrNodeNames) then Wscript.StdOut.WriteLine "Entered NodeNames wrong: " & CheckedElement WScript.Quit(intUnknown) end if For Each objItem in colItems do while true if not Object_in_Array(objItem.Name, arrNodeNames) then exit do End if strStatus=Explain_Node_State (objItem.State) If strStatus = "paused" or strStatus = "joining" Then if strResultWarning <> "" then strResultWarning=strResultWarning & ", " end if strResultWarning = strResultWarning & objItem.Name & " (" & strStatus & ")" End If If strStatus = "down" or strStatus = "unknown" Then if strResultCritical <> "" then strResultCritical=strResultCritical & ", " end if strResultCritical = strResultCritical & objItem.Name & " (" & strStatus & ")" End If exit do loop next If strResultWarning = "" and strResultCritical = "" Then Wscript.StdOut.WriteLine "OK - Clusternodes" WScript.Quit(intOK) End If If strResultCritical = "" Then Wscript.StdOut.WriteLine "WARNING - Clusternodes: " & strResultWarning WScript.Quit(intWarning) Else dim strMsgOut strMsgOut="CRITICAL - Clusternodes: " & strResultCritical if strResultWarning <> "" then strMsgOut=strMsgOut & ", " & strResultWarning end if Wscript.StdOut.WriteLine strMsgOut WScript.Quit(intCritical) End If Case "LIST" wscript.StdOut.WriteLine "List of Cluster Resource Information" wscript.StdOut.WriteLine "------------------------------------" strWmiQuery = "Select * from MSCluster_Resource" Set colItems = objWMIService.ExecQuery(strWmiQuery) For Each objItem in colItems wscript.StdOut.WriteLine Make_Length(objItem.Name,40) & vbTab & Explain_Res_State (objItem.State) & vbTab & objItem.Status next wscript.StdOut.WriteLine "" wscript.StdOut.WriteLine "List of Cluster Node Information" wscript.StdOut.WriteLine "----------------------------------" strWmiQuery = "Select * from MSCluster_Node" Set colItems = objWMIService.ExecQuery(strWmiQuery) For Each objItem in colItems wscript.StdOut.WriteLine objItem.Name & vbTab & vbTab & Explain_Node_State (objItem.State) & vbTab & objItem.Status next wscript.StdOut.WriteLine "" wscript.StdOut.WriteLine "List of Cluster Network Information" wscript.StdOut.WriteLine "-----------------------------------" strWmiQuery = "Select * from MSCluster_Network" Set colItems = objWMIService.ExecQuery(strWmiQuery) For Each objItem in colItems wscript.StdOut.WriteLine Make_Length(objItem.Name,20) & vbTab & Explain_Net_State (objItem.State) & vbTab & objItem.Status next wscript.StdOut.WriteLine "" wscript.StdOut.WriteLine "List of Cluster Resource Group Information" wscript.StdOut.WriteLine "------------------------------------------" strWmiQuery = "Select * from MSCluster_ResourceGroup" Set colItems = objWMIService.ExecQuery(strWmiQuery) For Each objItem in colItems wscript.StdOut.WriteLine Make_Length(objItem.Name,20) & vbTab & Explain_Group_State (objItem.State) & vbTab & objItem.Status & vbTab & objItem.AutoFailbackType next wscript.StdOut.WriteLine "" wscript.StdOut.WriteLine "List of Cluster Resource Group Preferred Node Information" wscript.StdOut.WriteLine "---------------------------------------------------------" strWmiQuery = "Select * from MSCluster_ResourceGroupToPreferredNode" Set colItems = objWMIService.ExecQuery(strWmiQuery) For Each objItem in colItems wscript.StdOut.WriteLine Make_Length(objItem.GroupComponent,20) & vbTab & objItem.PartComponent next Dim res Dim resGroup For Each res in objCluster.Nodes For Each resGroup in res.ResourceGroups If (resGroup.PreferredOwnerNodes.count > 0) Then For i=1 To resGroup.PreferredOwnerNodes.count if resGroup.OwnerNode.Name <> resGroup.PreferredOwnerNodes.Item(i).Name then wscript.StdOut.WriteLine "!!WARNING!! Resource Group " & resGroup.Name & " not on PreferredNode " & resGroup.PreferredOwnerNodes.Item(i).Name end if next else wscript.StdOut.WriteLine "!!WARNING!! Resource Group " & resGroup.Name & " no PreferredNode set" end if next next wscript.StdOut.WriteLine "" wscript.StdOut.WriteLine "List of Cluster Resource Type Information" wscript.StdOut.WriteLine "-----------------------------------------" strWmiQuery = "Select * from MSCluster_ResourceType" Set colItems = objWMIService.ExecQuery(strWmiQuery) For Each objItem in colItems wscript.StdOut.WriteLine Make_Length(objItem.Name,20) & vbTab & objItem.Status next wscript.StdOut.WriteLine "" wscript.StdOut.WriteLine "List of Cluster Service Information" wscript.StdOut.WriteLine "-----------------------------------" strWmiQuery = "Select * from MSCluster_Service" Set colItems = objWMIService.ExecQuery(strWmiQuery) For Each objItem in colItems wscript.StdOut.WriteLine Make_Length(objItem.Name,20) & vbTab & objItem.SystemName & vbTab & objItem.State & vbTab & objItem.Status next wscript.StdOut.WriteLine "" wscript.StdOut.WriteLine "List of Cluster Information" wscript.StdOut.WriteLine "---------------------------" strWmiQuery = "Select * from MSCluster_Cluster" Set colItems = objWMIService.ExecQuery(strWmiQuery) For Each objItem in colItems wscript.StdOut.WriteLine Make_Length(objItem.Name,20) & vbTab & objItem.Status next WScript.Quit(intOK) Case else Wscript.StdOut.WriteLine "Parameter wrong: " & strCommand WScript.Quit(intUnknown) End Select Function Check_CLRES (strCommand) arrResNames = Split(strArglist, ",") strWmiQuery = "Select * from MSCluster_Resource" Set colItems = objWMIService.ExecQuery(strWmiQuery) if Entered_Values_Wrong(colItems,arrResNames) then Wscript.StdOut.WriteLine "Entered ResourceNames wrong: " & CheckedElement WScript.Quit(intUnknown) end if For Each objItem in colItems do while true if not Object_in_Array(objItem.Name, arrResNames) then exit do End if strStatus=Explain_Res_State (objItem.State) If strStatus <> "online" Then if strResultCritical <> "" then strResultCritical=strResultCritical & ", " end if strResultCritical = strResultCritical & objItem.Name & " (" & strStatus & ")" End If exit do Loop Next If strResultCritical = "" Then if ( strCommand = "CLRESP" ) Then dim strPrefNode strPrefNode=Check_ClusterResource_PreferredNode() if ( strPrefNode <> "" ) then Wscript.StdOut.WriteLine "WARNING - Clusterresource: " & strPrefNode & " not on preferred node" WScript.Quit(intWarning) End If end if Wscript.StdOut.WriteLine "OK - Clusterresource" WScript.Quit(intOK) Else Wscript.StdOut.WriteLine "CRITICAL - Clusterresource: " & strResultCritical WScript.Quit(intCritical) End If End Function Function Check_ClusterResource_PreferredNode () Dim res Dim resGroup Dim strResult strResult="" For Each res in objCluster.Nodes For Each resGroup in res.ResourceGroups If (resGroup.PreferredOwnerNodes.count > 0) Then For i=1 To resGroup.PreferredOwnerNodes.count if resGroup.OwnerNode.Name <> resGroup.PreferredOwnerNodes.Item(i).Name then strResult=Build_String(strResult,resGroup.Name) Exit For end if next else if ( strCHECK_EMPTY_PREFERREDNODE = "ON" ) Then strResult=Build_String(strResult,resGroup.Name) End If end if next next Check_ClusterResource_PreferredNode=strResult End Function Function Build_String (strResult,strName) if ( strResult <> "" ) then strResult=strResult & ", " end if strResult=strResult & strName Build_String=strResult End Function Function Explain_Node_State (state) dim strStatus Select Case state Case 0 strStatus = "up" Case 1 strStatus = "down" Case 2 strStatus = "paused" Case 3 strStatus = "joining" Case Else strStatus = "unknown" End Select Explain_Node_State=strStatus End Function Function Explain_Group_State (state) dim strStatus Select Case state Case 0 strStatus = "Online" Case 1 strStatus = "Offline" Case 2 strStatus = "Failed" Case 3 strStatus = "PartialOnline" Case 4 strStatus = "Pending" Case Else strStatus = "StateUnknown" End Select Explain_Group_State=strStatus End Function Function Explain_Net_State (state) dim strStatus Select Case state Case 0 strStatus = "StateUnavailable" Case 1 strStatus = "Down" Case 2 strStatus = "Partitioned" Case 3 strStatus = "Up" Case Else strStatus = "StateUnknown" End Select Explain_Net_State=strStatus End Function Function Explain_Res_State (state) dim strStatus Select Case state Case 2 strStatus = "online" Case 3 strStatus = "offline" Case 4 strStatus = "failed" Case 129 strStatus = "online pending" Case 130 strStatus = "offline pending" Case Else strStatus = "unknown" End Select Explain_Res_State=strStatus End Function Function Display_Usage Wscript.StdOut.WriteLine "" Wscript.StdOut.WriteLine "Check Microsoft Cluster Usage" Wscript.StdOut.WriteLine "" Wscript.StdOut.WriteLine " check_microsoft_cluster.vbs CLRES [resource list]" & vbcrlf wscript.StdOut.WriteLine " same as above with checking if owner = preferred owner (preferred node)" Wscript.StdOut.WriteLine " check_microsoft_cluster.vbs CLRESP [resource list]" & vbcrlf Wscript.StdOut.WriteLine " check_microsoft_cluster.vbs CLNODE [node list]" Wscript.StdOut.WriteLine vbcrlf & " for debugging purposes:" Wscript.StdOut.WriteLine " check_microsoft_cluster.vbs LIST" Wscript.StdOut.WriteLine "" Wscript.StdOut.WriteLine vbTab & "resource list list of MSCS resource names to be monitored" Wscript.StdOut.WriteLine vbTab & "node list list of MSCS node names to be monitored" Wscript.StdOut.WriteLine "" Wscript.StdOut.WriteLine "List items are comma separated." Wscript.StdOut.WriteLine "" WScript.Quit(intOK) End Function Function Make_Length (sstr, slen) Dim istrlen istrlen=len(sstr) istrlen = slen - istrlen if istrlen > 0 then Make_Length=sstr & space(istrlen) else Make_Length=sstr End If End Function Function Object_in_Array(strName, arrNames) dim strElement if ubound(arrNames) < 0 then Object_in_Array=true exit function end if For Each strElement in arrNames if StrComp(strName,strElement,0) = 0 then Object_in_Array=true exit function end if Next Object_in_Array=false End Function function Entered_Values_Wrong(colItems,arrNames) dim strElement dim sFound if ubound(arrNames) < 0 then Entered_Values_wrong=false exit function end if For Each strElement in arrNames sFound=false CheckedElement=strElement For Each objItem in colItems if objItem.Name = strElement then sFound=true end if next if sFound = false then Entered_Values_wrong=true exit function end if next Entered_Values_wrong=false end function