Kevin Holman's System Center Blog

Posts in this blog are provided "AS IS" with no warranties, and confers no rights. Use of included script samples are subject to the terms specified in the Terms of UseAre you interested in having a dedicated engineer that will be your Mic

What is a group anyway?

What is a group anyway?

  • Comments 9
  • Likes

So – this is a first part, of a multi-post series on creating groups.

 

The most common reason we create groups in OpsMgr… is to scope Notifications, Views, and to use for overrides.

Most of the groups my customers create are dealing with Windows Computer objects.  The reason for this, is that the Windows Computer object class, is a “parent" level” class that works well for the group uses just mentioned.  Lets look at what a group really is… in XML:

When we create a simple group to contain Windows Computers in the UI, it creates some basic XML behind the scenes.  Understanding this XML – will help us create much more powerful and dynamic groups down the road… doing things that cannot be done in the UI.

 

Let's get started.

I will create a new empty MP, named “GroupMP”.

 

With nothing in this MP… let’s look at the XML:

 

<?xml version="1.0" encoding="utf-8"?><ManagementPack ContentReadable="true" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
  <Manifest>
    <Identity>
      <ID>GroupMP</ID>
      <Version>1.0.0.0</Version>
    </Identity>
    <Name>GroupMP</Name>
    <References>
      <Reference Alias="SystemCenter">
        <ID>Microsoft.SystemCenter.Library</ID>
        <Version>6.0.6278.0</Version>
        <PublicKeyToken>31bf3856ad364e35</PublicKeyToken>
      </Reference>
    </References>
  </Manifest>
  <Presentation>
    <Folders>
      <Folder ID="Folder_ba0b8fceb992416c835fe9d66a6ce0a1" Accessibility="Public" ParentFolder="SystemCenter!Microsoft.SystemCenter.Monitoring.ViewFolder.Root" />
    </Folders>
  </Presentation>
  <LanguagePacks>
    <LanguagePack ID="ENU" IsDefault="false">
      <DisplayStrings>
        <DisplayString ElementID="GroupMP">
          <Name>GroupMP</Name>
          <Description />
        </DisplayString>
        <DisplayString ElementID="Folder_ba0b8fceb992416c835fe9d66a6ce0a1">
          <Name>GroupMP</Name>
        </DisplayString>
      </DisplayStrings>
    </LanguagePack>
  </LanguagePacks>
</ManagementPack>

 

Not much there.  We have the <Manifest> section, which contains the name, version, ID, and a single reference – to the System Center Library MP.  The <Presentation> section simply contains the UI generated folder name, which will show up in the console, by default.  The <LanguagePacks> section contains the friendly names for the MP name and the folder… which will be displayed in the console.

 

Now – lets add a group.  I will create a new group in the UI, named “ATestGroup”.  I will not give it any group membership…. and save it to my new MP, and export it.  Let’s see what changed:

 

