Ron's Sandbox

Iterating Groups in SCOM

Monday, 1 December 2008 23:51 by hagermanr
 

Greetings all,

I've had the fundamental need to go through and find all of the servers in the SCOM console that belong to a specific group. The idea is that we monitor most servers with SCOM and send the critical hardware and OS alerts to another company that uses OVO while the application alerts go to the Boeing server administrators for those applications.

So I created a group and dynamically exclude all servers that don't go to the external company. This is much easier than trying to include every server since we only manage the domain controllers and Exchange servers ourselves and all others go to the other company.

Without getting into regular expressions and the rules of the group, I'll talk about the real intent here. I need to have some C# code that runs as a Windows service on my utility server. It will go through and get the list of servers being sent to OVO and it will then query the OVO database to see if that server is defined in the OVO node bank. If it is, great! If not, write a record to an Oracle table somewhere so a script on the Unix side can pick it up and add it to the OVO node bank through a cron job.

So that being said, here is the C# code to get the node list from SCOM:

 

public static void GetNodeGroups()
{
    ManagementGroup mg = new ManagementGroup("myRMS.boeing.com");
    ReadOnlyCollection<MonitoringObject> monitoringObjects; MonitoringClass computerMonitoringClass;
    MonitoringObjectCriteria criteria;

    computerMonitoringClass = mg.GetMonitoringClass( SystemMonitoringClass.WindowsComputer);
    criteria = new MonitoringObjectCriteria("Name LIKE '%'", computerMonitoringClass);
    monitoringObjects = mg.GetMonitoringObjects(criteria);

    foreach (MonitoringObject monitoringObject in monitoringObjects)
    {
        try
        {
            foreach (MonitoringObjectGroup DiscObj in monitoringObject.GetParentMonitoringObjects())
            {
                if (DiscObj.DisplayName == "My Computers Report Group"
                {
                     string[] test = monitoringObject.DisplayName.Split('.');

                     DataSet myDataSet = new DataSet();

                     myDataSet = GetOVOData(test[0]);

                     foreach (DataRow dataRow in myDataSet.Tables[0].Rows)
                     {
                         string sPropTagId = dataRow["PROP_TAG_ID"].ToString();
                         string sSystemName = dataRow["SYSTEM_NAME"].ToString();
                         string sDomainName = dataRow["DOMAIN_NAME"].ToString();
                         string sStatus = dataRow["STATUS"].ToString(); 
                         string sRespRollup = dataRow["RESPONSIBLE_ROLLUP"].ToString();
                         string sOSTypeName = dataRow["OS_TYPE_NAME"].ToString();
                         string sOSName = dataRow["OS_NAME"].ToString();
                         string sCity = dataRow["CITY"].ToString();

                         InsertLink(sPropTagId, sSystemName, sDomainName, sStatus, sRespRollup, sOSTypeName, sOSName, sCity); 
                     }
                 }
             }
         }
         catch { }
     }

}

 

So what is this doing?

Well, we connect to the RMS and retrieve a list of all the computer objects on the RMS. We then create an instance of the MonitoringObjectGroup and return the parent objects. The parent objects would be the groups that the computer class belongs to. Now, keep in mind, this code works with the computer class so it does not work with logical drive classes or any other class. You'd have to figure out how to find that and duplicate the code to list the groups for that as well. In all honesty, I don't have a requirement for that so I didn't bother to look into it.

Once I have all of the computer objects, I loop through each one and get the list of groups that it belongs to and if the groups DisplayName property equals the group I care about, then I look at OVO to see if it is there. In all honesty, since this is my test code, this particular function will query our servers database for things like asset tag number, OS type, etc. and then writes the data to my table. Once finished, I'll then have the OVO stuff integrated but you do get the general idea here.

If you want to know what groups a specific servers computer class belongs to, take the criteria line and change it a bit.

criteria = new MonitoringObjectCriteria("Name LIKE '%'", computerMonitoringClass);

Instead of NAME LIKE '%' you can say name like 'myserver%'  or even NAME ='myserver.company.com' and it will return groups for myserver. You would also want to remove the if statement so it doesn't filter the groups out.

If you have a need to do some kind of maintenance with a specific group of servers, this is the way to go. You can replace all the code inside the if block where I have the dataset with your maintenance tasks, or better yet, create a function to take care of your maintenance tasks and call the function from within the block.

Happy coding!

Ron

Be the first to rate this post

  • Currently 0/5 Stars.
  • 1
  • 2
  • 3
  • 4
  • 5

Comments

Add comment


(Will show your Gravatar icon)  

  Country flag

biuquote
  • Comment
  • Preview
Loading