Monitor Type For SPHA Results On SPServer
Microsoft.SharePoint.2016.MonitorType.SPHARule.SPServer (UnitMonitorType)
Three state monitor type for SPHARule monitoring on SPServer.
Element properties: Member Modules:
Overrideable Parameters:
Source Code: <UnitMonitorType ID="Microsoft.SharePoint.2016.MonitorType.SPHARule.SPServer" Accessibility="Internal" RunAs="MOSS!Microsoft.SharePoint.Library.AdminAccount">
<MonitorTypeStates>
<MonitorTypeState ID="Error" NoDetection="false"/>
<MonitorTypeState ID="Warning" NoDetection="false"/>
<MonitorTypeState ID="Success" NoDetection="false"/>
</MonitorTypeStates>
<Configuration>
<xsd:element xmlns:xsd="http://www.w3.org/2001/XMLSchema" name="Category" type="xsd:string"/>
<xsd:element xmlns:xsd="http://www.w3.org/2001/XMLSchema" name="IntervalSeconds" type="xsd:integer"/>
<xsd:element xmlns:xsd="http://www.w3.org/2001/XMLSchema" name="SyncTime" type="xsd:string"/>
<xsd:element xmlns:xsd="http://www.w3.org/2001/XMLSchema" name="TimeoutSeconds" type="xsd:integer"/>
<xsd:element xmlns:xsd="http://www.w3.org/2001/XMLSchema" name="DebugTrace" type="xsd:boolean"/>
<xsd:element xmlns:xsd="http://www.w3.org/2001/XMLSchema" name="FilterValue" type="xsd:string"/>
</Configuration>
<OverrideableParameters>
<OverrideableParameter ID="IntervalSeconds" Selector="$Config/IntervalSeconds$" ParameterType="int"/>
<OverrideableParameter ID="SyncTime" Selector="$Config/SyncTime$" ParameterType="string"/>
<OverrideableParameter ID="TimeoutSeconds" Selector="$Config/TimeoutSeconds$" ParameterType="int"/>
<OverrideableParameter ID="DebugTrace" Selector="$Config/DebugTrace$" ParameterType="bool"/>
</OverrideableParameters>
<MonitorImplementation>
<MemberModules>
<DataSource ID="DataSource" TypeID="Microsoft.SharePoint.2016.TimedScript.FilteredPropertyBagProvider">
<IntervalSeconds>$Config/IntervalSeconds$</IntervalSeconds>
<SyncTime>$Config/SyncTime$</SyncTime>
<ScriptName>MOSSBPAMonitorSPServer.ps1</ScriptName>
<Arguments>$Target/Property[Type="MOSS!Microsoft.SharePoint.Library.SPServer"]/ComputerID$</Arguments>
<ScriptBody><Script> $error.Clear()
$ErrorActionPreference = "SilentlyContinue"
$global:EventObject = New-Object Diagnostics.EventLog
$global:EventObject.Source = "Operations Manager"
function global:Write-Event ([string] $LogContent, $LogType = [Diagnostics.EventLogEntryType]::Information)
{
if ($error)
{
$error.Clear()
$LogType = [Diagnostics.EventLogEntryType]::Error
}
$EventObject.WriteEntry($LogContent, $LogType)
}
function global:LogScriptTime($InvocationObj)
{
$dtEnd = [DateTime]::Now
$msg = @"
[Debug] {0} ended.
Current User: {1}
Current PID: {2}
start time: {3}
stop time: {4}
time taken: {5}
"@ -f $InvocationObj.MyCommand,
[Environment]::UserName,
$pid,
$dtStart,
$dtEnd,
(New-TimeSpan $dtStart $dtEnd).TotalMilliseconds
Write-Event $msg
}
function global:GetDebugSetting($DebugTrace)
{
if ($DebugTrace.ToUpper() -eq "TRUE")
{
$global:Debug = $True;
}
else
{
$global:Debug = $False;
}
}
GetDebugSetting $Args[1]
function global:LogMessage($Message)
{
$Message = "[Debug] {0} `r`n{1}" -f $MyInvocation.ScriptName, $Message
Write-Event $Message
}
if ($global:Debug) {
$msg = "Powershell script {0} execution starting...`r`nArguments:{1} {2}" -f $MyInvocation.MyCommand, $args[0], $args[1]
LogMessage $msg
$dtStart = [DateTime]::Now
}
function Handle-Errors([string] $ErrMsg = [String]::Empty, [bool] $IsExit = $true)
{
if (!$error)
{
return
}
$IsLog = $true
if ("" -eq $ErrMsg)
{
$IsLog = $false
}
else
{
$IsLog = $true
}
if ($IsLog)
{
$ErrorString = ""
if (!$IsExit)
{
$ErrorString = "{0} Monitoring script {1} continues under this error! " -f $MyInvocation.MyCommand, $ErrMsg
}
else
{
$ErrorString = "{0} Monitoring script {1} was terminated! " -f $MyInvocation.MyCommand, $ErrMsg
}
$Exception = $error[$error.Count - 1]
if ($Exception.InvocationInfo)
{
$ErrorString += @"
Current User: {0}
Current PID: {1}
InvocationInfo.MyCommand: {2}
InvocationInfo.ScriptLineNumber: {3}
InvocationInfo.OffsetInLine: {4}
InvocationInfo.ScriptName: {5}
InvocationInfo.Line: {6}
InvocationInfo.PositionMessage: {7}
InvocationInfo.InvocationName: {8}
InvocationInfo.PipelineLength: {9}
InvocationInfo.PipelinePosition: {10}
"@ -f [Environment]::UserName,
$pid,
$Exception.InvocationInfo.MyCommand,
$Exception.InvocationInfo.ScriptLineNumber,
$Exception.InvocationInfo.OffsetInLine,
$Exception.InvocationInfo.ScriptName,
$Exception.InvocationInfo.Line,
$Exception.InvocationInfo.PositionMessage,
$Exception.InvocationInfo.InvocationName,
$Exception.InvocationInfo.PipelineLength,
$Exception.InvocationInfo.PipelinePosition
}
if ($Exception.Exception)
{
$Exception = $Exception.Exception
}
if (!$Exception.InnerException)
{
$ErrType = "Error"
}
else
{
$ErrType = $Exception.InnerException.GetType().FullName
}
$EventObject.WriteEntry(("{0} `n{1}`n{2}" -f $ErrType, $ErrorString, $Exception.Message), [System.Diagnostics.EventLogEntryType]::Error)
}
if ($IsExit)
{
break
}
$error.Clear()
}
$oAPI = New-Object -comObject "MOM.ScriptAPI"
Handle-Errors "Error loading MOM.ScriptAPI COM object "
$MOSSAssembly = [System.Reflection.Assembly]::LoadWithPartialName("Microsoft.SharePoint")
Handle-Errors ""
if (!$MOSSAssembly)
{
break
}
if ($MOSSAssembly.GetName().Version.Major -ne 16)
{
break
}
$RuleLocSeverities = @{}
$RuleLocSeverities["RuleExecutionFailure"] = [Microsoft.SharePoint.Administration.Health.SPHealthAnalyzer]::GetLocalizedSeverity([Microsoft.SharePoint.Administration.Health.SPHealthCheckErrorLevel]::RuleExecutionFailure)
$RuleLocSeverities["Error"] = [Microsoft.SharePoint.Administration.Health.SPHealthAnalyzer]::GetLocalizedSeverity([Microsoft.SharePoint.Administration.Health.SPHealthCheckErrorLevel]::Error)
$RuleLocSeverities["Warning"] = [Microsoft.SharePoint.Administration.Health.SPHealthAnalyzer]::GetLocalizedSeverity([Microsoft.SharePoint.Administration.Health.SPHealthCheckErrorLevel]::Warning)
$RuleLocSeverities["Information"] = [Microsoft.SharePoint.Administration.Health.SPHealthAnalyzer]::GetLocalizedSeverity([Microsoft.SharePoint.Administration.Health.SPHealthCheckErrorLevel]::Information)
$RuleLocSeverities["Success"] = [Microsoft.SharePoint.Administration.Health.SPHealthAnalyzer]::GetLocalizedSeverity([Microsoft.SharePoint.Administration.Health.SPHealthCheckErrorLevel]::Success)
$RuleStatesFromLocSeverities = @{}
$RuleStatesFromLocSeverities[$RuleLocSeverities["RuleExecutionFailure"]] = "WARNING"
$RuleStatesFromLocSeverities[$RuleLocSeverities["Error"]] = "ERROR"
$RuleStatesFromLocSeverities[$RuleLocSeverities["Warning"]] = "WARNING"
$RuleStatesFromLocSeverities[$RuleLocSeverities["Information"]] = "SUCCESS"
$RuleStatesFromLocSeverities[$RuleLocSeverities["Success"]] = "SUCCESS"
function global:GetSPHARuleState($ErrorLevel)
{
$RuleState = $RuleStatesFromLocSeverities[$ErrorLevel]
return $RuleState
}
function global:GetHealthRuleProperty([string] $HealthRuleType, [string] $HealthRulePropertyName)
{
if (!$HealthRuleType -or !$HealthRulePropertyName)
{
Handle-Errors "Must pass 2 parameters to function GetHealthRuleProperty()"
return [String]::Empty
}
$HealtuRulePropertyValue = "{0} Property {1} Not Found" -f $HealthRuleType, $HealthRulePropertyName
foreach ($HealthRule in $HealthRules)
{
if ($HealthRule["HealthRuleType"].ToUpper() -eq $HealthRuleType.ToUpper())
{
$HealthRulePropertyValue = $HealthRule[$HealthRulePropertyName]
break
}
}
Handle-Errors "Error in function GetHealthRuleProperty({0}, {1}) " -f $HealthRuleType, $HealthRulePropetyName
return $HealthRulePropertyValue
}
function global:GetComputerNameWithoutDomain([string] $ComputerName)
{
if (!$ComputerName)
{
Handle-Errors "Must pass 1 parameter to function GetComputerNameWithoutDomain()"
break
}
$ComputerNameOnly = $ComputerName
if ($ComputerName.IndexOf(".") -ge 0)
{
$ComputerNameOnly = $ComputerName.SubString(0, $ComputerName.IndexOf("."))
}
return $ComputerNameOnly
}
$HealthReports = [Microsoft.SharePoint.Administration.SPAdministrationWebApplication]::Local.HealthReports
if (!$HealthReports)
{
$ErrMsg = @"
Error in {0}:
Failed to get SharePoint Health Reports.
Make sure user {1} have enough permission or SharePoint is configured correctly and the database server is running.
Other issues might also cause this failure. Please see Microsoft SharePoint Server 2016 Management Pack Guide.docx for more information.
"@ -f $MyInvocation.MyCommand, [Environment]::UserName
$EventObject.WriteEntry($ErrMsg, [System.Diagnostics.EventLogEntryType]::Warning)
break;
}
$HealthReportQuery = new-object Microsoft.SharePoint.SPQuery
$HealthReportQuery.ViewFields = "<FieldRef Name='HealthReportSeverity'/><FieldRef Name='Title'/><FieldRef Name='HealthReportCategory'/><FieldRef Name='HealthRuleType'/><FieldRef Name='Modified'/><FieldRef Name='HealthReportServers'/>"
$HealthReportQuery.Query = "<OrderBy><FieldRef Name='Title' /><FieldRef Name='Modified' Ascending='FALSE' /></OrderBy>"
$HealthReports = $HealthReports.GetItems($HealthReportQuery)
Handle-Errors "Error loading Microsoft SharePoint 2016 HealthReports "
if (!$HealthReports)
{
break
}
$ComputerName = $args[0]
if (!$ComputerName)
{
if ($global:Debug) { LogMessage "Passed in argument ComputerName is null" }
break
}
$ComputerName = GetComputerNameWithoutDomain($ComputerName)
$HealthRuleQuery = new-object Microsoft.SharePoint.SPQuery
$HealthRuleQuery.ViewFields = "<FieldRef Name='Title'/><FieldRef Name='HealthRuleScope'/><FieldRef Name='HealthRuleCheckEnabled'/><FieldRef Name='HealthReportCategory'/><FieldRef Name='HealthRuleType'/><FieldRef Name='HealthRuleSchedule'/><FieldRef Name='HealthRuleService'/><FieldRef Name='HealthRuleAutoRepairEnabled'/>"
$HealthRules = [Microsoft.SharePoint.Administration.SPAdministrationWebApplication]::Local.HealthRules
if (!$HealthRules)
{
$ErrMsg = @"
Error in {0}:
Failed to get SharePoint Health Rules.
Make sure user {1} have enough permission or SharePoint is configured correctly and the database server is running.
Other issues might also cause this failure. Please see Microsoft SharePoint 2016 Management Pack Guide.docx for more information.
"@ -f $MyInvocation.MyCommand, [Environment]::UserName
$EventObject.WriteEntry($ErrMsg, [System.Diagnostics.EventLogEntryType]::Warning)
break;
}
$HealthRules = $HealthRules.GetItems($HealthRuleQuery)
Handle-Errors "Error loading Microsoft SharePoint 2016 HealthRules."
if (!$HealthRules)
{
if ($global:Debug) { LogMessage "[Microsoft.SharePoint.Administration.SPAdministrationWebApplication]::Local.HealthRules returns null" }
break
}
$SuccessCounts = @(0, 0, 0, 0, 0)
$WarningCounts = @(0, 0, 0, 0, 0)
$ErrorCounts = @(0, 0, 0, 0, 0)
$RuleLocCategories = @{}
$RuleLocCategories["Availability"] = [Microsoft.SharePoint.Administration.Health.SPHealthAnalyzer]::GetLocalizedCategory([Microsoft.SharePoint.Administration.Health.SPHealthCategory]::Availability)
$RuleLocCategories["Configuration"] = [Microsoft.SharePoint.Administration.Health.SPHealthAnalyzer]::GetLocalizedCategory([Microsoft.SharePoint.Administration.Health.SPHealthCategory]::Configuration)
$RuleLocCategories["Performance"] = [Microsoft.SharePoint.Administration.Health.SPHealthAnalyzer]::GetLocalizedCategory([Microsoft.SharePoint.Administration.Health.SPHealthCategory]::Performance)
$RuleLocCategories["Security"] = [Microsoft.SharePoint.Administration.Health.SPHealthAnalyzer]::GetLocalizedCategory([Microsoft.SharePoint.Administration.Health.SPHealthCategory]::Security)
$RuleLocCategories["Custom"] = [Microsoft.SharePoint.Administration.Health.SPHealthAnalyzer]::GetLocalizedCategory([Microsoft.SharePoint.Administration.Health.SPHealthCategory]::Custom)
$RuleStates = @{Availability = "Unknown"; Configuration = "Unknown"; Performance = "Unknown"; Security = "Unknown"; Custom = "Unknown"}
$RuleCategories = @{Availability = 0; Configuration = 1; Performance = 2; Security = 3; Custom = 4}
$SPHARuleLocScopes = @{}
$SPHARuleLocScopes["Any"] = [Microsoft.SharePoint.Administration.Health.SPHealthAnalyzer]::GetLocalizedScope([Microsoft.SharePoint.Administration.Health.SPHealthCheckScope]::Any)
$SPHARuleLocScopes["All"] = [Microsoft.SharePoint.Administration.Health.SPHealthAnalyzer]::GetLocalizedScope([Microsoft.SharePoint.Administration.Health.SPHealthCheckScope]::All)
if ($global:Debug) { $FailingRulesAll = $null }
foreach ($Category in $RuleCategories.Keys)
{
$oBag = $oAPI.CreatePropertyBag()
$oBag.AddValue("FilterValue", $Category)
$FailingRules = $null
$LastReportTitle = $null
foreach ($HealthReport in $HealthReports)
{
if ($LastReportTitle -eq $HealthReport.Title)
{
continue;
}
$RuleCategory = $HealthReport["HealthReportCategory"]
if ($RuleCategory -eq $RuleLocCategories[$Category])
{
$RuleType = $HealthReport["HealthRuleType"]
$RuleScope = GetHealthRuleProperty $RuleType "HealthRuleScope"
$RuleEnabled = GetHealthRuleProperty $RuleType "HealthRuleCheckEnabled"
if ($RuleScope -eq $SPHARuleLocScopes["All"] -and $RuleEnabled)
{
$Found = $false
if ($HealthReport["HealthReportServers"])
{
$FailingServers = $HealthReport["HealthReportServers"].Split("`n")
for ($j = 0; $j -lt $FailingServers.length; $j++)
{
if ($FailingServers[$j].Trim().ToUpper() -eq $ComputerName.ToUpper())
{
$Found = $true
break
}
}
}
if ($Found)
{
$ErrorLevel = $HealthReport["HealthReportSeverity"]
switch ($ErrorLevel)
{
$RuleLocSeverities["RuleExecutionFailure"]
{
$WarningCounts[$RuleCategories[$Category]]++
}
$RuleLocSeverities["Error"]
{
$ErrorCounts[$RuleCategories[$Category]]++
}
$RuleLocSeverities["Warning"]
{
$WarningCounts[$RuleCategories[$Category]]++
}
$RuleLocSeverities["Information"]
{
$SuccessCounts[$RuleCategories[$Category]]++
}
$RuleLocSeverities["Success"]
{
$SuccessCounts[$RuleCategories[$Category]]++
}
}
$RuleState = GetSPHARuleState($ErrorLevel)
if ($RuleState -ne "SUCCESS")
{
$oBag.AddValue($HealthReport.Title, $RuleState)
$FailingRules += $HealthReport.Title + "`n"
}
}
else
{
$SuccessCounts[$RuleCategories[$Category]]++
}
Handle-Errors "Failed to get SPHA Health Report property" $false
}
}
$LastReportTitle = $HealthReport.Title
}
if ($ErrorCounts[$RuleCategories[$Category]] -gt 0)
{
$RuleStates[$Category] = "Error"
}
elseif ($WarningCounts[$RuleCategories[$Category]] -gt 0)
{
$RuleStates[$Category] = "Warning"
}
elseif ($SuccessCounts[$RuleCategories[$Category]] -gt 0)
{
$RuleStates[$Category] = "Success"
}
$oBag.AddValue("Status", $RuleStates[$Category])
if ($FailingRules)
{
$oBag.AddValue("Failing Rules", $FailingRules)
if ($global:Debug) { $FailingRulesAll += $Category + "`n" + $FailingRules }
}
$oAPI.AddItem($oBag)
Handle-Errors "Failed to get Health Report property" $false
}
$oAPI.ReturnItems()
Handle-Errors "Failed to submit PropertyBag data to SCOM Agent" $false
if ($global:Debug) {
$msg = @"
Current User: {0}
Current PID: {1}
SPServer SPHA Availability Status: {2}
SPServer SPHA Configuration Status: {3}
SPServer SPHA Performance Status: {4}
SPServer SPHA Security Status: {5}
SPServer SPHA Custom Status: {6}
"@ -f [Environment]::UserName,
$pid,
$RuleStates["Availability"],
$RuleStates["Configuration"],
$RuleStates["Performance"],
$RuleStates["Security"],
$RuleStates["Custom"]
$dtEnd = [DateTime]::Now
$msg += @"
SPServer SPHA Failing Rules: {0}
start time: {1}
stop time: {2}
time taken: {3}
Powershell script {4} execution ended.
"@ -f $FailingRulesAll,
$dtStart,
$dtEnd,
(New-TimeSpan $dtStart $dtEnd).TotalMilliseconds,
$MyInvocation.MyCommand
LogMessage $msg
}</Script> </ScriptBody>
<TimeoutSeconds>$Config/TimeoutSeconds$</TimeoutSeconds>
<DebugTrace>$Config/DebugTrace$</DebugTrace>
<FilterValue>$Config/FilterValue$</FilterValue>
</DataSource>
<ConditionDetection ID="ErrorFilter" TypeID="System!System.ExpressionFilter">
<Expression>
<SimpleExpression>
<ValueExpression>
<XPathQuery Type="String">Property[@Name='Status']</XPathQuery>
</ValueExpression>
<Operator>Equal</Operator>
<ValueExpression>
<Value Type="String">ERROR</Value>
</ValueExpression>
</SimpleExpression>
</Expression>
</ConditionDetection>
<ConditionDetection ID="WarningFilter" TypeID="System!System.ExpressionFilter">
<Expression>
<SimpleExpression>
<ValueExpression>
<XPathQuery Type="String">Property[@Name='Status']</XPathQuery>
</ValueExpression>
<Operator>Equal</Operator>
<ValueExpression>
<Value Type="String">WARNING</Value>
</ValueExpression>
</SimpleExpression>
</Expression>
</ConditionDetection>
<ConditionDetection ID="SuccessFilter" TypeID="System!System.ExpressionFilter">
<Expression>
<SimpleExpression>
<ValueExpression>
<XPathQuery Type="String">Property[@Name='Status']</XPathQuery>
</ValueExpression>
<Operator>Equal</Operator>
<ValueExpression>
<Value Type="String">SUCCESS</Value>
</ValueExpression>
</SimpleExpression>
</Expression>
</ConditionDetection>
</MemberModules>
<RegularDetections>
<RegularDetection MonitorTypeStateID="Error">
<Node ID="ErrorFilter">
<Node ID="DataSource"/>
</Node>
</RegularDetection>
<RegularDetection MonitorTypeStateID="Warning">
<Node ID="WarningFilter">
<Node ID="DataSource"/>
</Node>
</RegularDetection>
<RegularDetection MonitorTypeStateID="Success">
<Node ID="SuccessFilter">
<Node ID="DataSource"/>
</Node>
</RegularDetection>
</RegularDetections>
<OnDemandDetections>
<OnDemandDetection MonitorTypeStateID="Error">
<Node ID="ErrorFilter">
<Node ID="DataSource"/>
</Node>
</OnDemandDetection>
<OnDemandDetection MonitorTypeStateID="Warning">
<Node ID="WarningFilter">
<Node ID="DataSource"/>
</Node>
</OnDemandDetection>
<OnDemandDetection MonitorTypeStateID="Success">
<Node ID="SuccessFilter">
<Node ID="DataSource"/>
</Node>
</OnDemandDetection>
</OnDemandDetections>
</MonitorImplementation>
</UnitMonitorType>