<?xml version="1.0" encoding="utf-8"?><ManagementPack ContentReadable="true" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
  <Manifest>
    <Identity>
      <ID>GroupMP</ID>
      <Version>1.0.0.0</Version>
    </Identity>
    <Name>GroupMP</Name>
    <References>
      <Reference Alias="SystemCenter">
        <ID>Microsoft.SystemCenter.Library</ID>
        <Version>6.0.6278.0</Version>
        <PublicKeyToken>31bf3856ad364e35</PublicKeyToken>
      </Reference>
      <Reference Alias="MicrosoftSystemCenterInstanceGroupLibrary6062780">
        <ID>Microsoft.SystemCenter.InstanceGroup.Library</ID>
        <Version>6.0.6278.0</Version>
        <PublicKeyToken>31bf3856ad364e35</PublicKeyToken>
      </Reference>
    </References>
  </Manifest>
  <TypeDefinitions>
    <EntityTypes>
      <ClassTypes>
        <ClassType ID="UINameSpace66d4622586f2416c804144a081d72995.Group" Accessibility="Public" Abstract="false" Base="MicrosoftSystemCenterInstanceGroupLibrary6062780!Microsoft.SystemCenter.InstanceGroup" Hosted="false" Singleton="true" />
      </ClassTypes>
    </EntityTypes>
  </TypeDefinitions>
  <Monitoring>
    <Discoveries>
      <Discovery ID="UINameSpace66d4622586f2416c804144a081d72995.Group.DiscoveryRule" Enabled="true" Target="UINameSpace66d4622586f2416c804144a081d72995.Group" ConfirmDelivery="false" Remotable="true" Priority="Normal">
        <Category>Discovery</Category>
        <DiscoveryTypes>
          <DiscoveryRelationship TypeID="MicrosoftSystemCenterInstanceGroupLibrary6062780!Microsoft.SystemCenter.InstanceGroupContainsEntities" />
        </DiscoveryTypes>
        <DataSource ID="GroupPopulationDataSource" TypeID="SystemCenter!Microsoft.SystemCenter.GroupPopulator">
          <RuleId>$MPElement$</RuleId>
          <GroupInstanceId>$MPElement[Name="UINameSpace66d4622586f2416c804144a081d72995.Group"]$</GroupInstanceId>
          <MembershipRules>
            <MembershipRule Comment="EMPTY_RULE_8eadaced-59c8-4ebc-a4e4-b8428a374442">
              <MonitoringClass>$MPElement[Name="SystemCenter!Microsoft.SystemCenter.AllComputersGroup"]$</MonitoringClass>
              <RelationshipClass>$MPElement[Name="MicrosoftSystemCenterInstanceGroupLibrary6062780!Microsoft.SystemCenter.InstanceGroupContainsEntities"]$</RelationshipClass>
              <Expression>
                <SimpleExpression>
                  <ValueExpression>
                    <Value>True</Value>
                  </ValueExpression>
                  <Operator>Equal</Operator>
                  <ValueExpression>
                    <Value>False</Value>
                  </ValueExpression>
                </SimpleExpression>
              </Expression>
            </MembershipRule>
          </MembershipRules>
        </DataSource>
      </Discovery>
    </Discoveries>
  </Monitoring>
  <Presentation>
    <Folders>
      <Folder ID="Folder_ba0b8fceb992416c835fe9d66a6ce0a1" Accessibility="Public" ParentFolder="SystemCenter!Microsoft.SystemCenter.Monitoring.ViewFolder.Root" />
    </Folders>
  </Presentation>
  <LanguagePacks>
    <LanguagePack ID="ENU" IsDefault="false">
      <DisplayStrings>
        <DisplayString ElementID="GroupMP">
          <Name>GroupMP</Name>
        </DisplayString>
        <DisplayString ElementID="Folder_ba0b8fceb992416c835fe9d66a6ce0a1">
          <Name>GroupMP</Name>
        </DisplayString>
        <DisplayString ElementID="UINameSpace66d4622586f2416c804144a081d72995.Group">
          <Name>ATestGroup</Name>
        </DisplayString>
        <DisplayString ElementID="UINameSpace66d4622586f2416c804144a081d72995.Group.DiscoveryRule">
          <Name>Populate ATestGroup</Name>
          <Description>This discovery rule populates the group 'ATestGroup'</Description>
        </DisplayString>
      </DisplayStrings>
    </LanguagePack>
  </LanguagePacks>
</ManagementPack>

 

I have bolded in Red color – the new stuff.

In the <Manifest> section, we added a new reference… to the Microsoft.SystemCenter.InstanceGroup.Library MP, and gave it an alias of “MicrosoftSystemCenterInstanceGroupLibrary6062780”.  An alias is just a short way of referring to a management pack…  (just not so short when created by the UI)  :-)

We also added a new section, <TypeDefinitions>  In here – we defined a new class type…  for the UI generated group.  In this case – it is UINameSpace66d4622586f2416c804144a081d72995.Group.  The UI creates a randomly generated name for the group… just to make sure all group ID’s are unique in a management pack.  This definition of this group class, is based on the “Microsoft.SystemCenter.InstanceGroup” class, which is called from the recently referenced “Microsoft.SystemCenter.InstanceGroup.Library” MP, using the alias we just talked about.  Notice - “Singleton = True”.  Without going too deep at this point, this means the Group is a class, but is a single instance class… the only instance of this group class will be the group itself.  It may have members in the group at some point…. but those members are NOT instances of the group class.  They are simply objects, that have a containment relationship from the group class.  Ok, not too deep right now.

We also added another new section to the XML - <Monitoring>  Under <Monitoring> we will define the discovery that we need to run – in order to populate the group membership.  This discovery by default will call the “Microsoft.SystemCenter.GroupPopulator” (Group populator module) from the “SystemCenter!” alias (Microsoft.SystemCenter.Library MP)  This discovery will define what types of objects the group will contain, and any <MembershipRule> expressions we need to use to “match” on those objects.  For instance… we might want to match only on Windows Computer objects, with a NetBIOS Name that starts with “EX*” using a wildcard.  All this can be done with the UI – but at this point – we left it all blank.  What you see is is a basic discovery that does nothing… in this case.

We will also notice – that the <DisplayStrings> section got updated with a friendly name for the new discovery rule… which will be visible in the console for the object discovery.

 

Ok….  now lets add a simple discovery rule… a dynamic rule, that will place Windows Computer objects that match the example I just used… NetBIOS names that start with “EX”

image

 

If I perform a “View Group Members” (after a short wait for the updated MP to be processed by the RMS, and the group populator module to complete)… I will see this when I “view group members”:

 

image

 

