The following article by Jimmy Harper explains very well how to set up agents and gateways’ failover paths thru Powershell http://blogs.technet.com/b/jimmyharper/archive/2010/07/23/powershell-commands-to-configure-gateway-server-agent-failover.aspx . This is the approach I also recommend, and that article is great – I encourage you to check it out if you haven’t done it yet!
Anyhow, when checking for the actual failover paths that have been configured, the use of Powershell suggested by Jimmy is rather slow – especially if your agent count is high. In the Operations Manager Health Check tool I was also using that technique at the beginning, but eventually moved to the use of SQL queries just for performance reasons. Since then, we have been using these SQL queries quite successfully for about 3 years now.
But this the season of giving... and I guess SQL Queries can be a gift, right? Therefore I am now donating them as Christmas Gift to the OpsMrg community
Enjoy – and Merry Christmas!
--GetAgentForWhichServerIsPrimary SELECT SourceBME.DisplayName as Agent,TargetBME.DisplayName as Server FROM Relationship R WITH (NOLOCK) JOIN BaseManagedEntity SourceBME ON R.SourceEntityID = SourceBME.BaseManagedEntityID JOIN BaseManagedEntity TargetBME ON R.TargetEntityID = TargetBME.BaseManagedEntityID WHERE R.RelationshipTypeId = dbo.fn_ManagedTypeId_MicrosoftSystemCenterHealthServiceCommunication() AND SourceBME.DisplayName not in (select DisplayName from dbo.ManagedEntityGenericView WITH (NOLOCK) where MonitoringClassId in (select ManagedTypeId from dbo.ManagedType WITH (NOLOCK) where TypeName = 'Microsoft.SystemCenter.GatewayManagementServer') and IsDeleted ='0') AND SourceBME.DisplayName not in (select DisplayName from dbo.ManagedEntityGenericView WITH (NOLOCK) where MonitoringClassId in (select ManagedTypeId from dbo.ManagedType WITH (NOLOCK) where TypeName = 'Microsoft.SystemCenter.ManagementServer') and IsDeleted ='0') AND R.IsDeleted = '0' --GetAgentForWhichServerIsFailover SELECT SourceBME.DisplayName as Agent,TargetBME.DisplayName as Server FROM Relationship R WITH (NOLOCK) JOIN BaseManagedEntity SourceBME ON R.SourceEntityID = SourceBME.BaseManagedEntityID JOIN BaseManagedEntity TargetBME ON R.TargetEntityID = TargetBME.BaseManagedEntityID WHERE R.RelationshipTypeId = dbo.fn_ManagedTypeId_MicrosoftSystemCenterHealthServiceSecondaryCommunication() AND SourceBME.DisplayName not in (select DisplayName from dbo.ManagedEntityGenericView WITH (NOLOCK) where MonitoringClassId in (select ManagedTypeId from dbo.ManagedType WITH (NOLOCK) where TypeName = 'Microsoft.SystemCenter.GatewayManagementServer') and IsDeleted ='0') AND SourceBME.DisplayName not in (select DisplayName from dbo.ManagedEntityGenericView WITH (NOLOCK) where MonitoringClassId in (select ManagedTypeId from dbo.ManagedType WITH (NOLOCK) where TypeName = 'Microsoft.SystemCenter.ManagementServer') and IsDeleted ='0') AND R.IsDeleted = '0' --GetGatewayForWhichServerIsPrimary SELECT SourceBME.DisplayName as Gateway, TargetBME.DisplayName as Server FROM Relationship R WITH (NOLOCK) JOIN BaseManagedEntity SourceBME ON R.SourceEntityID = SourceBME.BaseManagedEntityID JOIN BaseManagedEntity TargetBME ON R.TargetEntityID = TargetBME.BaseManagedEntityID WHERE R.RelationshipTypeId = dbo.fn_ManagedTypeId_MicrosoftSystemCenterHealthServiceCommunication() AND SourceBME.DisplayName in (select DisplayName from dbo.ManagedEntityGenericView WITH (NOLOCK) where MonitoringClassId in (select ManagedTypeId from dbo.ManagedType WITH (NOLOCK) where TypeName = 'Microsoft.SystemCenter.GatewayManagementServer') and IsDeleted ='0') AND R.IsDeleted = '0' --GetGatewayForWhichServerIsFailover SELECT SourceBME.DisplayName As Gateway, TargetBME.DisplayName as Server FROM Relationship R WITH (NOLOCK) JOIN BaseManagedEntity SourceBME ON R.SourceEntityID = SourceBME.BaseManagedEntityID JOIN BaseManagedEntity TargetBME ON R.TargetEntityID = TargetBME.BaseManagedEntityID WHERE R.RelationshipTypeId = dbo.fn_ManagedTypeId_MicrosoftSystemCenterHealthServiceSecondaryCommunication() AND SourceBME.DisplayName in (select DisplayName from dbo.ManagedEntityGenericView WITH (NOLOCK) where MonitoringClassId in (select ManagedTypeId from dbo.ManagedType WITH (NOLOCK) where TypeName = 'Microsoft.SystemCenter.GatewayManagementServer') and IsDeleted ='0') AND R.IsDeleted = '0' --xplat agents select bme2.DisplayName as XPlatAgent, bme.DisplayName as Server from dbo.Relationship r with (nolock) join dbo.RelationshipType rt with (nolock) on r.RelationshipTypeId = rt.RelationshipTypeId join dbo.BasemanagedEntity bme with (nolock) on bme.basemanagedentityid = r.SourceEntityId join dbo.BasemanagedEntity bme2 with (nolock) on r.TargetEntityId = bme2.BaseManagedEntityId where rt.RelationshipTypeName = 'Microsoft.SystemCenter.HealthServiceManagesEntity' and bme.IsDeleted = 0 and r.IsDeleted = 0 and bme2.basemanagedtypeid in (SELECT DerivedTypeId FROM DerivedManagedTypes with (nolock) WHERE BaseTypeId = (select managedtypeid from managedtype where typename = 'Microsoft.Unix.Computer') and DerivedIsAbstract = 0)
Have you ever wondered what would happen if, in Operations Manager, you’d delete a Management Server or Gateway that managed objects (such as network devices) or has agents pointing uniquely to it as their primary server?
The answer is simple, but not very pleasant: you get ORPHANED objects, which will linger in the database but you won’t be able to “see” or re-assign anymore from the GUI.
So the first thing I want to share is a query to determine IF you have any of those orphaned agents. Or even if you know, since you are not able to "see" them from the console, you might have to dig their name out of the database. Here's a query I got from a colleague in our reactive support team:
-- Check for orphaned health services (e.g. agent). declare @DiscoverySourceId uniqueidentifier; SET @DiscoverySourceId = dbo.fn_DiscoverySourceId_User(); SELECT TME.[TypedManagedEntityid], HS.PrincipalName FROM MTV_HealthService HS INNER JOIN dbo.[BaseManagedEntity] BHS WITH(nolock) ON BHS.[BaseManagedEntityId] = HS.[BaseManagedEntityId] -- get host managed computer instances INNER JOIN dbo.[TypedManagedEntity] TME WITH(nolock) ON TME.[BaseManagedEntityId] = BHS.[TopLevelHostEntityId] AND TME.[IsDeleted] = 0 INNER JOIN dbo.[DerivedManagedTypes] DMT WITH(nolock) ON DMT.[DerivedTypeId] = TME.[ManagedTypeId] INNER JOIN dbo.[ManagedType] BT WITH(nolock) ON DMT.[BaseTypeId] = BT.[ManagedTypeId] AND BT.[TypeName] = N'Microsoft.Windows.Computer' -- only with missing primary LEFT OUTER JOIN dbo.Relationship HSC WITH(nolock) ON HSC.[SourceEntityId] = HS.[BaseManagedEntityId] AND HSC.[RelationshipTypeId] = dbo.fn_RelationshipTypeId_HealthServiceCommunication() AND HSC.[IsDeleted] = 0 INNER JOIN DiscoverySourceToTypedManagedEntity DSTME WITH(nolock) ON DSTME.[TypedManagedEntityId] = TME.[TypedManagedEntityId] AND DSTME.[DiscoverySourceId] = @DiscoverySourceId WHERE HS.[IsAgent] = 1 AND HSC.[RelationshipId] IS NULL;
Once you have identified the agent you need to re-assign to a new management server, this is doable from the SDK. Below is a powershell script I wrote which will re-assign it to the RMS. It has to run from within the OpsMgr Command Shell. You still need to change the logic which chooses which agent - this is meant as a starting base... you could easily expand it into accepting parameters and/or consuming an input text file, or using a different Management Server than the RMS... you get the point.
Similarly, you might get orphaned network devices. The script below is used to re-assign all Network Devices to the RMS. This script is actually something I have had even before the other one (yes, it has been sitting in my "digital drawer" for a couple of years or more...) and uses the same concept - only you might notice that the relation's source and target are "reversed", since the relationships are different:
With a bit of added logic it should be easy to have it work for specific devices.
Disclaimer
The information in this weblog is provided "AS IS" with no warranties, and confers no rights. This weblog does not represent the thoughts, intentions, plans or strategies of my employer. It is solely my own personal opinion. All code samples are provided "AS IS" without warranty of any kind, either express or implied, including but not limited to the implied warranties of merchantability and/or fitness for a particular purpose.