Skip to main content

SCOM 2007 R2: Daily Health Check Script v2

 Author
Author
Sam McGeown
Steely-eyed missile man
Warning: This article is now 14 years old! It is highly likely that this information is out of date and the author will have completely forgotten about it. Please take care when following any guidance to ensure you have up-to-date recommendations.

MSFT-System-Center-logoA couple of months ago I posted the first version of my SCOM 2007 R2 Daily Health Check Script - here is version 2. It’s more than a little motivated by some friendly competition with a Microsoft PFE for SCOM, hopefully you’ll agree it’s a big improvement on the last version.

Updated for this version

  • Formatting changed to make it more readable and more compatible
  • Added “Report generated on ” to the top of the report
  • Management Server states reported as one section
  • Default MP check moved to beneath the Management servers
  • Agents in pending states moved to be with the Agent health states
  • Clarified “Unresponsive Agents” and “Agents reporting errors”
  • Management server alerts streamlined
  • Added top 10 alerts for the last 7 days, and added top alerters for each

I’m planning to wrap in some SQL database size checks and some of the other recommendations later - I’ll post again here when that’s ready 🙂

$Head = "<style>"
$Head +="BODY{background-color:#FFF;font-family:Verdana,sans-serif; font-size: 11px;}"
$Head +="TABLE{border-width: 0px;border-collapse: collapse; width: 100%;}"
$Head +="TH{border-width: 0px;background-color:#F5F5F5;color:Navy;padding: 5px; font-weight: bold;text-align:left;}"
$Head +="TD.Gray{ border-width: 0px; background-color: #D3D3D3; color:Navy; padding: 5px; font-weight: bold; text-align:left;}"
$Head +="TD.Blank{ border-width: 0px;}"
$Head +="TD{ border-width: 0px; color:Red;}"
$Head +="H1{color:Navy; font-size: 12px; padding: 5px;}"
$Head +="H3{color:Navy; font-size: 11px;}"
$Head +="P{font-size: 11px;}"
$Head +="P.OK{color:Green; font-size: 11px;}"
$Head +="P.Error{color:Red; font-size: 11px; font-weight: Bold;}"
$Head +="</style>"
$ReportOutput += "<H1>SCOM Daily Healthcheck Report</H1>"
$ReportOutput += "<p>Report generated on "+(gwmi WIN32_ComputerSystem).Name+"</p>"

write-host "Getting Management Health Server States" -ForegroundColor Yellow
$ReportOutput += "<TABLE><TR><TD class=Gray><H1>Management Servers</H1></TD></TR><TR><TD class=Blank>"
$Count = Get-ManagementServer | where {$_.HealthState -ne "Success"} | Measure-Object
if($Count.Count -gt 0) {
	$ReportOutput += Get-ManagementServer | where {$_.HealthState -ne "Success"} | select Name,HealthState,IsRootManagementServer,IsGateway | ConvertTo-HTML -fragment
} else {
	$ReportOutput += "<p class=OK>All management servers are in healthy state.</p>"
}
write-host "Getting RMS Maintenance Mode" -ForegroundColor Yellow
$RMS = Get-ManagementServer | where {$_.IsRootManagementServer -eq $True}
$criteria = new-object Microsoft.EnterpriseManagement.Monitoring.MonitoringObjectGenericCriteria("InMaintenanceMode=1")
$objectsInMM = (Get-ManagementGroupConnection).ManagementGroup.GetPartialMonitoringObjects($criteria)
$is = "<p class=OK>"+ $RMS.Name +" is not in maintenance mode</p>"
foreach ($MM in $objectsInMM){
	if($MM.Displayname -eq $RMS.Name){
		$is = "<p class=Error>"+ $RMS.Name +" is in maintenance mode</p>"
	}
}
$ReportOutput += "</TD></TR><TR><TD class=Blank>"+$is+"</TD></TR><TR><TD class=Blank>"

$ReportOutput += "</TD></TR><TR><TD class=Blank><p> </p></TD></TR><TR><TD class=Blank>"

write-host "Getting Overrides in Default Management Pack" -ForegroundColor Yellow
$ReportOutput += "</TD></TR><TR><TD class=Gray><H1>Overrides in Default Management Pack</H1></TD></TR><TR><TD class=Blank>"
$OverrideCount = Get-ManagementPack | where {$_.DisplayName -match "Default Management Pack"} | get-override | measure-object
if($OverrideCount.Count -gt 2){
	$ReportOutput += "<p class=Error>There are unexpected overrides in the Default Management Pack</p>"
	foreach ($monitor in Get-ManagementPack | where {$_.DisplayName -match "Default Management Pack"} | get-override | where {$_.monitor}) {
		$ReportOutput += get-monitor | where {$_.Id -eq $monitor.monitor.id} | select-object DisplayName,Description | ConvertTo-HTML -fragment
		$ReportOutput += "<br />"
	}
	foreach ($rule in Get-ManagementPack | where {$_.DisplayName -match "Default Management Pack"} | get-override | where {$_.rule}) {
		$ReportOutput += get-rule | where {$_.Id -eq $rule.rule.id} | select-object DisplayName,Description | ConvertTo-HTML -fragment
		$ReportOutput += "<br />"
	}
} else {
	$ReportOutput += "<p class=OK>There are no unexpected overrides in the Default Management Pack</p>"
}

