Dell Server Fans Status (Event Triggered)

Dell.WindowsServer.ServerFansUnitEventUnitMonitor (UnitMonitor)

Unit Monitor to calculate Dell Server Fans Status on getting a related Event.

Knowledge Base article:

Summary

This Health Monitor fetches the State of Dell Fan Sensors. The status can be one of the following three types:

Success: If the status is success, the fan sensor has returned to a normal state.

Warning: If the status is warning, the fan sensor is reporting a warning state.

Critical: If the status is critical, the fan sensor has detected a failure or a nonrecoverable state.

Causes

Warning: The cause for a Warning status may be that a fan sensor reading in the specified system has exceeded its warning threshold.

Critical: The cause for a Critical status may be that a fan sensor in the specified system detected the failure of one or more fans or detected an error from which it cannot recover. Additional details are available in the product knowledge of the last modified Dell OpenManage alert that caused the state change.

Resolutions

Perform the following steps for the Warning and Critical messages:

Warning: A Warning message refers to an event that is not necessarily significant, but may indicate a possible future problem. Plan to proactively replace the failed fan or change the environment, such as power or cooling, based on the pattern of occurrence, as well as the impact to operations if the fan goes to a critical state.

Critical: A Critical message refers to a significant event that indicates actual or imminent loss of data or loss of function. Change the environment, such as cooling or power, as appropriate; or replace the failed component. Additional details are available in the product knowledge of the last modified Dell OpenManage alert that caused the state change.

When the issue has been resolved, the status changes to Success.

Element properties:

TargetDell.WindowsServer.Sensors
Parent MonitorSystem.Health.AvailabilityState
CategoryAvailabilityHealth
EnabledTrue
Alert GenerateFalse
Alert Auto ResolveTrue
Monitor TypeDell.WindowsServer.EventTriggeredScriptMonitorType.3StateScriptMonitorType
RemotableTrue
AccessibilityPublic
RunAsDefault

Source Code:

<UnitMonitor ID="Dell.WindowsServer.ServerFansUnitEventUnitMonitor" Accessibility="Public" Target="Dell.WindowsServer.Sensors" TypeID="Dell.WindowsServer.EventTriggeredScriptMonitorType.3StateScriptMonitorType" ParentMonitorID="SystemHealth!System.Health.AvailabilityState">
<Category>AvailabilityHealth</Category>
<OperationalStates>
<OperationalState HealthState="Success" MonitorTypeStateID="Success" ID="HealthyState"/>
<OperationalState HealthState="Warning" MonitorTypeStateID="Warning" ID="WarningState"/>
<OperationalState HealthState="Error" MonitorTypeStateID="Critical" ID="CriticalState"/>
</OperationalStates>
<Configuration>
<ComputerName>$Target/Host/Property[Type="Windows!Microsoft.Windows.LogicalDevice"]/DeviceID$</ComputerName>
<LogName>System</LogName>
<EventExpression>
<And>
<Expression>
<SimpleExpression>
<ValueExpression>
<XPathQuery Type="String">PublisherName</XPathQuery>
</ValueExpression>
<Operator>Equal</Operator>
<ValueExpression>
<Value Type="String">Server Administrator</Value>
</ValueExpression>
</SimpleExpression>
</Expression>
<Expression>
<Or>
<Expression>
<Or>
<Expression>
<And>
<Expression>
<SimpleExpression>
<ValueExpression>
<XPathQuery Type="Integer">EventDisplayNumber</XPathQuery>
</ValueExpression>
<Operator>GreaterEqual</Operator>
<ValueExpression>
<Value Type="Integer">1100</Value>
</ValueExpression>
</SimpleExpression>
</Expression>
<Expression>
<SimpleExpression>
<ValueExpression>
<XPathQuery Type="Integer">EventDisplayNumber</XPathQuery>
</ValueExpression>
<Operator>LessEqual</Operator>
<ValueExpression>
<Value Type="Integer">1105</Value>
</ValueExpression>
</SimpleExpression>
</Expression>
</And>
</Expression>
<Expression>
<And>
<Expression>
<SimpleExpression>
<ValueExpression>
<XPathQuery Type="Integer">EventDisplayNumber</XPathQuery>
</ValueExpression>
<Operator>GreaterEqual</Operator>
<ValueExpression>
<Value Type="Integer">5100</Value>
</ValueExpression>
</SimpleExpression>
</Expression>
<Expression>
<SimpleExpression>
<ValueExpression>
<XPathQuery Type="Integer">EventDisplayNumber</XPathQuery>
</ValueExpression>
<Operator>LessEqual</Operator>
<ValueExpression>
<Value Type="Integer">5105</Value>
</ValueExpression>
</SimpleExpression>
</Expression>
</And>
</Expression>
</Or>
</Expression>
<Expression>
<Or>
<Expression>
<And>
<Expression>
<SimpleExpression>
<ValueExpression>
<XPathQuery Type="Integer">EventDisplayNumber</XPathQuery>
</ValueExpression>
<Operator>GreaterEqual</Operator>
<ValueExpression>
<Value Type="Integer">1450</Value>
</ValueExpression>
</SimpleExpression>
</Expression>
<Expression>
<SimpleExpression>
<ValueExpression>
<XPathQuery Type="Integer">EventDisplayNumber</XPathQuery>
</ValueExpression>
<Operator>LessEqual</Operator>
<ValueExpression>
<Value Type="Integer">1455</Value>
</ValueExpression>
</SimpleExpression>
</Expression>
</And>
</Expression>
<Expression>
<And>
<Expression>
<SimpleExpression>
<ValueExpression>
<XPathQuery Type="Integer">EventDisplayNumber</XPathQuery>
</ValueExpression>
<Operator>GreaterEqual</Operator>
<ValueExpression>
<Value Type="Integer">5450</Value>
</ValueExpression>
</SimpleExpression>
</Expression>
<Expression>
<SimpleExpression>
<ValueExpression>
<XPathQuery Type="Integer">EventDisplayNumber</XPathQuery>
</ValueExpression>
<Operator>LessEqual</Operator>
<ValueExpression>
<Value Type="Integer">5455</Value>
</ValueExpression>
</SimpleExpression>
</Expression>
</And>
</Expression>
</Or>
</Expression>
</Or>
</Expression>
</And>
</EventExpression>
<ScriptName>DellServerFansUnitUnitMonitorEventTrigger.vbs</ScriptName>
<Arguments>$MPElement$ $Target/Id$ $Config/Computer$ $Target/Property[Type="Dell.WindowsServer.Sensors"]/ServerType$</Arguments>
<ScriptBody><Script>
'**********************************************************************************
' Script Name - DellServerFansPeriodicUnitMonitor
' Author: Vignesh Pandian
'
' Description:
' Determine Unit Monitor health for ServerFans
'
' (c) Copyright &#xA9; 2009&#x2013; 2017 Dell Inc, or its subsidiaries. All Rights Reserved
'**********************************************************************************
Option Explicit
On Error Resume Next
SetLocale("en-us")

Dim oArgs
Set oArgs = WScript.Arguments
if oArgs.Count &lt; 4 Then
Wscript.Quit -1
End If

Dim serverType:serverType = oArgs(3)
If ( StrComp(serverType, "ModularBlade") &lt;&gt; 0 ) Then
MOMDebugLog 1, "Setting ModularBlade status to OK"
Call oBag.AddValue("Status","OK")
Call oAPI.Return(oBag)
Wscript.Quit 0
End if

Dim RedundancyState

Dim strComputer, objDellConnection, LogMessage, sQuery, colItems, objItemFan, FanStatus, TargetComputer, prmDeviceID
TargetComputer = oArgs(2)
strComputer = "."

set objDellConnection = GetObject("winmgmts:" &amp; "{impersonationLevel=impersonate}!\\" &amp; strComputer &amp; "\root\cimv2\Dell")
If Err.Number &lt;&gt; 0 Then
LogMessage = "WMI Cimv2Dell Error Number : " &amp; Err.Number &amp; ". Description :" &amp; Err.Description
Err.Clear
Else
If IsEmpty(objDellConnection) Then
LogMessage = "Unable to open WMI Namespace root-cimv2-dell. Check to see if the WMI service is enabled and running, and Install/Re-Install ServerAdministrator to ensure this WMI namespace exists. " &amp; Err
Else
sQuery = "Select * from DELL_FanRedundancyGroup"
Set colItems = GetObjectSet(objDellConnection, sQuery, "__COUNT__", "DELL_FanRedundancyGroup")
If Err.Number &lt;&gt; 0 Then
LogMessage = sQuery &amp; " Error Number:" &amp; Err.Number &amp; "Description:" &amp; Err.Description
If Err.Number = -2147023169 Then
LogMessage = "RPC Failure occurred for namespace root-cimv2-dell"
End If
Err.Clear
End If
If colItems is Nothing Then
LogMessage = "Unable to retrieve DELL_PSRedundancyGroup object"
Err.Clear
Else
If (colItems.Count &gt; 0) Then
RedundancyState = 1
End If
End If 'colItems is nothing
Set colItems = Nothing