So far, so good.  I have 4 Windows Computer objects in my group, all matching my criteria.  Lets look at the XML now, with the newest updates bold and blue:

 

<?xml version="1.0" encoding="utf-8"?><ManagementPack ContentReadable="true" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
  <Manifest>
    <Identity>
      <ID>GroupMP</ID>
      <Version>1.0.0.0</Version>
    </Identity>
    <Name>GroupMP</Name>
    <References>
      <Reference Alias="MicrosoftSystemCenterInstanceGroupLibrary6062780">
        <ID>Microsoft.SystemCenter.InstanceGroup.Library</ID>
        <Version>6.0.6278.0</Version>
        <PublicKeyToken>31bf3856ad364e35</PublicKeyToken>
      </Reference>
      <Reference Alias="SystemCenter">
        <ID>Microsoft.SystemCenter.Library</ID>
        <Version>6.0.6278.0</Version>
        <PublicKeyToken>31bf3856ad364e35</PublicKeyToken>
      </Reference>
      <Reference Alias="MicrosoftWindowsLibrary6062780">
        <ID>Microsoft.Windows.Library</ID>
        <Version>6.0.6278.0</Version>
        <PublicKeyToken>31bf3856ad364e35</PublicKeyToken>
      </Reference>
    </References>
  </Manifest>
  <TypeDefinitions>
    <EntityTypes>
      <ClassTypes>
        <ClassType ID="UINameSpace66d4622586f2416c804144a081d72995.Group" Accessibility="Public" Abstract="false" Base="MicrosoftSystemCenterInstanceGroupLibrary6062780!Microsoft.SystemCenter.InstanceGroup" Hosted="false" Singleton="true" />
      </ClassTypes>
    </EntityTypes>
  </TypeDefinitions>
  <Monitoring>
    <Discoveries>
      <Discovery ID="UINameSpace66d4622586f2416c804144a081d72995.Group.DiscoveryRule" Enabled="true" Target="UINameSpace66d4622586f2416c804144a081d72995.Group" ConfirmDelivery="false" Remotable="true" Priority="Normal">
        <Category>Discovery</Category>
        <DiscoveryTypes>
          <DiscoveryRelationship TypeID="MicrosoftSystemCenterInstanceGroupLibrary6062780!Microsoft.SystemCenter.InstanceGroupContainsEntities" />
        </DiscoveryTypes>
        <DataSource ID="GroupPopulationDataSource" TypeID="SystemCenter!Microsoft.SystemCenter.GroupPopulator">
          <RuleId>$MPElement$</RuleId>
          <GroupInstanceId>$MPElement[Name="UINameSpace66d4622586f2416c804144a081d72995.Group"]$</GroupInstanceId>
          <MembershipRules>
            <MembershipRule>
              <MonitoringClass>$MPElement[Name="MicrosoftWindowsLibrary6062780!Microsoft.Windows.Computer"]$</MonitoringClass>
              <RelationshipClass>$MPElement[Name="MicrosoftSystemCenterInstanceGroupLibrary6062780!Microsoft.SystemCenter.InstanceGroupContainsEntities"]$</RelationshipClass>
              <Expression>
                <RegExExpression>
                  <ValueExpression>
                    <Property>$MPElement[Name="MicrosoftWindowsLibrary6062780!Microsoft.Windows.Computer"]/NetbiosComputerName$</Property>
                  </ValueExpression>
                  <Operator>MatchesWildcard</Operator>
                  <Pattern>EX*</Pattern>
                </RegExExpression>
              </Expression>
            </MembershipRule>
          </MembershipRules>
        </DataSource>
      </Discovery>

    </Discoveries>
  </Monitoring>
  <Presentation>
    <Folders>
      <Folder ID="Folder_ba0b8fceb992416c835fe9d66a6ce0a1" Accessibility="Public" ParentFolder="SystemCenter!Microsoft.SystemCenter.Monitoring.ViewFolder.Root" />
    </Folders>
  </Presentation>
  <LanguagePacks>
    <LanguagePack ID="ENU" IsDefault="false">
      <DisplayStrings>
        <DisplayString ElementID="GroupMP">
          <Name>GroupMP</Name>
        </DisplayString>
        <DisplayString ElementID="Folder_ba0b8fceb992416c835fe9d66a6ce0a1">
          <Name>GroupMP</Name>
        </DisplayString>
        <DisplayString ElementID="UINameSpace66d4622586f2416c804144a081d72995.Group">
          <Name>ATestGroup</Name>
        </DisplayString>
        <DisplayString ElementID="UINameSpace66d4622586f2416c804144a081d72995.Group.DiscoveryRule">
          <Name>Populate ATestGroup</Name>
          <Description>This discovery rule populates the group 'ATestGroup'</Description>
        </DisplayString>
      </DisplayStrings>
    </LanguagePack>
  </LanguagePacks>
