Making the World Greener One Monitor at a Time - Reset SCOM Monitors Enmasse

Updated 10/19/2014 – Put the script on TechNet Gallery.  Link:  ResetAllMonitorsOfASpecificType.ps1

Recently, I’ve had the pleasure of tuning a new SCOM implementation.  Like all new implementations of monitoring software there were a lot of alerts coming from the systems in the environment.  As I went through and tuned the installed Management Packs, I realized that resetting the individual monitors, for those that don’t recalculate automatically, once the override is implemented is really, really, really tedious.  Especially when the systems number in the hundreds or thousands.

I looked at “GreenMachine”, but realized that it was to much of a brute force approach and I didn’t want to reset the monitors that we had not yet troubleshot, so I developed the below PowerShell script to automatically iterate through all systems experiencing the issue and reset the monitor.

The PowerShell script to do so is attached to this post, just download and rename it to ResetAllMonitorsOfASpecificType.ps1.  Note:  You will need PowerShell and the Operations Console and Shell installed on the machine you run this from.

Note:  I updated this heavily the day after I released it.  The old approach would only work if there were alerts that existed for the monitors.  So if someone closed the alerts, no reset of the monitor.  Additionally, I ran into an odd quirk where when run from the Operations Manager Shell where the queries to SCOM returned 2 items where there should only have been one (I had only tested under the regular PowerShell console and in the ISE).  This is fixed, though when run in the Operations Manager Shell it will "close" the alert multiple times.  Without spending a whole bunch of time to deal with this quirky behavior, there is nothing else that can be done instead of just letting it reset the monitor multiple times.  However, this is PowerShell, so if anyone wants to take on that before I get around to messing with it, I'll be glad to update this script with the info.

Updated content as of 4/5/2011 following this.  I've also updated the text file in hopes that it works this time.
Script Syntax (just copy and paste to a file with a .PS1 extension, I hope it doesn't mess up the formatting):

param (
    [Parameter(Mandatory = $true)]
    [string]$rootMS,
   
    [Parameter(Mandatory = $true)]
    [string]$MonitorDisplayName
)

#adding SCOM PSSnapin 
if ((Get-PSSnapin | where-Object { $_.Name -eq 'Microsoft.EnterpriseManagement.OperationsManager.Client' }) -eq $null) 
{
    "Adding Operations Manager Snapin to session"  
    Add-PSSnapin Microsoft.EnterpriseManagement.OperationsManager.Client -ErrorAction SilentlyContinue -ErrorVariable Err 

if ((Get-PSDrive | where-Object { $_.Name -eq 'Monitoring' }) -eq $null) 
{
    "Mapping PSDrive for OpsManager" 
    New-PSDrive -Name:Monitoring -PSProvider:OperationsManagerMonitoring -Root:\ -ErrorAction SilentlyContinue -ErrorVariable Err | Out-Null 
}

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

#Based on the display name in object health explorer, get the monitor identity
$FindMonitorFilter = 'DisplayName LIKE ''' + $MonitorDisplayName + ''''
$Monitors = @(Get-Monitor -Criteria $FindMonitorFilter)
If ($Monitors -eq $null)
{
    "Couldn't find the Monitor definition.  Exiting"
    Exit
}

ForEach ($Monitor in $Monitors)
{
    #Get the class the monitor applies to
    $MonitorClass = @(Get-MonitoringClass -Id $Monitor.Target.Id)

    #Get the list of monitors with the display name that are in Error and Warning state
    $MonitoringObjectFilter = "(HealthState = 2 OR HealthState = 3) AND IsAvailable = 'True'"
    $ActiveMonitors = @(Get-MonitoringObject -MonitoringClass $MonitorClass[0] -Criteria $MonitoringObjectFilter)
    "Found '" + $ActiveMonitors.Count + "' active monitors."

    If ($ActiveMonitors -ne $null)
    {
        #loop through the list of degraded agents and perform actions described within the loop
        Foreach ($ActiveMonitor in $ActiveMonitors)
        {
            #Output current entity working on and monitor being worked on.
            "Resetting Health State on '" + $ActiveMonitor.FullName + "'"

            #Reset the monitor (assume that the monitor can't be recalculated since that is easier to code)
#            $ActiveMonitor.ResetMonitoringState($Monitor.Id)|Out-Null
        }
    }
}

ResetAllMonitorsOfASpecificType.ps1.txt