Share via


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

  • Anonymous
    December 13, 2017
    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.RelationshipIdWHERE mt.Name = 'Microsoft.SystemCenter.Agent' AND rtv.Name like 'Microsoft.SystemCenter.HealthService%Communication' AND rgv.IsDeleted = 0