sQuery = "Select * from Dell_Chassis"
Set colItems = GetObjectSet(objDellConnection, sQuery, "SystemClass", "Dell_Chassis")
If Err.Number &lt;&gt; 0 Then
LogMessage = sQuery &amp; " Error Number:" &amp; Err.Number &amp; "Description:" &amp; Err.Description
If Err.Number = -2147023169 Then
LogMessage = "RPC Failure occurred for namespace root-cimv2-dell"
End If
Err.Clear
End If
If colItems is Nothing Then
LogMessage = "Unable to retrieve Dell_Chassis object"
Err.Clear
Else
LogMessage = "Dell_Chassis object retrieved"
For Each objItemFan in colItems
If Err.Number &lt;&gt; 0 Then
If Err.Number = -2147023169 Then
LogMessage = "RPC Failure occurred for cimv2\dell - bmc info : " &amp; Err.Number
ElseIf Err.Number = -2147217389 Then
LogMessage = "If Fan present, Please Install/Re-Install ServerAdministrator on Dell Server : " &amp; Err.Number
Else
LogMessage = "Object RetrievalLoop Error Number:" &amp; Err.Number &amp; "Description:" &amp; Err.Description
End If
Err.Clear
End If
If Not objItemFan is Nothing Then
If RedundancyState = 1 Then
FanStatus = objItemFan.FanRedStatus
Else
FanStatus = objItemFan.FanStatus
End If
End If
Next
End If 'colItems is nothing
Set colItems = Nothing
End If 'dellconnection is nothing
End If

If FanStatus = "Stressed" OR FanStatus = "Degraded" Then
FanStatus = "Warning"
ElseIf FanStatus = "Non-recover" Then
FanStatus = "Error"
End If

Dim oAPI, oBag
Set oAPI = CreateObject("MOM.ScriptAPI")
Set oBag = oAPI.CreatePropertyBag()
Call oBag.AddValue("Status",FanStatus)

Call oAPI.Return(oBag)
' *** Add double query fix

' Function to retrieve the object

Function GetObjectSet(ByRef objDellConnection, SelectQuery, Attribute, objName)
Dim retry, retryFlag
Dim objItem, arrURL, logMessage

On Error Resume Next
RetryFlag = False
For retry = 0 To 1
MOMDebugLog 1, "Retrying for " &amp; retry &amp; " time..."
Set GetObjectSet = objDellConnection.ExecQuery(SelectQuery)
LogErrorNumber(objName)
If (GetObjectSet is Nothing) Or (IsNull(GetObjectSet)) Then
logMessage = "INFO: Unable to retrieve " &amp; objName &amp; " Attributes"
MOMDebugLog 1, logMessage
WScript.Sleep(1000)
RetryFlag = True
Else
logMessage= "INFO: " &amp; objName &amp; " attributes retrieved successfully"
MOMDebugLog 1, logMessage
If Attribute = "__COUNT__" Then
Exit For
End If
For Each objItem in GetObjectSet
If LogErrorNumber(objName) = 0 Then
If Not objItem is nothing Then
Dim attrVal : attrVal = objItem.Properties_.Item(Attribute)
If IsNull(attrVal) Or Len(attrVal) &lt;= 0 Then
MOMDebugLog 1, Attribute &amp; " value is null or empty"
RetryFlag = True
WScript.Sleep(500)
Exit For
Else
Exit Function
End If
End If
End If
Next
If RetryFlag = False Then
Exit For
End If
End If
Next
End Function

