SCOM Effective Monitoring Configuration – Decoded

Since the advent of SCOM, one question that lingers among the admins and the end consumers is What is the effective monitoring configuration for a server or an object or an alert? Microsoft answered with Export-SCOMEffectiveMonitoringConfiguration PS Cmdlet which you can use to get effective config for an Instance (Object). This will export the data as CSV file.

Stefan Roth has used this and done it in his (PowerShell) way here. This has advantage of retrieving Effective Config for all objects contained in a Computer and it displays the data in GUI while dumping the data in CSV format as well.

But I thought, I would write up this post to expose the logic behind Export-SCOMEffectiveMonitoringConfiguration which you can use it and build your own logic around it.

Effective Monitoring Configuration is evaluated between Object, Monitor/Rule and Effective Overrides for the Object (If any). In this blog post, I will decode the logic with an example of the most common requirement among end consumers – to get effective monitoring configuration for each SCOM Alert.

First step is to get Monitored Object and there are multiple ways to get using Get-SCOMClassInstance PS Cmdlet. For our scenario, we will get Monitored Object from a SCOM Alert.

From SCOM Alert:

$SCOMAlerts = Get-SCOMAlert -Name $AlertName -ResolutionState $ResolutionStateNumber
Foreach ($SCOMAlert in $SCOMAlerts) {
		$MonitoredObject = Get-SCOMClassInstance -Id $SCOMAlert.MonitoringObjectId
}

Second Step is to get the associated monitor/rule for which you need to get Effective Configuration. Get-SCOMMonitor/Get-SCOMRule lists several methods to get desired monitor/rule and for our scenario, we will get the monitor/rule for each SCOM Alert we are interested to get Effective Config.

If ($SCOMAlert.IsMonitorAlert -eq $true) {
	$Workflow = Get-SCOMMonitor -Id $SCOMAlert.MonitoringRuleId   #For Monitor Based Alert
}
Else {
	$Workflow = Get-SCOMRule -Id $SCOMAlert.MonitoringRuleId  #For Rule Based Alert
}

Third Step is to get Configuration for Monitor or Rule obtained above.

If ($Workflow.Configuration){
	#Get Workflow Default Config for Monitor Based Alert
	$Config = "<configuration>" + $Workflow.Configuration + "</configuration>"
	$WorkflowConfig = @{}
	$Config.Configuration.ChildNodes | Foreach {$WorkflowConfig[$_.Name] = $_.'#Text'}
}
Elseif ($Workflow.DataSourceCollection.Configuration){
	#Get Workflow Default Config for Rule
    $Config = "<configuration>" + $Workflow.DataSourceCollection.Configuration + "</configuration>"
    $WorkflowConfig = @{}
    $Config.Configuration.ChildNodes | Foreach {$WorkflowConfig[$_.Name] = $_.'#Text'}
	If ($WorkflowConfig.ContainsKey("Expression")) {
		If ($WorkflowConfig['Expression'] -eq $null) {$WorkflowConfig['Expression'] = $Config.Configuration.Expression.InnerText}
	}
}

Fourth Step is to get Resultant Override for Monitored Object – Monitor/Rule Pair

#Get Resultant Overrides for the Object-Monitor Pair
$Overrides = ($Object.GetResultantOverrides($Workflow)).ResultantConfigurationOverrides
$n = $Overrides.Count

Final Step is to iterate each Override and get Property and its Value from the Override. Once the Overridden Property and its Value is obtained, we must replace the Original Configuration Value for the Property with the Overridden Value.

If there are no overrides returned, the effective configuration is same as the monitor/rule configuration.

If ($n -eq 0) {
	$EffectiveConfig = $WorkflowConfig	
}

If there are Overrides,

If ($n -eq 1) {
	$Key = $Object.GetResultantOverrides($Workflow).resultantconfigurationoverrides.keys.name
	$Value = $Object.GetResultantOverrides($Workflow).resultantconfigurationoverrides.values.effectivevalue
	$change = $EffectiveConfig.GetEnumerator() | ? {$_.key -eq $Key}
	$change | % { $EffectiveConfig[$_.Key]=$Value}
}
If ($n -gt 1) {
	for ($i=0; $i -lt $n; $i++) {
		$Key = $Object.GetResultantOverrides($Workflow).resultantconfigurationoverrides.keys.name[$i]
		$Value = $Object.GetResultantOverrides($Workflow).resultantconfigurationoverrides.values.effectivevalue[$i]
		$change = $EffectiveConfig.GetEnumerator() | ? {$_.key -eq $Key}
		$change | % { $EffectiveConfig[$_.Key]=$Value }
    }
}

The Effective Configuration is thus stored in variable $EffectiveConfig. You can display it or use it further in the logic you are building.

$EffectiveConfig

One of the most effective way of using this is in the Connector Framework, if you are integrating SCOM with any ticketing tool through Orchestrator. You can use this to fetch the effective config for each alert and update the Alert Description so that it enlightens end consumers of the alert either it be Operations Team or Engineering Team and helps them in addressing the issue effectively.

Powershell Script can be download here

Happy Scripting!

You may also like...

Leave a Reply

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

%d bloggers like this: