Grouping Windows Computer Objects and Associated Health Service Watcher Object

The question has come up several times - how do you create a group that contains windows computer objects and their associated health service watcher object?  First, why would you even want to?  A key reason is because of the way OpsMgr admins commonly build out their notifications structure.  Different groups of windows servers are placed into opsmgr groups and the groups are associated with the servers administrators who should receive notifications when there is a problem.

The goal here would be to ensure administrators are notified when any alert is raised related to the servers they manage.  Mostly, this is straight forward and works fine as long as all objects of interest are 'windows computer' objects or roll up to 'windows computer objects.  One key exception to this is the 'health service watcher' object - which is responsible for monitoring agent heartbeats. 

In the spirit of trying to include all objects that might generate an alert about a monitored server you must include the 'health service watcher' in the group along with the 'windows computer' object or you will miss heartbeat failure alerts.  The problem comes in because the 'health service watcher' object is not related to the 'windows computer' object so simply creating a group of 'windows computer' objects does not include monitoring for heartbeat failures.  To fix this we need to add the 'health service watcher' object to the group. 

When you try to do this you quickly find that it's not as straight forward as it might seem.  As shown in the screenshot, there is limited formula criteria in common that would allow you to dynamically add every 'health service object' watcher object where there is a matching 'windows computer' object. 

image

One option would be to use wildcards and match on computer name.  That would work assuming two assumptions are true
-There is a dependable naming convention in place which will allow us to use wildcards
-The group is being constructed based on computer name
If either of these is not true then we are faced with manually adding each required 'health service watcher' object to the group.  This is not only tedious but a manual process as well.  It would really be helpful if we had a way to simply include every 'health service watcher' object in a group dynamically based on whatever criteria is used to populate the windows computer object.

Good news!  There is a way to do this - and it's not too difficult.  To set this up you can either build the MP completely in XML (first example) or you can build the MP group the way you want it in the UI and add the relevant XML sections later (second example). 

Example1
The example below shows the entire XML from a sample management pack (built completely in XML) that simply defines a group based on a standard windows computer object.  The XML section that populates group membership is shown in BOLD.

<ManagementPack  xmlns:xsi="https://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="https://www.w3.org/2001/XMLSchema">
  <Manifest>
    <Identity>
      <ID>SteveTest.mp</ID>
      <Version>1.0.0.0</Version>
    </Identity>
    <Name>SteveTest.mp</Name>
    <References>
      <Reference Alias="System">
        <ID>System.Library</ID>
        <Version>6.0.6278.0</Version>
        <PublicKeyToken>31bf3856ad364e35</PublicKeyToken>
      </Reference>
      <Reference Alias="Mom">
        <ID>Microsoft.SystemCenter.Library</ID>
        <Version>6.0.6278.0</Version>
        <PublicKeyToken>31bf3856ad364e35</PublicKeyToken>
      </Reference>
      <Reference Alias="Windows">
        <ID>Microsoft.Windows.Library</ID>
        <Version>6.0.6278.0</Version>
        <PublicKeyToken>31bf3856ad364e35</PublicKeyToken>
      </Reference>
    </References>
  </Manifest>
  <TypeDefinitions>
    <EntityTypes>
      <ClassTypes>
        <ClassType ID="SteveTest.GroupA" Accessibility="Public" Base="System!System.Group" Abstract="false" Singleton="true" />
      </ClassTypes>
      <RelationshipTypes>
        <RelationshipType Accessibility="Public" ID="SteveTest.GroupContainsEntity" Base="System!System.Containment">
          <Source>System!System.Group</Source>
          <Target>System!System.Entity</Target>
        </RelationshipType>
      </RelationshipTypes>
    </EntityTypes>
  </TypeDefinitions>
  <Monitoring>
    <Discoveries>
      <Discovery ID="SteveTest.Discovery" Target="SteveTest.GroupA" Enabled="true">
        <Category>Discovery</Category>
        <DiscoveryTypes/>
        <DataSource ID="GroupPopulationDataSourceA" TypeID="Mom!Microsoft.SystemCenter.GroupPopulator">
          <RuleId>$MPElement$</RuleId>
          <GroupInstanceId>$Target/Id$</GroupInstanceId>
          <MembershipRules>
            <MembershipRule>