Function LogErrorNumber(objName)
Dim logMessage
LogErrorNumber = Err.Number
If Err.Number &lt;&gt; 0 Then
Select Case Err.Number
Case -2147749904
logMessage = "CIM Object not found"
Case -2147749902
logMessage = "Dell CIM object not found"
Case -2147023169
logMessage = "RPC Failure occurred for namespace root-cimv2-dell"
Case -2147217389
logMessage = "Please Install/Re-Install ServerAdministrator on Dell Server!"
Case -2147217394 '0x8004100E
logMessage = "Not able to find Dell CIM object"
Case -2147217392 '0x8004100C
logMessage = "Not able to find the collection"
Case -2147749890
logMessage = "Object cannot be found"
Case -2147749892
logMessage = "Object cannot be found"
Case Else
logMessage = "Unable to retrieve " &amp; objName
logMessage = logMessage &amp; " Err Number:" &amp; Err.Number
logMessage = logMessage &amp; " Err Descr:" &amp; Err.Description
End Select
MOMDebugLog 1, "ERROR: " &amp; logMessage
End If
End Function
'*** Add MOMDebug
Const DEBUG_LOG_FILENAME = "DellServerFansUnitUnitMonitorEventTrigger.log"
Dim loginited: loginited = False
Dim objLogTextFile, objLogFSO

Sub InitLog(strFileName)
' Begin Logheader
If logLevel &lt;&gt; 0 And loginited = False Then
Dim fileSize, strOutFile
Const ForAppending = 8
Const ForWriting = 2
Const MaxFileSize = 524288 'File Size is limited to 512 KB

dim wsShell : Set wsShell = Createobject("WScript.Shell")
dim wshSysEnv : Set wshSysEnv = wsShell.Environment
dim tFolder : tFolder = wshSysEnv("TEMP")
dim wshPrcEnv : Set wshPrcEnv = wsShell.Environment("Process")
tFolder = Replace(tFolder, "%SystemRoot%", wshPrcEnv("SYSTEMROOT"), 1, -1, vbTextCompare)

Set objLogFSO = CreateObject("Scripting.FileSystemObject")
If Not objLogFSO.FolderExists(tFolder) Then
objLogFSO.CreateFolder(tFolder)
End If
strOutFile = tFolder &amp; "\"&amp; strFileName
WScript.Echo strOutFile
If Not objLogFSO.FileExists(strOutFile) Then
Set objLogTextFile = objLogFSO.CreateTextFile(strOutFile)
objLogTextFile.Close()
End If
fileSize = objLogFSO.GetFile(strOutFile).Size
If (fileSize &gt; MaxFileSize) Then
Set objLogTextFile = objLogFSO.OpentextFile(strOutFile, ForWriting, True)
Else
Set objLogTextFile = objLogFSO.OpentextFile(strOutFile, ForAppending, True)
End If
loginited = True
MOMDebugLog 1, "------------------------------------------------------"
MOMDebugLog 1, "INFO: Script - " &amp; strFileName &amp; ": Start()"
Err.Clear
End If
End Sub

Sub MOMDebugLog (ByVal debugLevel, ByVal Message)
'On Error Resume Next
If (debugLevel &gt; 0) and (debugLevel &lt;= logLevel) Then
If loginited = False Then
InitLog DEBUG_LOG_FILENAME
End If
objLogTextFile.WriteLine(Now() &amp; " ---- " &amp; Message)
Err.Clear
End If
End Sub

Sub CloseLog
' Begin Logheader
If loginited = True Then
objLogTextFile.Close
End If
End Sub

CloseLog
</Script></ScriptBody>
<TimeoutSeconds>300</TimeoutSeconds>
<SuccessExpression>
<SimpleExpression>
<ValueExpression>
<XPathQuery Type="String">Property[@Name='Status']</XPathQuery>
</ValueExpression>
<Operator>Equal</Operator>
<ValueExpression>
<Value Type="String">OK</Value>
</ValueExpression>
</SimpleExpression>
</SuccessExpression>
<WarningExpression>
<SimpleExpression>
<ValueExpression>
<XPathQuery Type="String">Property[@Name='Status']</XPathQuery>
</ValueExpression>
<Operator>Equal</Operator>
<ValueExpression>
<Value Type="String">Warning</Value>
</ValueExpression>
</SimpleExpression>
</WarningExpression>
<CriticalExpression>
<SimpleExpression>
<ValueExpression>
<XPathQuery Type="String">Property[@Name='Status']</XPathQuery>
</ValueExpression>
<Operator>Equal</Operator>
<ValueExpression>
<Value Type="String">Error</Value>
</ValueExpression>
</SimpleExpression>
</CriticalExpression>
</Configuration>
</UnitMonitor>