DefinIT

SCOM 2007 R2: Daily Health Check Script v2

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 <server>” 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 = "scom.report@definit.co.uk"
$mailmessage.To.add("<a href="mailto:sam@definit.co.uk">sam@definit.co.uk</a>")
#$mailmessage.To.add("<a href="mailto:another@definit.co.uk">another@definit.co.uk</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