Operations Manager - How to create a Dynamic Distributed Application using Seed Discovery and PowerShell

This is a sample SC Operations Manager Management Pack (MP) that builds a Distributed Application (DA) dynamically based on a seed (registry key) discovery.  This sample builds a DA based on SC Orchestrator.  In this blog, I will detailed the discovery process on how to dynamically populate the DA Components group "All Web Sites" using a PowerShell script.

Overview of the components of my 3-tier LOB distributed application:

  • Database(s)
  • Website(s)
  • Windows Service(s)

   MyDynamicDA-Orchestrator

So, how do I populate a DA Component group for the All Web Sites DA using PowerShell? 

Type Definitions required

1- Class definition needed. 

     <!-- Seed class -->
    <ClassType ID="MyDynamicAppDA.Computers.Seed.Class" Accessibility="Internal" Abstract="false" Base="Windows!Microsoft.Windows.LocalApplication" Hosted="true" Singleton="false" />

    <!-- All Web Sites DA component group class -->
     <ClassType ID="MyDynamicAppDA.AllWebSites.DA" Accessibility="Public" Abstract="false" Base="MicrosoftSystemCenterServiceDesignerLibrary7084320!Microsoft.SystemCenter.ServiceDesigner.ServiceComponentGroup" Hosted="false" Singleton="true" />

Note:   I don't need a class for my Web Sites as I want to re-use the IIS web site class (see below)

2- Relationship definition needed.  In here, I specify the class that can be member of my DA component group

      <RelationshipType ID="MyDynamicAppDA.AllWebSitesDAContainsWebSite2008" Accessibility="Public" Abstract="false" Base="System!System.Containment">
          <Source>MyDynamicAppDA.AllWebSites.DA</Source>
          <Target>IIS2008!Microsoft.Windows.InternetInformationServices.2008.WebSite</Target>
     </RelationshipType>

PowerShell Script for Web Site discovery

1- My discovery must target my seed class 

    <!-- Sample discovery script for specific Web Sites targeted at instances of myDynamicAppDa Seed Servers -->
    <!-- This script populate the DA component and build the relationship -->
    <Discovery ID="MyDynamicAppDA.AllWebSites.DA.Discovery" Enabled="true" Target="MyDynamicAppDA.Computers.Seed.Class" ConfirmDelivery="false" Remotable="true" Priority="Normal">
      <Category>Discovery</Category>
      <DiscoveryTypes>
        <DiscoveryClass TypeID="MyDynamicAppDA.DA" />
        <DiscoveryClass TypeID="MyDynamicAppDA.AllWebSites.DA" />
        <DiscoveryRelationship TypeID="MyDynamicAppDA.DAContainsAllWebSitesDA" />
        <DiscoveryRelationship TypeID="MyDynamicAppDA.AllWebSitesDAContainsWebSite2008" />
        <DiscoveryRelationship TypeID="MyDynamicAppDA.AllWebSitesDAContainsWebSite2012" />
       

2- I use WMI to query local Websites for a specific name and return the Name and SiteID

IMPORTANT: You must have installed the 'IIS Management Scripts and Tools' for the 'IIS Role' for populating the All WebSites DA on the Server where the discovery will be executed.

    # Using IIS7 Management Scripts and Tools.
    $sites = Get-WmiObject -Namespace "root/webadministration" -Class Site | ? {$_.Name -match 'Microsoft System Center 2012 Orchestrator'} | Select Name, ID

3- When a web site that should be part of my DA component group is found, then I create an instance of each class for my DA Component Group

    # Add Instance for the WebSites DA class 
    $Instance1 = $DiscoveryData.CreateClassInstance("$MPElement[Name='MyDynamicAppDA.AllWebSites.DA']$")
    $Instance1.AddProperty("$MPElement[Name='System!System.Entity']/DisplayName$", "All Web Sites")
    $DiscoveryData.AddInstance($Instance1)  

    # Add Instance for the WebSites class
    $Instance2 = $DiscoveryData.CreateClassInstance("$MPElement[Name='IIS2008!Microsoft.Windows.InternetInformationServices.2008.WebSite']$")
    $Instance2.AddProperty("$MPElement[Name='Windows!Microsoft.Windows.Computer']/PrincipalName$", $oTarget)
    $Instance2.AddProperty("$MPElement[Name='IISCommonLibrary!Microsoft.Windows.InternetInformationServices.WebSite']/SiteID$", "W3SVC/$($Site.ID)")
    $DiscoveryData.AddInstance($Instance2)

Note:  
The WebSite Instance should have already been discovered by the IIS MP, so to insure OpsMgr will not create a new web site instance for this discovery, we have to match the index of the web site class.  In this case, the index of the IIS Web Site class is the Site ID as follow: "W3SVC/$($Site.ID)"

4- Once I have the instance of each class, then I create an instance for the relationship:

    # Add Relationship class WebSites contains WebSite
    $Relation1 = $DiscoveryData.CreateRelationshipInstance("$MPElement[Name='MyDynamicAppDA.AllWebSitesDAContainsWebSite2008']$")
    $Relation1.Source = $Instance1
    $Relation1.Target = $Instance2
    $DiscoveryData.AddInstance($Relation1)

The above detailed is a quick overview for advanced MP authors and there is definitely more to it. Included in this blog post, is a fully functional sample MP with detailed comments in it. I would highly recommend anyone interested to open the MP using a text editor to review all the comments.

MyDynamicApp Sample MP

Notes:  

  1. You cannot edit this DA using the DA User Interface from the Authoring tab of the OpsMgr console.  It is suggested to seal the MP to avoid making any unwanted modifications
  2. It may take some time for the distributed application to roll up health.

This posting is provided "AS IS" with no warranties and confers no rights.

Comments

  • Anonymous
    January 01, 2003
    Operations Manager - How to create a Dynamic Distributed Application using PowerShell
    thank you
  • Anonymous
    January 01, 2003
    Operations Manager - How to create a Dynamic Distributed Application using PowerShell
    thank you