Methode GetFailoverManagementServers() is very slow? Here’s a faster methode to collect failover configuration from scom agents


In some cases, it is necessary to review the Primary and Failover Management Server configuration of your window SCOM agents.

Most customer are using PowerShell to receive those information

for Example:

$agent = get-scomagent -Name "name.of.my.agent"
$agent.PrimaryManagmentServer
$agent.GetFailoverManagementServers()

Depends on the size of your environment calling the method GetFailoverManagementServers() might take several seconds per agent.

Measure-command {$agent.GetFailoverManagementServers()}

Days              : 0
Hours             : 0
Minutes           : 0
Seconds           : 26
Milliseconds      : 44
Ticks             : 260445702
TotalDays         : 0,000301441784722222
TotalHours        : 0,00723460283333333
TotalMinutes      : 0,43407617
TotalSeconds      : 26,0445702
TotalMilliseconds : 26044,5702

If you need to review the failover configuration of all your Windows SCOM agents, this might take several hours to run completely against all your agents.

Hmm.... "OK, what can I do to avoid such a long runtime?"

Theoretically you could call this information directly via SQL DB query, But I wouldn't recommend doing this, because you can't rely in long-term on the database query in case that the SCOM product group decides to change or optimize anything in the DB table structure in any future update rollup. Therefore, I'd like to show you another way with PowerShell.

There is another method to call the failover information from SCOM in a much faster way.

Background information:

There are two relationships that reflects the relations between SCOM Agent and its communication partners (Primary and Failover Management Servers)

Primary Management Server

ID                           : 37848e16-37a2-b81b-daaf-60a5a626be93
DisplayName    : Health Service Communication
Source                 : Microsoft.SystemCenter.HealthService
Target                  : Microsoft.SystemCenter.HealthService

Failover Managment Server(s)
ID                           : ca26f3f0-b8ce-c193-d6df-632d53dee714
DisplayName    : Health Service Failover Communication
Source                 : Microsoft.SystemCenter.HealthService
Target                  : Microsoft.SystemCenter.HealthService

Using this relationship is much faster than calling the agent method GetFailoverManagementServers()

Solution:

Important! Instead of Get-ScomAgent (this returns an instance of AgentManagedComputer), you need to use HealthService class instance in this case.

$Class   = Get-SCOMClass -Name Microsoft.SystemCenter.HealthService
$Agent = Get-SCOMClassInstance -Class $class | Where-Object {$_.DisplayName -eq "name.of.my.agent" }
Get-SCOMRelationshipInstance -SourceInstance $agent | ? {(($_.RelationshipId -eq '37848e16-37a2-b81b-daaf-60a5a626be93') -or ($_.RelationshipId -eq 'ca26f3f0-b8ce-c193-d6df-632d53dee714')) -and ($_.IsDeleted -eq $False)} | Sort TargetObject | FT SourceObject,TargetObject,RelationshipId

Measuring this command shows us a significant faster runtime of just a few milliseconds

Measure-command {Get-SCOMRelationshipInstance -SourceInstance $target | ? {($_.RelationshipId -eq '37848e16-37a2-b81b-daaf-60a5a626be93') -or ($_.RelationshipId -eq 'ca26f3f0-b8ce-c193-d6df-632d53dee714')} | Sort TargetObject | FT SourceObject,TargetObject,RelationshipId }

Days              : 0
Hours             : 0
Minutes           : 0
Seconds           : 0
Milliseconds      : 94
Ticks             : 948595
TotalDays         : 1,09791087962963E-06
TotalHours        : 2,63498611111111E-05
TotalMinutes      : 0,00158099166666667
TotalSeconds      : 0,0948595
TotalMilliseconds : 94,8595

I think 94 ms vs. 26 Sec. ..... this could help speeding up your scripts a bit 😉

Have Fun!

 

 


Comments (1)

  1. In addition to Daniels great post: If you need to handle thousands of Agents, a direct SQL Query might be the fastest option, if you want to get primary and failover Management Server for all Agents.

    SELECT
    rgv.SourceObjectPath AS [Agent],
    meg.HealthState,
    meg.Isavailable,
    meg.InMaintenanceMode as [MaintenanceMode],
    meg.TimeAdded,
    rgv.TargetObjectPath AS [ManagementServer],
    CASE
    WHEN rtv.DisplayName = ‘Health Service Communication’ THEN ‘Primary’
    ELSE ‘Failover’
    END AS [Type]
    FROM ManagedTypeView mt INNER JOIN
    ManagedEntityGenericView AS meg ON meg.MonitoringClassId = mt.Id INNER JOIN
    RelationshipGenericView rgv ON rgv.SourceObjectId = meg.Id INNER JOIN
    RelationshipTypeView rtv ON rtv.Id = rgv.RelationshipId
    WHERE mt.Name = ‘Microsoft.SystemCenter.Agent’ AND
    rtv.Name like ‘Microsoft.SystemCenter.HealthService%Communication’ AND
    rgv.IsDeleted = 0

Skip to main content