$ReportOutput += "</TD></TR><TR><TD class=Blank><p> </p></TD></TR><TR><TD class=Blank>"

write-host "Getting Agents in Pending State" -ForegroundColor Yellow
$ReportOutput += "</TD></TR><TR><TD class=Gray><H1>Agents in Pending State</H1></TD></TR><TR><TD class=Blank>"
#$ReportOutput += Get-AgentPendingAction | sort AgentPendingActionType | select AgentName,ManagementServerName,AgentPendingActionType | ConvertTo-HTML -fragment
$Pending = Get-AgentPendingAction
if($Pending.Count -gt 0) {
	$ReportOutput += $Pending | sort AgentPendingActionType | select AgentName,ManagementServerName,AgentPendingActionType | ConvertTo-HTML -fragment
} else {
	$ReportOutput += "<p class=OK>No pending agents</p>"
}

$ReportOutput += "</TD></TR><TR><TD class=Blank><p> </p></TD></TR><TR><TD class=Blank>"

$ReportOutput += "</TD></TR><TR><TD class=Gray><H1>Unresponsive Agents</H1></TD></TR><TR><TD class=Blank>"
$AgentMonitoringClass = get-monitoringclass -name "Microsoft.SystemCenter.Agent"
$ReportOutput += Get-MonitoringObject -monitoringclass:$AgentMonitoringClass | where {$_.IsAvailable -eq $false} | select DisplayName | ConvertTo-HTML -fragment

$ReportOutput += "</TD></TR><TR><TD class=Blank><p> </p></TD></TR><TR><TD class=Blank>"

write-host "Getting Agent Health Status" -ForegroundColor Yellow
$ReportOutput += "</TD></TR><TR><TD class=Gray><H1>Agents reporting errors</H1></TD></TR><TR><TD class=Blank>"
$ReportOutput += Get-Agent | where {$_.HealthState -ne "Success"} | select Name,HealthState | ConvertTo-HTML -fragment

$ReportOutput += "</TD></TR><TR><TD class=Blank><p> </p></TD></TR><TR><TD class=Blank>"

write-host "Getting Management Server Alerts" -ForegroundColor Yellow
$ReportOutput += "</TD></TR><TR><TD class=Gray><H1>Management Server Alerts</H1></TD></TR><TR><TD class=Blank>"
$ManagementServers = Get-ManagementServer
$ReportOutput += "<TABLE>"
foreach ($ManagementServer in $ManagementServers){
	$ReportOutput += "<TR><TD class=Blank><H3>" + $ManagementServer.ComputerName + "</H3></TD><TD>"
	$MSAlerts = get-alert -Criteria ("NetbiosComputerName = '" + $ManagementServer.ComputerName + "'") | where {$_.ResolutionState -ne '255' -and $_.MonitoringObjectFullName -Match 'Microsoft.SystemCenter'}
	if(($MSAlerts).Count -gt 0) {
		$ReportOutput += $MSAlerts  | select TimeRaised,Name,Description,Severity | ConvertTo-HTML -fragment
	} else {
		$ReportOutput += "<p class=OK>No Alerts</p>"
	}
	$ReportOutput += "</TD></TR>"
}
$ReportOutput += "</TABLE>"

$ReportOutput += "</TD></TR><TR><TD class=Blank><p> </p></TD></TR><TR><TD class=Blank>"

write-host "Getting Top 10 Alerts in the last 7 days" -ForegroundColor Yellow
$ReportOutput += "</TD></TR><TR><TD class=Gray><H1>Top 10 Alerts (last 7 days)</H1></TD></TR><TR><TD>"
$ReportOutput += "<TABLE>"
$topten = get-alert | where {$_.TimeRaised -gt ((get-date).adddays(-7))} | group-Object Name | sort-object Count -desc | select -first 10 Name, Count
foreach ($toptenalert in $topten) {
	$ReportOutput += "<TD class=Gray>"+$toptenalert.Name+" (Total: "+$toptenalert.Count+")</TD><TR><TD>"
	$ReportOutput += get-alert | where {$_.Name -eq $toptenalert.Name -and $_.TimeRaised -gt ((get-date).adddays(-7))} | group-Object PrincipalName | sort-object Count -desc | select -first 10 Name, Count | ConvertTo-HTML -fragment
	$ReportOutput += "</TD></TR>"
}
$ReportOutput += "</TABLE>"
$ReportOutput += "</TD></TR></TABLE>"

$Body = ConvertTo-HTML -head $Head -body "$ReportOutput"

$SmtpClient = New-Object system.net.mail.smtpClient
$MailMessage = New-Object system.net.mail.mailmessage
$SmtpClient.Host = "smtp.definit.co.uk"
$mailmessage.from = "[email protected]"
$mailmessage.To.add("<a href="mailto:[email protected]">[email protected]</a>")
#$mailmessage.To.add("<a href="mailto:[email protected]">[email protected]</a>")
$mailmessage.Subject = "SCOM Daily Healthcheck Report"
$MailMessage.IsBodyHtml = 1
$mailmessage.Body = $Body
$smtpclient.Send($mailmessage)
}

Download the full PowerShell file here:Get-HealthCheck.v2.ps1