<MonitoringClass>$MPElement[Name="Windows!Microsoft.Windows.Computer"]$</MonitoringClass>
<RelationshipClass>$MPElement[Name="SteveTest.GroupContainsEntity"]$</RelationshipClass>
<Expression>
<SimpleExpression>
<ValueExpression>
<Property>$MPElement[Name="Windows!Microsoft.Windows.Computer"]/NetBiosDomainName$</Property>
</ValueExpression>
<Operator>Equal</Operator>
<ValueExpression>
<Value>REDMOND</Value>
</ValueExpression>
</SimpleExpression>
</Expression>
</MembershipRule>
 
          </MembershipRules>
        </DataSource>
      </Discovery>
    </Discoveries>
    <Rules>
    </Rules>
  </Monitoring>
</ManagementPack>

The above works great EXCEPT the resulting group does not contain the health service watcher class.  To adjust this all you need to do is add in a second membership criteria section to the rules of the group as shown below. 

<MembershipRule>
  <MonitoringClass>$MPElement[Name="Mom!Microsoft.SystemCenter.HealthServiceWatcher"]$</MonitoringClass>
  <RelationshipClass>$MPElement[Name="SteveTest.GroupContainsEntity"]$</RelationshipClass>
  <Expression>
    <Contains>
      <MonitoringClass>$MPElement[Name="Mom!Microsoft.SystemCenter.HealthService"]$</MonitoringClass>
      <Expression>
        <Contained>
          <MonitoringClass>$MPElement[Name="Windows!Microsoft.Windows.Computer"]$</MonitoringClass>
          <Expression>
            <Contained>
              <MonitoringClass>$Target/Id$</MonitoringClass>
            </Contained>
          </Expression>
        </Contained>
      </Expression>
    </Contains>
  </Expression>
</MembershipRule>

So, when both are put together the resulting MP XML will appears as follows - note the comments added in to help explain what is being done.

<ManagementPack  xmlns:xsi="https://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="https://www.w3.org/2001/XMLSchema">
  <Manifest>
    <Identity>
      <ID>SteveTest.mp</ID>
      <Version>1.0.0.0</Version>
    </Identity>
    <Name>SteveTest.mp</Name>
    <References>
      <Reference Alias="System">
        <ID>System.Library</ID>
        <Version>6.0.6278.0</Version>
        <PublicKeyToken>31bf3856ad364e35</PublicKeyToken>
      </Reference>
      <Reference Alias="Mom">
        <ID>Microsoft.SystemCenter.Library</ID>
        <Version>6.0.6278.0</Version>
        <PublicKeyToken>31bf3856ad364e35</PublicKeyToken>
      </Reference>
      <Reference Alias="Windows">
        <ID>Microsoft.Windows.Library</ID>
        <Version>6.0.6278.0</Version>
        <PublicKeyToken>31bf3856ad364e35</PublicKeyToken>
      </Reference>
    </References>
  </Manifest>
  <TypeDefinitions>
    <EntityTypes>
      <ClassTypes>
        <ClassType ID="SteveTest.GroupA" Accessibility="Public" Base="System!System.Group" Abstract="false" Singleton="true" />
      </ClassTypes>
      <RelationshipTypes>
        <RelationshipType Accessibility="Public" ID="SteveTest.GroupContainsEntity" Base="System!System.Containment">
          <Source>System!System.Group</Source>
          <Target>System!System.Entity</Target>
        </RelationshipType>
      </RelationshipTypes>
    </EntityTypes>
  </TypeDefinitions>
  <Monitoring>
    <Discoveries> 
      <Discovery ID="SteveTest.Discovery" Target="SteveTest.GroupA" Enabled="true">
        <Category>Discovery</Category>
        <DiscoveryTypes/>
        <DataSource ID="GroupPopulationDataSourceA" TypeID="Mom!Microsoft.SystemCenter.GroupPopulator">
          <RuleId>$MPElement$</RuleId>
          <GroupInstanceId>$Target/Id$</GroupInstanceId>
          <MembershipRules>

            <!--