</ManagementPack>

 

This basically just added a new reference, and modified the discovery rule section – to reflect our updated relationship and criteria.

The new <reference> was because we added the “Windows Computer” object class to the group definitions.  This class needs to be referenced, because it lives in the “Microsoft.Windows.Library” MP, which the UI gave a reference alias of “MicrosoftWindowsLibrary6062780”.

The UPDATED <MembershipRule> section now has some new information.  

First – it defines the <MonitoringClass> we will use in this membership rule to be Windows Computer objects.

Next – it defines that the group will contain entities in the <RelationshipClass> section, esentially building the containment relationship between the Group Class Instance, and the Windows Computer objects.

Last – it defines the expression to use to “match” on the defined property we chose (NetBIOS name) with a pattern (EX* wildcard)  We can match on ANY known attribute of a class… and NetBIOS name is but one of many on the Windows Computer class.

 

This understand will be a fundamental building block… for the next group posts… which will require that we see what is happening behind the scenes with a basic group, in order to use much more advanced groupings, that prove difficult or impossible to achieve in the console.

Comments
  • Just want to add a note that might be useful to some when troubleshooting Dynamic group population like the one shown here: the "Matches Wildcard" operator is CASE-SENSITIVE, as far as I know. Therefore, depending on how your machines names have been written (when windows was installed) and therefore discovered, the above sample might or might not be populating your group, so you might need to add multiple criterias matching combinations or lower and upper case characters in NetBIOS names...

  • Absolutely correct.  I show an example of this in http://blogs.technet.com/kevinholman/archive/2008/02/01/configuring-notifications-to-include-specific-alerts-from-specific-groups-and-classes.aspx

  • Not really on topic, but we would like to list all groups that a particular server is a member of.  Any idea on how we could do that?

    Thanks.

  • To see all groups a computer is a member of (or any object) change "omdw" in the following query to your computername:

    SELECT SourceMonitoringObjectDisplayName AS 'Group'

    FROM RelationshipGenericView

    WHERE TargetMonitoringObjectDisplayName like ('%omdw%')

    AND (SourceMonitoringObjectDisplayName IN

    (SELECT ManagedEntityGenericView.DisplayName

    FROM ManagedEntityGenericView INNER JOIN

    (SELECT     BaseManagedEntityId

    FROM          BaseManagedEntity WITH (NOLOCK)

    WHERE      (BaseManagedEntityId = TopLevelHostEntityId) AND (BaseManagedEntityId NOT IN

    (SELECT     R.TargetEntityId

    FROM          Relationship AS R WITH (NOLOCK) INNER JOIN

    dbo.fn_ContainmentRelationshipTypes() AS CRT ON R.RelationshipTypeId = CRT.RelationshipTypeId

    WHERE      (R.IsDeleted = 0)))) AS GetTopLevelEntities ON

    GetTopLevelEntities.BaseManagedEntityId = ManagedEntityGenericView.Id INNER JOIN

    (SELECT DISTINCT BaseManagedEntityId

    FROM          TypedManagedEntity WITH (NOLOCK)

    WHERE      (ManagedTypeId IN

    (SELECT     DerivedManagedTypeId

    FROM dbo.fn_DerivedManagedTypes(dbo.fn_ManagedTypeId_Group()) AS fn_DerivedManagedTypes_1))) AS GetOnlyGroups ON

    GetOnlyGroups.BaseManagedEntityId = ManagedEntityGenericView.Id))

    ORDER BY 'Group'

  • Thanks for that Kevin, much appreciated. I think I'll create a report to put it in.

    Following on from that, would you also be able to tell me how we could get a listing of all Subscriptions containing a particular Group?

  • Thanks for detailed discription Kevin, much appreciated.

    assume we have the same senario

    i have a computer with small letters "ex07B.opsmgr.net" whcih i added it manually in the explicit members instead of dynamic rule.

    when i do the health explore on "ex07B.opsmgr.net i don't see the MP "GroupMP” & the monitors created the MP.

     Any idea on how we could do that?

    Thanks.

  • Not sure I follow you - health explorer will show all monitors targeting a specific object of a class.... plus any rollup monitors linked by a dependency.

    Are you targeting a group with your monitors and hence its not working?  You cannot target groups with a workflow.

    Feel free to contact me directly via the contact form on the blog - might be too complicated for this forum.

  • What if you want to query the groups from the data warehouse. The same structures don't seem to exist in the same way.

  • Coming back to this post a few years later... to say that on my recent OpsMgr 2012 environment, the "MatchesWildcard" now appears to correctly work by doing a case-insensitive match, unlike what I remembered from some years ago. It must have been fixed at one point, but I am not sure when.

Your comment has been posted.   Close
Thank you, your comment requires moderation so it may take a while to appear.   Close
Leave a Comment
Search Blogs