Creating and Updating Groups

I've received several questions over the past few days about how to create and update groups in the SDK. Below is a commented sample of how to do it.

What InsertCustomMonitoringObject group does, is create a new singleton class that derives from Microsoft.SystemCenter.InstanceGroup. It also creates a rule that populates this group which essentially defines the formula and inclusion and exlusion lists for the group. Hopefully the sample and comments in the code below explain this in more detail.

Note: A quick apology on the formating of the strings for formulas below. I found that when I had extra spaces, the schema validation failed and caused some exceptions to be thrown. This way, a direct cut and paste should work.

Edit: If you receive an ArgumentException for the references collection, this means that your default management pack already has a reference for the given management pack. When this happens, replace the alias I used with the existing alias for the management pack in the default management pack and don't add it to the newReferences collection.

using System;

using Microsoft.EnterpriseManagement;

using Microsoft.EnterpriseManagement.Configuration;

using Microsoft.EnterpriseManagement.ConnectorFramework;

using Microsoft.EnterpriseManagement.Monitoring;

 

namespace Jakub_WorkSamples

{

    partial class Program

    {

        static void InsertAndUpdatingGroups()

        {

            // Connect to the sdk service on the local machine

            ManagementGroup localManagementGroup = new ManagementGroup("localhost");

 

            // Create the formula

            // There can be multiple membership rules, no need for a root tag.

            // The monitoring class is the class of instance you want in the group.

            // The Relationship class is a relationhip whose source type needs to

            // be in the base class hierarchy of the class of your group (in this

            // case we actually create a new class using the insert method on

            // ManagementPack and this class will derive from InstanceGroup

            // which is the source of InstanceGroupContainsEntities) and the target

            // class needs to be in the base class hierarchy of the of the

            // aforementioned MonitoringClass.

            // You can also have an include and exclude list of specific entities that

            // also must match the relationship class and monitoring class critiera.

            // So in the example below, you could only include or exclude instances

            // that derive from Microsoft.Windows.Computer.

            // These look like this: (if both are specified the include list is first)

            // <IncludeList>

            // <MonitoringObjectId>f5E5F15E-3D7D-1839-F4C6-13E36BCD982a

            // </MonitoringObjectId>

            // </IncludeList>

            // <ExcludeList>

            // <MonitoringObjectId>f5E5F15E-3D7D-1839-F4C6-13E36BCD982a

            // </MonitoringObjectId>

            // </ExcludeList>

            // Prior to the include list, you can also add an expression to include

            // instances by. The element is defined as Expression and the schema for

            // it (as well as this entire MembershipRule schema) is defined in the

            // Microsoft.SystemCenter.Library management pack.

            // An example of an expression:

            // <Expression>

            // <SimpleExpression>

            // <ValueExpression>

            // <Property>

            // $MPElement[Name="Microsoft.SystemCenter.HealthService"]/IsRHS$

            // </Property>

            // </ValueExpression>

            // <Operator>Equal</Operator>

            // <ValueExpression>

            // <Value>False</Value>

            // </ValueExpression>

            // </SimpleExpression>

            // </Expression>

            // This expression can reference properties of the class of the membership

            // rule and in this case would include any health services that are not

            // the root health service.

            // Note: this example doesn't work with the rule I have below, it is simple

            // for illustrative purposes. I would need to filter by a

            // Microsoft.Windows.Computer property in order to use it below.

 

            string formula =

                @"<MembershipRule>

                <MonitoringClass>$MPElement[Name=""Windows!Microsoft.Windows.Computer""]$</MonitoringClass>

                <RelationshipClass>$MPElement[Name=""InstanceGroup!Microsoft.SystemCenter.InstanceGroupContainsEntities""]$</RelationshipClass>

                </MembershipRule>";

 

            // Create the custom monitoring object group

            CustomMonitoringObjectGroup allComputersGroup =

                new CustomMonitoringObjectGroup("Jakub.At.Work.Namespace",

                "AllComputerGroup",

                "Jakub@Work Sample All Computers Group",

                formula);

 

            // Get the default management pack.

            ManagementPack defaultManagementPack =

                localManagementGroup.GetManagementPacks(

                "Microsoft.SystemCenter.OperationsManager.DefaultUser")[0];

 

            // Get the management packs for references

            ManagementPack windowsManagementPack = localManagementGroup.

                GetManagementPack(SystemManagementPack.Windows);

            ManagementPack instanceGroupManagementPack = localManagementGroup.

                GetManagementPack(SystemManagementPack.Group);

            ManagementPackReferenceCollection newReferences =

                new ManagementPackReferenceCollection();

            newReferences.Add("Windows", windowsManagementPack);

            newReferences.Add("InstanceGroup", instanceGroupManagementPack);

 

            defaultManagementPack.InsertCustomMonitoringObjectGroup(allComputersGroup,

                newReferences);

 

            // Get the class that represents my new group

            MonitoringClass myNewGroup = localManagementGroup.

                GetMonitoringClasses("Jakub.At.Work.Namespace.AllComputerGroup")[0];

 

            // Get the discovery rule that populates this group

            // For the purposes of this sample, I know there is only 1 in the template

            MonitoringDiscovery groupPopulateDiscovery = myNewGroup.

                GetMonitoringDiscoveries()[0];

 

            // This is the full configuration of the discovery of which the

            // membership rule is one part that you can configure and update

            Console.WriteLine("The discovery configuration: {0}",

                groupPopulateDiscovery.DataSource.Configuration);

 

            // Update the configuration in some fasion

            string newConfiguration =

                @"<RuleId>$MPElement$</RuleId>

                <GroupInstanceId>$MPElement[Name=""Jakub.At.Work.Namespace.AllComputerGroup""]$</GroupInstanceId>

                <MembershipRules>

                    <MembershipRule>

                <MonitoringClass>$MPElement[Name=""Windows!Microsoft.Windows.Computer""]$</MonitoringClass>

                <RelationshipClass>$MPElement[Name=""InstanceGroup!Microsoft.SystemCenter.InstanceGroupContainsEntities""]$</RelationshipClass>

                <ExcludeList>

                    <MonitoringObjectId>f5E5F15E-3D7D-1839-F4C6-13E36BCD982a</MonitoringObjectId>

                </ExcludeList>

                </MembershipRule>

                </MembershipRules>";

 

            // Now we want to update the group membership for this group

            groupPopulateDiscovery.Status = ManagementPackElementStatus.PendingUpdate;

            groupPopulateDiscovery.DataSource.Configuration = newConfiguration;

            groupPopulateDiscovery.GetManagementPack().AcceptChanges();

        }

    }

}