First membership rule groups computers of interest. The criteria reads something like this:
"Group Windows.Computer with a NetbiosDomainName equal to Redmond." This could be any attribute of the windows computer class that you would like to use - NetbiosComputerName, OrganizationalUnit, etc
-->

            <MembershipRule>
              <MonitoringClass>$MPElement[Name="Windows!Microsoft.Windows.Computer"]$</MonitoringClass>
              <RelationshipClass>$MPElement[Name="SteveTest.GroupContainsEntity"]$</RelationshipClass>
              <Expression>
                <SimpleExpression>
                  <ValueExpression>
                    <Property>$MPElement[Name="Windows!Microsoft.Windows.Computer"]/NetBiosDomainName$</Property>
                  </ValueExpression>
                  <Operator>Equal</Operator>
                  <ValueExpression>
                    <Value>REDMOND</Value>
                  </ValueExpression>
                </SimpleExpression>
              </Expression>
            </MembershipRule>

            <!--
Next membership rule groups associated health service watchers with computers already grouped by first membership rule. The
criteria reads something like this:
"Group HealthServiceWatcher that contains HealthService contained by a computer that is contained by this group."
-->

            <MembershipRule>
              <MonitoringClass>$MPElement[Name="Mom!Microsoft.SystemCenter.HealthServiceWatcher"]$</MonitoringClass>
              <RelationshipClass>$MPElement[Name="SteveTest.GroupContainsEntity"]$</RelationshipClass>
              <Expression>
                <Contains>
                  <MonitoringClass>$MPElement[Name="Mom!Microsoft.SystemCenter.HealthService"]$</MonitoringClass>
                  <Expression>
                    <Contained>
                      <MonitoringClass>$MPElement[Name="Windows!Microsoft.Windows.Computer"]$</MonitoringClass>
                      <Expression>
                        <Contained>
                          <MonitoringClass>$Target/Id$</MonitoringClass>
                        </Contained>
                      </Expression>
                    </Contained>
                  </Expression>
                </Contains>
              </Expression>
            </MembershipRule>

          </MembershipRules>
        </DataSource>
      </Discovery> 
     </Discoveries>
    <Rules>
    </Rules>
  </Monitoring>
</ManagementPack>

Example 2
The above works fine but is an example of building an MP by hand.  It would be helpful to have a more generic example that works in every situation.  In this example you should be able to simply copy and paste the added membership rule to your own MP and make sure all references are correct (if building the base group through the opsmgr UI they should be).  References that go together are color coded below to demonstrate what to check. 

For this example, we have extended the windows computer class with a registry attribute we want to key off of to build our initial group membership.  The extended windows computer attribute along with the initial group using that windows computer attribute were built in the UI and saved in the same management pack.  That base MP is below.  Note that this MP is much the same as the one in example 1 except that we now have a section defining the attribute and many of the names are in a different format because the MP was UI generated.

