Agent-Integritätsstatus erfassen

ManagementGroupCollectionAgentHealthStatesRule (Rule)

Agent-Integritätszustände für das Übersichtsdashboard von Operations Manager zusammenfassen

Element properties:

TargetMicrosoft.SystemCenter.AllManagementServersPool
CategoryPerformanceCollection
EnabledTrue
Alert GenerateFalse
RemotableTrue

Member Modules:

ID Module Type TypeId RunAs 
DS DataSource Microsoft.Windows.TimedPowerShell.PerformanceProvider System.PrivilegedMonitoringAccount
WriteToDB WriteAction Microsoft.SystemCenter.CollectPerformanceData Default
WriteToDW WriteAction Microsoft.SystemCenter.DataWarehouse.PublishPerformanceData Default

Source Code:

<Rule ID="ManagementGroupCollectionAgentHealthStatesRule" Enabled="true" Target="SC!Microsoft.SystemCenter.AllManagementServersPool" ConfirmDelivery="false" Remotable="true" Priority="Normal" DiscardLevel="100">
<Category>PerformanceCollection</Category>
<DataSources>
<DataSource ID="DS" TypeID="Microsoft.Windows.TimedPowerShell.PerformanceProvider" RunAs="System!System.PrivilegedMonitoringAccount">
<IntervalSeconds>900</IntervalSeconds>
<SyncTime/>
<ScriptName>AgentStateRollup.ps1</ScriptName>
<ScriptBody><Script>$errorActionPreference = 'Stop'
Set-StrictMode -Version 2

$SCOMPowerShellKey = "HKLM:\SOFTWARE\Microsoft\System Center Operations Manager\12\Setup\Powershell\V2"
$SCOMModulePath = Join-Path (Get-ItemProperty $SCOMPowerShellKey).InstallDirectory &#x201C;OperationsManager&#x201D;
Import-module $SCOMModulePath

# set default counts as zero
$totalAgentCount = 0
$UnavailableAgentsCount = 0
$UnmonitoredAgentsCount = 0
$HealthyAgentsCount = 0
$CriticalAgentsCount = 0
$WarningAgentsCount = 0

# get the agent data and put it in a hash
$agents = Get-SCOMAgent
# if there's no agents, just simply set all counts to zero
if (!$agents)
{
# do nothing, the counts will be zero as default
}
else
{
$totalAgentCount = @($agents).Count

#map to all agents table
$allAgentsTable = @{}
$agents | % {$allAgentsTable.Add($_.DisplayName, $_.HealthState)}

#get the agent watcher class and heartbeat monitor
$monitor = Get-SCOMMonitor -Name Microsoft.SystemCenter.HealthService.Heartbeat
$monitorCollection = @($monitor)
$monitorCollection = $monitorCollection -as [Microsoft.EnterpriseManagement.Configuration.ManagementPackMonitor[]]
$watcherClass = Get-SCOMClass -Name Microsoft.SystemCenter.AgentWatcher
$watcherInstances = @(Get-SCOMClassInstance -Class $watcherClass)

#map to all heartbeat monitors table
$allHeartbeatMonitorsTable = @{}
$watcherInstances | % {$allHeartbeatMonitorsTable.Add($_.DisplayName, $_.GetMonitoringStates($monitorCollection)[0].HealthState.ToString())}

#get agents count in different states
foreach ($agent in $allAgentsTable.GetEnumerator())
{
# get count of healthy agents
if ($agent.Value -eq 'Success' -and $allHeartbeatMonitorsTable[$agent.Name] -eq 'Success')
{
$HealthyAgentsCount++
}
# get count of warning agents
elseif ($agent.Value -eq 'Warning' -and $allHeartbeatMonitorsTable[$agent.Name] -eq 'Success')
{
$WarningAgentsCount++
}
# get count of critical agents
elseif ($agent.Value -eq 'Error' -and $allHeartbeatMonitorsTable[$agent.Name] -eq 'Success')
{
$CriticalAgentsCount++
}
}
# get count of unmonitored agents
$UnmonitoredAgentsCount = @($allAgentsTable.GetEnumerator() | ? {$_.Value -eq 'Uninitialized'}).Count
# get count of unavailable agents
$UnavailableAgentsCount = $totalAgentCount - $HealthyAgentsCount - $WarningAgentsCount - $CriticalAgentsCount - $UnmonitoredAgentsCount

#check if the Unavailable agents count is negative
if ($UnavailableAgentsCount -lt 0)
{
Write-EventLog -LogName "Operations Manager" -Source "Health Service Script" -EventId 21000 -EntryType Warning -Message "AgentStateRollup script detected the Uavailable agents count is negative, script interrupted, will wait for next execution"
exit
}
}

#add a helper class to get the localized display strings
$langClass = New-Module {

$lang = (Get-Culture).ThreeLetterWindowsLanguageName
$mp = Get-SCOMManagementPack -Name Microsoft.SystemCenter.OperationsManager.SummaryDashboard
# Set localized language to ENU if the expected language is not found in MP
try
{
$temp = $mp.GetDisplayString($lang)
}
catch [Microsoft.EnterpriseManagement.Common.ObjectNotFoundException]
{
$lang = "ENU"
}

function GetLocalizedDisplayString($elementId)
{
$mp.FindManagementPackElementByName($elementId).GetDisplayString($lang).Name
}
Export-ModuleMember -Variable * -Function *
} -asCustomObject

$api = New-Object -comObject 'MOM.ScriptAPI'
function AddPropertyBag ($Name, [System.Int32]$Value)
{
if (!$Value) {$Value = 0}

$bag = $api.CreateTypedPropertyBag(2)
$bag.AddValue('AgentStates', $Name)
$bag.AddValue('Value', $Value)
$api.AddItem($bag)
$bag
}

#create propertybags for output
AddPropertyBag $langClass.GetLocalizedDisplayString('HeathStateTotal') $totalAgentCount
AddPropertyBag $langClass.GetLocalizedDisplayString('HeathStateUninitialized') $UnavailableAgentsCount
AddPropertyBag $langClass.GetLocalizedDisplayString('HeathStateUnmonitored') $UnmonitoredAgentsCount
AddPropertyBag $langClass.GetLocalizedDisplayString('HeathStateSuccess') $HealthyAgentsCount
AddPropertyBag $langClass.GetLocalizedDisplayString('HeathStateError') $CriticalAgentsCount
AddPropertyBag $langClass.GetLocalizedDisplayString('HeathStateWarning') $WarningAgentsCount</Script></ScriptBody>
<Parameters/>
<TimeoutSeconds>300</TimeoutSeconds>
<StrictErrorHandling>false</StrictErrorHandling>
<ObjectName>AgentStateRollup</ObjectName>
<CounterName>NumberAgents</CounterName>
<InstanceName>$Data/Property[@Name='AgentStates']$</InstanceName>
<Value>$Data/Property[@Name='Value']$</Value>
</DataSource>
</DataSources>
<WriteActions>
<WriteAction ID="WriteToDB" TypeID="SC!Microsoft.SystemCenter.CollectPerformanceData"/>
<WriteAction ID="WriteToDW" TypeID="SCDW!Microsoft.SystemCenter.DataWarehouse.PublishPerformanceData"/>
</WriteActions>
</Rule>