Close rule-generated alerts in SCOM

Rule-generated alerts in SCOM do not automatically close when the problem that triggered the alert has been resolved; they will remain open until they are closed by SCOM when they reach the automatic resolution threshold, the default for which is 30 days, or until they are closed by a user.

If you have a requirement for rule-generated alerts to be automatically closed after a defined period, try this PowerShell script. For best effect, the script should be scheduled to be executed every few hours. NB: this script has been tested with SCOM 2007 R2; it may have to be modified to function with 2012.

<#
	Closes rule-generated alerts after a defined period.
	Logging is to .\$LogFile and to a custom field in the alert.
	$MaximumAlertAge defines how old alerts can become before being closed.
#>

$Rms = "Localhost"
$LogFile = $Pwd.ToString() + "\Close rule-generated alerts.log"
$MaximumAlertAge = ((Get-Date).AddHours(-4.0).ToUniversalTime())
$StateClosed = "255"
$ServerFqdn = (Get-WmiObject Win32_ComputerSystem | Select-Object -expand Name) + "." + (Get-WmiObject Win32_ComputerSystem | Select-Object -expand Domain)
$ClosureComment = "Rule-generated alert closed by '$($MyInvocation.MyCommand.Name)' on $($ServerFqdn)."

# Initiate the SCOM snap-in.
If ((Get-PsSnapin | Where-Object {$_.Name -eq 'Microsoft.EnterpriseManagement.OperationsManager.Client'}) -eq $null)
{
	Add-PsSnapin "Microsoft.EnterpriseManagement.OperationsManager.Client" -ErrorAction "SilentlyContinue" -ErrorVariable "Err"
}
If ((Get-PsDrive | Where-Object {$_.Name -eq 'Monitoring'}) -eq $null)
{
	New-PsDrive -Name "Monitoring" -PSProvider "OperationsManagerMonitoring" -Root "\" -ErrorAction "SilentlyContinue" -ErrorVariable "Err" | Out-Null
}

# Connect to the RMS.
Set-Location "OperationsManagerMonitoring::"
New-ManagementGroupConnection -ConnectionString $Rms | Out-Null
Set-Location "Monitoring:\$Rms"

# Write to the log.
Add-Content $LogFile "---Begin execution: $(Get-Date -format "dd/MM/yyyy HH:mm:ss").------------------------------------------------"

# Obtain details of rule-generted alerts (i.e. IsMonitorAlert = 0) due to be closed.
$AlertsToBeClosed = Get-Alert -criteria "ResolutionState != $StateClosed AND IsMonitorAlert = 0 AND TimeRaised < '$MaximumAlertAge'"

# Close the alerts.
If ($AlertsToBeClosed)
{
	$NumberOfAlertsToClose = $AlertsToBeClosed | Measure-Object | Select-Object -expand Count
	If ($NumberOfAlertsToClose -eq 1)
	{
		Add-Content $LogFile "1 alert to close.`r`n"
	}
	Else
	{
		Add-Content $LogFile "$($NumberOfAlertsToClose) alerts to close.`r`n"
	}

	# Close the alerts.
	ForEach ($Alert in $AlertsToBeClosed)
	{
		Resolve-Alert -Alert $Alert -Comment $ClosureComment
		Add-Content $LogFile "ID:`t$($Alert.Id)`r`nHost:`t$($Alert.PrincipalName)`r`nName:`t$($Alert.Name)`r`nRaised:`t$(($Alert.TimeRaised).ToShortDateString() + " " + ($Alert.TimeRaised).ToLongTimeString())`r`nClosed:`t$(Get-Date -format "dd/MM/yyyy HH:mm:ss")`r`n"
	}
}
Else
{
	Add-Content $LogFile "No alerts to close."
}

# Write to the log.
Add-Content $LogFile "---End execution:   $(Get-Date -format "dd/MM/yyyy HH:mm:ss").------------------------------------------------`r`n"

Leave a Reply

Your email address will not be published. Required fields are marked *