GroupCalc

I have a strange liking for this quite obscure and convoluted capability of OpsMgr.

The GroupCalc provider is actually a database query, so it’s not a coincidence that the syntax can be mapped to SQL.  The SQL syntax below is pseudocode, not the actual select from the OpsMgr DB.

CASE 1

Group of computers with a name of *SRV*

select ComputerId from ComputerTable where name like ‘%SRV%’

Set my group

of computers

equal to what you get when you run "select * from Computer

where computer_name

like

%SRV%

<Configuration xmlns:p1="http://www.w3.org/2001/XMLSchema-instance"&gt;
  <RuleId>$MPElement</RuleId>
  <GroupInstanceId>$Target/Id$</GroupInstanceId>
  <GroupMonitoringClass>$MPElement[Name=’GRPMP.MyGroup’]$</GroupMonitoringClass>
  <MembershipRules>
    <MembershipRule>

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

      <RelationshipClass>$MPElement[Name=’SCLibrary!Microsoft.SystemCenter.ComputerGroupContainsComputer’$</RelationshipClass>

      <Expression>
        <SimpleExpression>
          <ValueExpression>
            <Property>$MPElement[Name=’Windows!Microsoft.Windows.Computer’]/NetbiosComputerName$</Property
          </ValueExpression>
          <Operator>Contain</Operator>
          <ValueExpression>
            <Value>SRV</Value>
          </ValueExpression>
        </SimpleExpression>
      </Expression>
    </MembershipRule>
  </MembershipRules>
</Configuration>

 

CASE 2

set my group equal to all computers that contain a MyHostedService class

select @myGroup = ComputerId from ComputerTable where ComputerId (select ComputerId from RelationshipTable where HostingClass = ‘Computer’ and HostedClass = ‘MyHostedService’)

Set my group

of Computers

Equal to the Computers

That contain
MyHostedService

<Configuration xmlns:p1="http://www.w3.org/2001/XMLSchema-instance"&gt;
  <RuleId>$MPElement</RuleId>
  <GroupInstanceId>$Target/Id$</GroupInstanceId>
  <GroupMonitoringClass>$MPElement[Name=’GRPMP.MyGroup’]$</GroupMonitoringClass>
  <MembershipRules>
    <MembershipRule>

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

      <RelationshipClass>$MPElement[Name=’SCLibrary!Microsoft.SystemCenter.ComputerGroupContainsComputer’$</RelationshipClass>

      <Expression>
        <Contains>
          <MonitoringClass>$MPElement[Name=’MyMP.MyHostedService’]$</MonitoringClass>
        </Contains>
      </Expression>
    </MembershipRule>
  </MembershipRules>
</Configuration>

CASE 3

Add some criteria, so that MyGroup has all computers that contain a MyHostedService class where the AutoStart property is set to False

Set my group

of Computers Equal to
The Computers

That contain
MyHostedService

where

the MyHostedService AutoStart property
equals

true

<Configuration xmlns:p1="http://www.w3.org/2001/XMLSchema-instance"&gt;
  <RuleId>$MPElement</RuleId>
  <GroupInstanceId>$Target/Id$</GroupInstanceId>
  <GroupMonitoringClass>$MPElement[Name=’GRPMP.MyGroup’]$</GroupMonitoringClass>
  <MembershipRules>
    <MembershipRule>

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

      <RelationshipClass>$MPElement[Name=’SCLibrary!Microsoft.SystemCenter.ComputerGroupContainsComputer’$</RelationshipClass>

      <Expression>
        <Contains>
          <MonitoringClass>$MPElementp[Name=’MyMP.MyHostedService’]$</MonitoringClass>
          <Expression>
            <SimpleExpression>
              <Property>$MPElement[Name=’MyMP.MyHostedService’]/AutoStart$</Property>
            </SimpleExpression>
            <Operator>Equal</Operator>
            <SimpleExpression>
              <Value>True</Value>
            </SimpleExpression>
          </Expression>
        </Contains>
      </Expression>
    </MembershipRule>
  </MembershipRules>
</Configuration>

 

One important point often missed is the unforgiving implementation of logic.  If you want a group that consists of multiple types, you have to OR them, not AND them.  People tend to think in terms of "I want class A and class B in my group" so they use AND, but this is incorrect.  If A and B have no derivation chain (i.e. one is not based on the other in some way), the result of AND is the empty set.  See the diagram.

When you say "AND" you are telling the engine to group "all objects that are class A and class B".  Objects can only be of A or B, there aren’t any that are both A and B, so nothing gets put into the group.

To have a group contain objects of different class types, the containment relationship between the group and the objects must specify a target that is a common base class for both A and B.  Every class has a common base class in System!System.Entity, so you can use this in a pinch.  You can also create multiple containment relationships with the group as the source and your class as the target. 

(CASE 4)

Assuming you have the object and relationship model correct, below is a configuration for Group_of_A_and_B to contain objects of both ClassA and ClassB

Group_of_A_and_B is the source
class for 2 containment relationships:
Contains ClassA (target)
Contains ClassB (target)

For my first membership rule
Use ClassA
And the appropriate relationship

then narrow down which ClassA

By using Property "Prop1"

And looking for

"Specific Property Value"

For my second membership rule
Use ClassB
And the appropriate relationship

then narrow down which ClassB’s

By using Property "PropX"

And using regular expression
to match AAfBBxxx, AA1BBqqq, etc.

<RuleId>$MPElement$</RuleId>
<GroupInstanceId>$Target/Id$</GroupInstanceId>
<GroupMonitoringClass>$MPElement[Name=’GroupPlayground.Group_of_A_and_B’]$</GroupMonitoringClass>
  <MembershipRules>

    <MembershipRule>
      <MonitoringClass>$MPElement[Name=’GroupPlayground.ClassA’]$</MonitoringClass>
      <RelationshipClass>$MPElement[Name=’GroupPlayground.GroupContainsClassA’]$</RelationshipClass>
      <Expression>
        <SimpleExpression>
          <ValueExpression>
            <Property>$MPElement[Name=’GroupPlayground.ClassA’]/Prop1$</Property>
          </ValueExpression>
          <Operator>Equal</Operator>
          <ValueExpression>
            <Value>Specific Property Value</Value>
          </ValueExpression>
        </SimpleExpression>
      </Expression>
    </MembershipRule>
    <MembershipRule>
      <MonitoringClass>$MPElement[Name=’GroupPlayground.ClassB’]$</MonitoringClass>
      <RelationshipClass>$MPElement[Name=’GroupPlayground.GroupContainsClassB’]$</RelationshipClass>
      <Expression>
        <RegExExpression>
          <ValueExpression>
            <Property>$MPElement[Name=’GroupPlayground.ClassB’]/PropX$</Property>
          </ValueExpression>
          <Operator>MatchesRegularExpression</Operator>
          <Pattern>^aa.bb.*$</Pattern>
        </RegExExpression>
      </Expression>
    </MembershipRule>
</MembershipRules>

And for my Swedish friend – CASE 5

Exclude members from MyGroup if they are already members of Dev_ComputerGroup

Set my group

of Computers

Equal to all Computers

Not contained by group
Dev_ComputerGroup 

<Configuration xmlns:p1="http://www.w3.org/2001/XMLSchema-instance"&gt;
  <RuleId>$MPElement</RuleId>
  <GroupInstanceId>$Target/Id$</GroupInstanceId>
  <GroupMonitoringClass>$MPElement[Name=’GRPMP.MyGroup’]$</GroupMonitoringClass>
  <MembershipRules>
    <MembershipRule>

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

      <RelationshipClass>$MPElement[Name=’SCLibrary!Microsoft.SystemCenter.ComputerGroupContainsComputer’$</RelationshipClass>

      <Expression>
        <NotContained>
          <MonitoringClass>$MPElement[Name=’MyMP.Dev_ComputerGroup’]$</MonitoringClass>
        </NotContained>
      </Expression>
    </MembershipRule>
  </MembershipRules>
</Configuration>

CASE 6

A group of computers that have SQL Server but not DPM on them (assuming your MP reference has DPM for the Microsoft.Windows.SystemCenterDPM management pack)

Set my group

of Computers

Equal to all Computers

That don’t contain (in this case host)
A DPM Server

But do contain (host)
A SQL DBEngine 

<Configuration xmlns:p1="http://www.w3.org/2001/XMLSchema-instance"&gt;
  <RuleId>$MPElement</RuleId>
  <GroupInstanceId>$Target/Id$</GroupInstanceId>
  <GroupMonitoringClass>$MPElement[Name=’GRPMP.MyGroup’]$</GroupMonitoringClass>
  <MembershipRules>
    <MembershipRule>

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

      <RelationshipClass>$MPElement[Name=’SCLibrary!Microsoft.SystemCenter.ComputerGroupContainsComputer’$</RelationshipClass>

      <Expression>
        <And>
          <Expression>
            <NotContains>
              <MonitoringClass>$MPElement[Name=’DPM!Microsoft.Windows.SystemCenterDPM.DPMServer’]$</MonitoringClass>
            </NotContains>
          </Expression>
          <Expression>
            <Contains>
              <MonitoringClass>$MPElement[Name=’SQL!Microsoft.SQLServer.DBEngine’]$</MonitoringClass>
            </Contains>
          </Expression>
        </And
      </Expression>
    </MembershipRule>
  </MembershipRules>
</Configuration>

 

CASE 7

Another newsgroup post

GroupMP.SQLGroup contains class instances of type SQL Server Role
  where SQL Server Role is hosted by
    Windows Servers that are contained in
      GroupMP.MyGroupOfComputers

Set my group

of SQL Server Roles

Equal to all SQL Server Roles
Contained (hosted) by Windows computers

that are contained by a specific group

 

<Discovery ID="GroupMP.GroupPop" Enabled="true" Target="GroupMP.SQLRoles" ConfirmDelivery="true" Remotable="true" Priority="Normal">
  <Category>Custom</Category>
  <DiscoveryTypes>
    <DiscoveryRelationship TypeID="SCInstanceLibrary!Microsoft.SystemCenter.InstanceGroupContainsEntities" />
  </DiscoveryTypes>
  <DataSource ID="GP" TypeID="SC!Microsoft.SystemCenter.GroupPopulator">
    <RuleId>$MPElement$</RuleId>
    <GroupInstanceId>$Target/Id$</GroupInstanceId>
    <MembershipRules>
      <MembershipRule>
        <MonitoringClass>$MPElement[Name=’SQL!Microsoft.SQLServer.ServerRole’]$</MonitoringClass>
        <RelationshipClass>$MPElement[Name=’SCInstanceLibrary!Microsoft.SystemCenter.InstanceGroupContainsEntities’]$</RelationshipClass>
        <Expression>
          <Contained>
            <MonitoringClass>$MPElement[Name=’Windows!Microsoft.Windows.Computer’]$</MonitoringClass>
            <Expression>
              <Contained>
                <MonitoringClass>$MPElement[Name=’GroupMP.MyGroupOfComputers’]$</MonitoringClass>
              </Contained>
            </Expression>
          </Contained>
        </Expression>
      </MembershipRule>
    </MembershipRules>
  </DataSource>
</Discovery>

CASE 8

Yet another newsgroup post.  Elizabeth1978 asked about a group of Agent Watchers, but limited to watchers for those computers where a custom class had been discovered.  This one sort of stirred in the back of my mind through all of MMS.  There isn’t a way to connect two unrelated objects through GroupCalc.  Turns out there is a lucky break here. Health Service Watcher, Health Service, Windows Computer, and LocalApplication all have some kind of containment/hosting relationship linking them.

  • Agent Watcher is a Health Service Watcher, which happens to be the source of a Containment relationship where Health Service is the target.  This exists for health rollup, not our use but we’re going to take advantage of it.
  • Health Service is a LocalApplication which means it is hosted by Windows.Computer.
  • Elizabeth1978’s custom class is also a LocalApplication, therefore also hosted by Windows Computer.

Cool!  So we can do this:

Set my group

of Agent Watchers

equal to the ones that contain Health Services

that are contained (hosted) by Windows Servers

that contain (host) my custom class

<Discovery ID="MyApplication.Core.ComputersGroup_AgentWatcher.DiscoveryRule" Enabled="true" Target="MyApplication.Core.AgentWatchersComputerGroup" ConfirmDelivery="true" Remotable="true" Priority="Normal">
  <Category>Custom</Category>
  <DiscoveryTypes>
    <DiscoveryRelationship TypeID="MicrosoftSystemCenterInstanceGroupLibrary6062780!Microsoft.SystemCenter.InstanceGroupContainsEntities" />
  </DiscoveryTypes>
  <DataSource ID="GroupPopulator" TypeID="SC!Microsoft.SystemCenter.GroupPopulator">
    <RuleId>$MPElement$</RuleId>
    <GroupInstanceId>$Target/Id$</GroupInstanceId>
    <MembershipRules>
      <MembershipRule>
        <MonitoringClass>$MPElement[Name=’SC!Microsoft.SystemCenter.AgentWatcher’]$</MonitoringClass>
        <RelationshipClass>$MPElement[Name=’MSCIGL!Microsoft.SystemCenter.InstanceGroupContainsEntities’]$</RelationshipClass>
        <Expression>
          <Contains>
            <MonitoringClass>$MPElement[Name=’SC!Microsoft.SystemCenter.HealthService’]$</MonitoringClass>
            <Expression>
              <Contained>
                <MonitoringClass>$MPElement[Name=’Windows!Microsoft.Windows.Computer’]$</MonitoringClass>
                <Expression>
                  <Contains>
                    <MonitoringClass>$MPElement[Name=’MyApplication.Core.Windows_Local_Application.Send_Connector.Class’]$</MonitoringClass>
                  </Contains>
                </Expression>
              </Contained>
            </Expression>
          </Contains>
        </Expression>
      </MembershipRule>
    </MembershipRules>
  </DataSource>
</Discovery>

   

CASE 9

Group of XP computers (from http://social.technet.microsoft.com/Forums/en-US/operationsmanagerauthoring/thread/8fc001bc-5fdf-435d-9fc6-51209889381b)

 

<MembershipRules>
  <MembershipRule>
    <MonitoringClass>$MPElement[Name="MicrosoftWindowsLibrary6062780!Microsoft.Windows.Computer"]$</MonitoringClass>
      <RelationshipClass>$MPElement[Name="MicrosoftSystemCenterInstanceGroupLibrary6062780!Microsoft.SystemCenter.InstanceGroupContainsEntities"]$</RelationshipClass>
      <Expression>
        <Contains>
          <MonitoringClass>$MPElement[Name="MicrosoftWindowsLibrary6062780!Microsoft.Windows.OperatingSystem"]$</MonitoringClass>
            <Expression>
              <RegExExpression>
                <ValueExpression>
                  <Property>$MPElement[Name="MicrosoftWindowsLibrary6062780!           Microsoft.Windows.OperatingSystem"]/OSVersionDisplayName$</Property>
                </ValueExpression>
                <Operator>ContainsSubstring</Operator>
                <Pattern>2003</Pattern>
              </RegExExpression>
            </Expression>
          </Contains>
        </Expression>
      </MembershipRule>
</MembershipRules>

 

CASE 10

Groups are created and populated based on a registry key.  But there should also be a hierarchy of groups where customername contains groups named customername_subgroup and customername_subgroup should contain customername_subgroup_subsubgroup should any exist. (http://social.technet.microsoft.com/Forums/en-US/operationsmanagerauthoring/thread/411232c0-53db-4ca8-a5a3-18d0cebab665?prof=required)

This rule will run targeting all instances of MyMP.Customer
ComputerGroup

So for whichever group is targeted

Add all computers

that are contained

by a Customer
ComputerGroup
that starts with
the same name
as this one (the one targeted)

RegEx “.”+” means at least one character after “my name” so that infinite recursion doesn’t occur.

<Configuration p1:noNamespaceSchemaLocation="C:\Documents and Settings\Administrator.TIADOM\Local Settings\Temp\Populate ParentGroup.xsd" xmlns:p1="http://www.w3.org/2001/XMLSchema-instance">
<!–
  $MyMP.CustomerComputerGroup$ is derived from type InstanceGroup (If you want to be able to contain HealthWatchers as well).
  All your groups are of type MyMP.CustomerComputerGroup.  In other words, you don’t differentiate group type by tier/hierarchy.
  MyMP.CustomerComputerGroup/Name is the property where you store "customername" or "customername_subgroup" or "customername_subgroup_subgroup2"
  SCIGL is Microsoft.SystemCenter.InstanceGroup.Library

  Discovery Rule Target = $MyMP.CustomerComputerGroup$
  Discovery Rule module type = System.GroupPopulator
  Configuration reads as follows
–>
  <RuleId>$MPElement$</RuleId>
  <GroupInstanceId>$Target/Id$</GroupInstanceId>
  <GroupMonitoringClass>$MPElement[Name"$MyMP.CustomerCustomerGroup$"]$</GroupMonitoringClass>
  <MembershipRules>
    <MembershipRule>
      <MonitoringClass>$MPElement[Name="Window!Microsoft.Windows.Computer"]$</MonitoringClass>
      <RelationshipClass>$MPElement[Name="SCIGL!Microsoft.SystemCenter.InstanceGroupContainsEntities"]$</RelationshipClass>
      <Expression>
        <Contained>
          <MonitoringClass>$MPElement[Name="MyMP.CustomerComputerGroup$"]</MonitoringClass>
          <Expression>
            <RegExExpression>
              <ValueExpression>
                <Property>$MPElement[Name=’MyMP.CustomerComputerGroup$]/Name$</Property>
              </ValueExpression>
              <Operator>MatchesRegularExpression</Operator>
              <Pattern>$Target/Property[Type=’MyMP.CustomerComputerGroup$]/Name$.+</Pattern>
            </RegExExpression>
          </Expression>
        </Contained>
      </Expression>
    </MembershipRule>
  </MembershipRules>
</Configuration>

Case 11

Containing actual subgroups rather than containing the objects in those groups.  This assumes a non-singleton group called MyMP.Group with key property Customer_GroupLevel.  The groups themselves must be discovered, since only singleton objects are automatically created, but this can be often done using the same logic as discovering the contained objects and simply creating a different class type.

This rule will add Group “Microsoft_STBU” to group “Microsoft” and will also add “Microsoft_STBU_Windows” to “Microsoft_STBU”

Target all MyMP.Group objects

using this relationship

Add all that match the key of the targeted one followed by text that does not include an underscore.

<Configuration p1:noNamespaceSchemaLocation="C:\Documents and Settings\Administrator.TIADOM\Local Settings\Temp\Populate ParentGroup.xsd" xmlns:p1="http://www.w3.org/2001/XMLSchema-instance">
  <RuleId>$MPElement$</RuleId>
  <GroupInstanceId>$Target/Id$</GroupInstanceId>
  <GroupMonitoringClass>$MPElement[Name=’MyMP.Group’]$</GroupMonitoringClass>
  <MembershipRules>
    <MembershipRule>
      <MonitoringClass>$MPElement[Name="MyMP.Group"]$</MonitoringClass>
      <RelationshipClass>$MPElement[Name="SCIGL!Microsoft.SystemCenter.InstanceGroupContainsEntities"]$</RelationshipClass>
      <Expression>
        <RegExExpression>
          <ValueExpression>
            <Property>$MPElement[Name=’MyMP.Group’]/Customer_GroupLevel$</Property>
          </ValueExpression>
          <Operator>MatchesRegularExpression</Operator>
          <Pattern>$Target/Property[Type=’MyMP.Group’]/Customer_GroupLevel$_[^_]+$</Pattern>
        </RegExExpression>
      </Expression>
    </MembershipRule>
  </MembershipRules>
</Configuration>

Advertisements
This entry was posted in Rules. Bookmark the permalink.

8 Responses to GroupCalc

  1. Elizabeth says:

    Hello!I have the need to achieve the population discovery illustrated in CASE 3 via VbScript.Currently I can, via VbScript, populate a Computer Group with a the class specified in as Target class but what I want to is to populate the Computer Group with all the Microsoft.Windows.Computer classed containing my Custom Class. Could you post an example if possible?Thank you!Lizzie.

  2. Chuck M says:

    Nice article. I am attempting to apply the logic in Case 5 but my MP throws up on the reference to my custom MP that contains the group I want to exclude.

    Thanks!

  3. JeffP says:

    I know this article is old but its still applicable and greatly helped me down the road of a custom group that would only contain healthservice watchers based on properties of a custom class. Thank you!! I really didnt think it could be done.

  4. Pingback: Operations Manager Advanced Dynamic Group Membership Rule – Objects from computers that are member in another Operations Manager group | Heading To The Clouds

  5. Pingback: SCOM GroupCalc Reference | sysctr2012

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s