<?xml version="1.0" encoding="utf-8"?><ManagementPack ContentReadable="true" xmlns:xsd="https://www.w3.org/2001/XMLSchema" xmlns:xsl="https://www.w3.org/1999/XSL/Transform">
  <Manifest>
    <Identity>
      <ID>WindowsComputerExtendedGroupandAttributeSample</ID>
      <Version>1.0.0.0</Version>
    </Identity>
    <Name>WindowsComputerExtendedGroupandAttributeSample</Name>
    <References>
      <Reference Alias="MicrosoftWindowsLibrary6062780">
        <ID>Microsoft.Windows.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>
      <Reference Alias="SystemCenter">
        <ID>Microsoft.SystemCenter.Library</ID>
        <Version>6.0.6278.0</Version>
        <PublicKeyToken>31bf3856ad364e35</PublicKeyToken>
      </Reference>
    </References>
  </Manifest>
  <TypeDefinitions>
    <EntityTypes>
      <ClassTypes>
        <ClassType ID="Type1a02432a999f4a97bb6ceab38dc5da75" Accessibility="Public" Abstract="false" Base="MicrosoftWindowsLibrary6062780!Microsoft.Windows.Computer" Hosted="false" Singleton="false">
          <Property ID="AttributeDiscoveryGeneratedByUIea6af13d16af48848c01f386bbfae286" Type="string" Key="false" CaseSensitive="false" Length="256" MinLength="0" />
        </ClassType>
        <ClassType ID="UINameSpaceae66a981ae23413b994dfc3e94e9ca60.Group" Accessibility="Public" Abstract="false" Base="MicrosoftSystemCenterInstanceGroupLibrary6062780!Microsoft.SystemCenter.InstanceGroup" Hosted="false" Singleton="true" />
      </ClassTypes>
    </EntityTypes>
  </TypeDefinitions>
  <Monitoring>
    <Discoveries>
      <Discovery ID="AttributeDiscoveryGeneratedByUIafcf6a834dfd469a96919290733aa8b3" Enabled="true" Target="MicrosoftWindowsLibrary6062780!Microsoft.Windows.Computer" ConfirmDelivery="false" Remotable="true" Priority="Normal">
        <Category>PerformanceCollection</Category>
        <DiscoveryTypes>
          <DiscoveryClass TypeID="Type1a02432a999f4a97bb6ceab38dc5da75">
            <Property TypeID="Type1a02432a999f4a97bb6ceab38dc5da75" PropertyID="AttributeDiscoveryGeneratedByUIea6af13d16af48848c01f386bbfae286" />
          </DiscoveryClass>
        </DiscoveryTypes>
        <DataSource ID="AttributeDiscoveryGeneratedByUIef1ebc256cde41f79424a1d7a6f745b0" TypeID="MicrosoftWindowsLibrary6062780!Microsoft.Windows.RegistryDiscoverySingleProvider">
          <ComputerName>$Target/Property[Type="MicrosoftWindowsLibrary6062780!Microsoft.Windows.Computer"]/NetworkName$</ComputerName>
          <AttributeName>AttributeDiscoveryRulec1dfa684045c4dacb943e411c54fc344</AttributeName>
          <Path>software\microsoft\mssqlserver</Path>
          <PathType>0</PathType>
          <AttributeType>0</AttributeType>
          <Frequency>60</Frequency>
          <ClassId>$MPElement[Name="Type1a02432a999f4a97bb6ceab38dc5da75"]$</ClassId>
          <InstanceSettings>
            <Settings>
              <Setting>
                <Name>$MPElement[Name="Type1a02432a999f4a97bb6ceab38dc5da75"]/AttributeDiscoveryGeneratedByUIea6af13d16af48848c01f386bbfae286$</Name>
                <Value>$Data/Values/AttributeDiscoveryRulec1dfa684045c4dacb943e411c54fc344$</Value>
              </Setting>
              <Setting>
                <Name>$MPElement[Name="MicrosoftWindowsLibrary6062780!Microsoft.Windows.Computer"]/PrincipalName$</Name>
                <Value>$Target/Property[Type="MicrosoftWindowsLibrary6062780!Microsoft.Windows.Computer"]/PrincipalName$</Value>
              </Setting>
            </Settings>
          </InstanceSettings>
        </DataSource>
      </Discovery>
      <Discovery ID="UINameSpaceae66a981ae23413b994dfc3e94e9ca60.Group.DiscoveryRule" Enabled="true" Target="UINameSpaceae66a981ae23413b994dfc3e94e9ca60.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="UINameSpaceae66a981ae23413b994dfc3e94e9ca60.Group"]$</GroupInstanceId>
          <MembershipRules>
            <MembershipRule>
              <MonitoringClass>$MPElement[Name="Type1a02432a999f4a97bb6ceab38dc5da75"]$</MonitoringClass>
              <RelationshipClass>$MPElement[Name="MicrosoftSystemCenterInstanceGroupLibrary6062780!Microsoft.SystemCenter.InstanceGroupContainsEntities"]$</RelationshipClass>
              <Expression>
                <SimpleExpression>
                  <ValueExpression>
                    <Property>$MPElement[Name="Type1a02432a999f4a97bb6ceab38dc5da75"]/AttributeDiscoveryGeneratedByUIea6af13d16af48848c01f386bbfae286$</Property>
                  </ValueExpression>
                  <Operator>Equal</Operator>
                  <ValueExpression>
                    <Value>true</Value>
                  </ValueExpression>
                </SimpleExpression>
              </Expression>
            </MembershipRule>
          </MembershipRules>
        </DataSource>
      </Discovery>
    </Discoveries>
  </Monitoring>
  <Presentation>
    <Folders>
      <Folder ID="Folder_cdf9b9091d7349d18334357446d704f8" Accessibility="Public" ParentFolder="SystemCenter!Microsoft.SystemCenter.Monitoring.ViewFolder.Root" />
    </Folders>
  </Presentation>
  <LanguagePacks>
    <LanguagePack ID="ENU" IsDefault="false">
      <DisplayStrings>
        <DisplayString ElementID="WindowsComputerExtendedGroupandAttributeSample">
          <Name>WindowsComputerExtendedGroupandAttributeSample</Name>
        </DisplayString>
        <DisplayString ElementID="Folder_cdf9b9091d7349d18334357446d704f8">
          <Name>WindowsComputerExtendedGroupandAttributeSample</Name>
        </DisplayString>
        <DisplayString ElementID="AttributeDiscoveryGeneratedByUIafcf6a834dfd469a96919290733aa8b3">
          <Name>WindowsComputerExtendedAttributeSQLServerDiscovery</Name>
        </DisplayString>
        <DisplayString ElementID="Type1a02432a999f4a97bb6ceab38dc5da75">
          <Name>Windows Computer_Extended</Name>
        </DisplayString>
        <DisplayString ElementID="Type1a02432a999f4a97bb6ceab38dc5da75" SubElementID="AttributeDiscoveryGeneratedByUIea6af13d16af48848c01f386bbfae286">
          <Name>WindowsComputerExtendedAttributeSQLServer</Name>
          <Description />
        </DisplayString>
        <DisplayString ElementID="UINameSpaceae66a981ae23413b994dfc3e94e9ca60.Group">
          <Name>TestGrouptojoinWindowsComputerExtendedAttributeandHealthServiceWatcherObject</Name>
        </DisplayString>
        <DisplayString ElementID="UINameSpaceae66a981ae23413b994dfc3e94e9ca60.Group.DiscoveryRule">
          <Name>Populate TestGrouptojoinWindowsComputerExtendedAttributeandHealthServiceWatcherObject</Name>
          <Description>This discovery rule populates the group 'TestGrouptojoinWindowsComputerExtendedAttributeandHealthServiceWatcherObject'</Description>
        </DisplayString>
      </DisplayStrings>
    </LanguagePack>
  </LanguagePacks>
</ManagementPack>

The above may look confusing but it's actually very easy to add in our extra membership rules section that adds all related health service watcher objects.  The MP with the required addition is below .  You will have to make edits when adding the second membership rule section to make all of the relationships in the MP work out correctly.  In the snip below I've color coded the entries from the original MP above and the corresponding lines in the added MP that need to match.

<?xml version="1.0" encoding="utf-8"?><ManagementPack ContentReadable="true" xmlns:xsd="https://www.w3.org/2001/XMLSchema" xmlns:xsl="https://www.w3.org/1999/XSL/Transform">
  <Manifest>
    <Identity>
      <ID>WindowsComputerExtendedGroupandAttributeSample</ID>
      <Version>1.0.0.0</Version>
    </Identity>
    <Name>WindowsComputerExtendedGroupandAttributeSample</Name>
    <References>
      <Reference Alias="MicrosoftWindowsLibrary6062780">
        <ID>Microsoft.Windows.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>
      <Reference Alias="SystemCenter">
        <ID>Microsoft.SystemCenter.Library</ID>
        <Version>6.0.6278.0</Version>
        <PublicKeyToken>31bf3856ad364e35</PublicKeyToken>
      </Reference>
    </References>
  </Manifest>
  <TypeDefinitions>
    <EntityTypes>
      <ClassTypes>
        <ClassType ID="Type1a02432a999f4a97bb6ceab38dc5da75" Accessibility="Public" Abstract="false" Base="MicrosoftWindowsLibrary6062780!Microsoft.Windows.Computer" Hosted="false" Singleton="false">
          <Property ID="AttributeDiscoveryGeneratedByUIea6af13d16af48848c01f386bbfae286" Type="string" Key="false" CaseSensitive="false" Length="256" MinLength="0" />
        </ClassType>
        <ClassType ID="UINameSpaceae66a981ae23413b994dfc3e94e9ca60.Group" Accessibility="Public" Abstract="false" Base="MicrosoftSystemCenterInstanceGroupLibrary6062780!Microsoft.SystemCenter.InstanceGroup" Hosted="false" Singleton="true" />
      </ClassTypes>
    </EntityTypes>
  </TypeDefinitions>
  <Monitoring>
    <Discoveries>
      <Discovery ID="AttributeDiscoveryGeneratedByUIafcf6a834dfd469a96919290733aa8b3" Enabled="true" Target="MicrosoftWindowsLibrary6062780!Microsoft.Windows.Computer" ConfirmDelivery="false" Remotable="true" Priority="Normal">
        <Category>PerformanceCollection</Category>
        <DiscoveryTypes>
          <DiscoveryClass TypeID="Type1a02432a999f4a97bb6ceab38dc5da75">
            <Property TypeID="Type1a02432a999f4a97bb6ceab38dc5da75" PropertyID="AttributeDiscoveryGeneratedByUIea6af13d16af48848c01f386bbfae286" />
          </DiscoveryClass>
        </DiscoveryTypes>
        <DataSource ID="AttributeDiscoveryGeneratedByUIef1ebc256cde41f79424a1d7a6f745b0" TypeID="MicrosoftWindowsLibrary6062780!Microsoft.Windows.RegistryDiscoverySingleProvider">
          <ComputerName>$Target/Property[Type="MicrosoftWindowsLibrary6062780!Microsoft.Windows.Computer"]/NetworkName$</ComputerName>
          <AttributeName>AttributeDiscoveryRulec1dfa684045c4dacb943e411c54fc344</AttributeName>
          <Path>software\microsoft\mssqlserver</Path>
          <PathType>0</PathType>
          <AttributeType>0</AttributeType>
          <Frequency>60</Frequency>
          <ClassId>$MPElement[Name="Type1a02432a999f4a97bb6ceab38dc5da75"]$</ClassId>
          <InstanceSettings>
            <Settings>
              <Setting>
                <Name>$MPElement[Name="Type1a02432a999f4a97bb6ceab38dc5da75"]/AttributeDiscoveryGeneratedByUIea6af13d16af48848c01f386bbfae286$</Name>
                <Value>$Data/Values/AttributeDiscoveryRulec1dfa684045c4dacb943e411c54fc344$</Value>
              </Setting>
              <Setting>
                <Name>$MPElement[Name="MicrosoftWindowsLibrary6062780!Microsoft.Windows.Computer"]/PrincipalName$</Name>
                <Value>$Target/Property[Type="MicrosoftWindowsLibrary6062780!Microsoft.Windows.Computer"]/PrincipalName$</Value>
              </Setting>
            </Settings>
          </InstanceSettings>
        </DataSource>
      </Discovery>
      <Discovery ID="UINameSpaceae66a981ae23413b994dfc3e94e9ca60.Group.DiscoveryRule" Enabled="true" Target="UINameSpaceae66a981ae23413b994dfc3e94e9ca60.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="UINameSpaceae66a981ae23413b994dfc3e94e9ca60.Group"]$</GroupInstanceId>
          <MembershipRules>
            <MembershipRule>
              <MonitoringClass>$MPElement[Name="Type1a02432a999f4a97bb6ceab38dc5da75"]$</MonitoringClass>
              <RelationshipClass>$MPElement[Name="MicrosoftSystemCenterInstanceGroupLibrary6062780!Microsoft.SystemCenter.InstanceGroupContainsEntities"]$</RelationshipClass>
              <Expression>
                <SimpleExpression>
                  <ValueExpression>
                    <Property>$MPElement[Name="Type1a02432a999f4a97bb6ceab38dc5da75"]/AttributeDiscoveryGeneratedByUIea6af13d16af48848c01f386bbfae286$</Property>
                  </ValueExpression>
                  <Operator>Equal</Operator>
                  <ValueExpression>
                    <Value>true</Value>
                  </ValueExpression>
                </SimpleExpression>
              </Expression>
            </MembershipRule>
            <MembershipRule>
              <MonitoringClass>$MPElement[Name="SystemCenter!Microsoft.SystemCenter.HealthServiceWatcher"]$</MonitoringClass>
              <RelationshipClass>$MPElement[Name="MicrosoftSystemCenterInstanceGroupLibrary6062780!Microsoft.SystemCenter.InstanceGroupContainsEntities"]$</RelationshipClass>
              <Expression>
                <Contains>
                  <MonitoringClass>$MPElement[Name="SystemCenter!Microsoft.SystemCenter.HealthService"]$</MonitoringClass>
                  <Expression>
                    <Contained>
                      <MonitoringClass>$MPElement[Name="MicrosoftWindowsLibrary6062780!Microsoft.Windows.Computer"]$</MonitoringClass>
                      <Expression>
                        <Contained>
                          <MonitoringClass>$Target/Id$</MonitoringClass>
                        </Contained>
                      </Expression>
                    </Contained>
                  </Expression>
                </Contains>
              </Expression>
            </MembershipRule>         
          </MembershipRules>
        </DataSource>
      </Discovery>
    </Discoveries>
  </Monitoring>
  <Presentation>
    <Folders>
      <Folder ID="Folder_cdf9b9091d7349d18334357446d704f8" Accessibility="Public" ParentFolder="SystemCenter!Microsoft.SystemCenter.Monitoring.ViewFolder.Root" />
    </Folders>
  </Presentation>
  <LanguagePacks>
    <LanguagePack ID="ENU" IsDefault="false">
      <DisplayStrings>
        <DisplayString ElementID="WindowsComputerExtendedGroupandAttributeSample">
          <Name>WindowsComputerExtendedGroupandAttributeSample</Name>
        </DisplayString>
        <DisplayString ElementID="Folder_cdf9b9091d7349d18334357446d704f8">
          <Name>WindowsComputerExtendedGroupandAttributeSample</Name>
        </DisplayString>
        <DisplayString ElementID="AttributeDiscoveryGeneratedByUIafcf6a834dfd469a96919290733aa8b3">
          <Name>WindowsComputerExtendedAttributeSQLServerDiscovery</Name>
        </DisplayString>
        <DisplayString ElementID="Type1a02432a999f4a97bb6ceab38dc5da75">
          <Name>Windows Computer_Extended</Name>
        </DisplayString>
        <DisplayString ElementID="Type1a02432a999f4a97bb6ceab38dc5da75" SubElementID="AttributeDiscoveryGeneratedByUIea6af13d16af48848c01f386bbfae286">
          <Name>WindowsComputerExtendedAttributeSQLServer</Name>
          <Description />
        </DisplayString>
        <DisplayString ElementID="UINameSpaceae66a981ae23413b994dfc3e94e9ca60.Group">
          <Name>TestGrouĂtojoinWindowsComputerExtendedAttributeandHealthServiceWatcherObject</Name>
        </DisplayString>
        <DisplayString ElementID="UINameSpaceae66a981ae23413b994dfc3e94e9ca60.Group.DiscoveryRule">
          <Name>Populate TestGrouptojoinWindowsComputerExtendedAttributeandHealthServiceWatcherObject</Name>
          <Description>This discovery rule populates the group 'TestGrouptojoinWindowsComputerExtendedAttributeandHealthServiceWatcherObject'</Description>
        </DisplayString>
      </DisplayStrings>
    </LanguagePack>
  </LanguagePacks>
</ManagementPack>

OK, done - just a few minor adjustments and the group is returning both the original target AND the associated health service watcher objects as shown.

image