.\Matthew Long

{An unsorted collection of thoughts}

How I added hundreds of Service Discoveries and Monitors into a SCOM MP in 20 minutes

Posted by Matthew on June 23, 2012

Recently I was presented by a customer with a huge list of windows services that needed to be discovered and monitored in Operations manager as part of an engagement. Many of these services were in house/custom services or ones for which no management pack currently exists.

The normal approach would of course be to put together grouped classes and discoveries that make sense for each application, however in this case time and project budget were against us, but more over the customer simply didn’t have the information (or need) to do anything other than simple up/down monitoring on each service.

So armed with a CSV file, the Visual Studio MP Authoring Extensions and a short amount of time, I set out to complete what would normally be a huge amount of work in a day.

The Solution – Snippets and Template groups

The Visual Studio MP authoring extensions have two features that used in combination allow you to take a template MP entity that you define (called a Snippit), and then by replacing placeholders with values from a table automatically generate concrete versions of your template when the MP is built (Template groups). The key here is that you can import the values into your template group from a CSV if you so wish!

This technique works for both 2007 and 2012 MPs, so you can use it for building any kind of management pack.

Before we get started however, here are two disclaimers:

This post was written using a pre-release copy of the Visual Studio MP Authoring extensions shown below are currently pre-release software.  Everything shown below could be subject to change at release.

This is not necessarily the best way to discover and monitor services. A more ideal approach would be to evaluate the services and cluster discoveries based on more than a service installation status. Consolidated discoveries would most likely be more efficient and services should only be monitored if that monitoring is useful. Having said that, anything can be created using the techniques shown here and even using this method to implement 10 items will be much faster than doing it by hand.

Steps After the jump…

Step 1 – define a custom class

The first thing we will need is a custom class to discover. In my case, I just implemented a new empty management pack with a class based off Microsoft.Windows.LocalService. To get started, Start Visual Studio and create a new management pack Project.

Next you’ll need to add a class. As i’m lazy and often work as part of a team, I like to store all my classes in different files, and don’t want to have to write all the XML required to add a class. So I’ll add a new class fragment to the project, which includes a lot of the standard definition done for me..

 So, now all I need to do is modify the sample to meet my needs.  Note that this file isn’t a complete management pack, it’s just a fragment so I can ignore a lot of the normal XML elements and just include the parts required for the class.  I can even skip whole sections, as seen where I define the display strings.  When I compile the MP, Visual Studio will stitch it all together into one valid MP file (each project in the solution becomes 1 MP, so you can have multiple MPs from a solution if you wish).

For sake of bandwidth and ease of reading, i’ll include my finished class here as XML directly.

<ManagementPackFragment SchemaVersion="1.0" xmlns:xsd="<a href="http://www.w3.org/2001/XMLSchema">http://www.w3.org/2001/XMLSchema</a>">
   <TypeDefinitions>
     <EntityTypes>
       <ClassTypes>
<ClassType ID="Blog.Snippit.ServiceDemo.Class.Service" Base="Windows!Microsoft.Windows.LocalService" Accessibility="Public" Abstract="false" Hosted="true" Singleton="false">
             <Property ID="ServiceName" Key="true" Type="string" MaxLength="256" CaseSensitive="false"/>
             <Property ID="ServerName" Key="false" Type="string" MaxLength="256" CaseSensitive="false"/>
           </ClassType>
         </ClassTypes>
     </EntityTypes>
   </TypeDefinitions>
   <LanguagePacks>
<LanguagePack ID="ENU" IsDefault="true">
       <DisplayStrings>
<DisplayString ElementID="Blog.Snippit.ServiceDemo.ClassService">
           <Name>Custom Service Class</Name>
           <Description>A Custom windows service class.</Description>
DisplayString>
<DisplayString ElementID="Blog.Snippit.ServiceDemo.ClassService" SubElementID="ServiceName">
           <Name>Service Name</Name>
           <Description>The actual name of the service (not the display name).</Description>
         </DisplayString>
         <DisplayString ElementID="Blog.Snippit.ServiceDemo.Class.Service" SubElementID="ServerName">
           <Name>Server Name</Name>
           <Description>The name of the computer on which this service is running.</Description>
         </DisplayString>
       </DisplayStrings>
     </LanguagePack>
   </LanguagePacks>
 </ManagementPackFragment>

As you can see, I’ve defined a simple class with 2 properties. Don’t worry if you can’t remember all the elements and attributes that make up a class, Visual Studio has Intelisense and validates my code against the schema as we go!  It even does intelisense on the XML attributes, so I don’t need to remember my class names and properties when filling out the display strings!

Step 2 – create a discovery Snippit

Now we have our class, we need a Snippit. This will define our Discovery template, containing everything we need to discover a service, but with special placeholders for the service name and display information.

First add a new snippet to the project

And now, start adding in your code as you normally would. Whenever you come to a place where you’ll need a unique value for each discovery (service name, IDs, display names) you can instead insert one of three new special values, shown in yellow below.

alias will automatically resolve an MP name into the valid alias used in this MP. Not required, but does help if you later upgrade or change your referenced MPs.  Nice, but not life changing.
choice will allow you to specify a list of values the person using the template can select for each instance. Can be useful for setting true/false properties such as enabled, alert generation, severity levels, etc.
text allows the user to freely enter text that will be inserted at this location. Very flexible and powerful, and what you’ll use most of the time.

It’s worth noting that you can use the Same value multiple times in the template, just use the same name wherever you need it.

Step 3 – add a template group to the MP Project

Now we have our template, it’s time to create some instances of it!   Add a Snippit template group to the project, and give it a meaningful name.

Select our snippet to use.

And now, the magic part. Normally we would now have to fill in each row and column (rows represent each item that will be automatically generated). See that Import CSV button? This is what’s going to make your life a lot easier!

What you need is a CSV file with a column for each value the snippet requires. Don’t use column headers, they will be included as an item! Simply arrange your columns in the CSV so that the first column is the first unique field in the snippet, the second is the second, and move the duplicate columns in the template to the end. Duplicate columns are a graphical glitch, once one column has been populated they will all share the same value. So in my example below I have 3 columns in my CSV: Service Names, Service Display Names and Discovery IDs. I just used a formula in excel to duplicate the service name and strip out illegal characters and spaces. Watch out for duplicates!

Then hit import CSV, select your file and make sure you get your content in the right order!

Step 4 – add monitoring to the custom class

Finally, let’s add a monitor to ensure the service is running! Since we are using a single class for all our services, and we have a class property for the service name, we can just target our class with a single monitor and pass in the service name!

Since I’m just monitoring a windows service (and there is already a perfectly good monitor for that) I can use a template group to set this up without having to type (almost!) any XML.  Well, I have to enter configuration XML, but that’s about as much as you would in the 2007 Authoring Console. I just add a template group and specify that I want it to contain Unit Monitors.

This works with both inbuilt monitors (such as the CheckNTServiceStateMonitor) as well as any custom ones you’ve defined.  So if you can author MPs using the authoring console but don’t know any XMl, they’ve got you covered.

All done, time to hit F6 to build our MP! Watch the output window to see the process, and if the build fails, check the error window for reasons why.  I got a warning stating that I’d configured Alert information for my monitor, but left my Monitor with alerting disabled.  It didn’t block me from building the MP, but it’s one of many new MPBA hints that help you to make optimal management packs.

Done!

If you use the management pack browser in Visual Studio, or open the MP in the authoring console, you’ll see all the discoveries that have been automatically built from my custom template!  You can see to the right I’ve added folders to my project and organised the fragment files and templates groups in a semi logical fashion.  You don’t really have to do this, I just find it makes things easier with larger projects.  If you wanted to you could put all your classes into one file, or all your related content (class, monitors for that class, discoveries etc) into a single file or template group.

As noted at the beginning of this process, you can automatically create anything using this technique, and you can generate as many elements from a Snippit as you’d like. If you wanted, the Snippit could include a class definition so that every service would have its own unique class (in that case, I’d probably define a base class they all inherit from and target my monitoring at that, but your monitor definition could also be in the Snippit).

I’ve personally used this technique a lot when putting in Performance or event Collection rules. Often these are configured exactly the same, other than a perf counter and display name. Using this technique can make adding 15 performance and collection rules to a class a piece of cake!

Advertisements

9 Responses to “How I added hundreds of Service Discoveries and Monitors into a SCOM MP in 20 minutes”

  1. John said

    Hello,

    I’d like to know something, is it possible to discover and monitor services which have a different name but at least one key word, like xxxxkeywordxxx-xxxx

    Thanks in advance.

    • Matthew said

      Hi John,

      Brian Wren has documented doing this using the built in SCOM Service templates, so while you will have to get your hands a little dirty with some XML, it’s very straightforward to follow, and will require nothing more than the SCOM console and Notepad (or other text editor of choice!).

      http://blogs.technet.com/b/brianwren/archive/2008/03/07/using-wildcards-with-the-windows-service-template.aspx

      If you want to do this as part of the monitoring of a custom class in your own management pack, you can either adapt his example above (uses WMI) or write your own simple discovery script module to discover your service.

      What you’ll need to do (via either VBScript & WMI or Powershell) is create a discovery that will enumerate all the services on the machine that match your key word (a simple Regular expression will do this) and then create an object instance for each matching service. Then you can use the built in Service monitor as i have above to monitor the service without having to hard code the service name.

      You won’t need the Visual Studio Authoring Extensions to do any of this, the 2007 R2 Authoring Console can accomplish it just fine. If you’ve got Powershell on all your target machines and SCOM 2012 or SCOM 2007 R2 then this is a bit easier in powershell, as either of the below commands will retrieve your services (the latter is if you actually need to search for the x letters, but don’t care what they are, just their number and layout)

      Get-Service -Name *keyword*
      Get-Service | Where {$_.Name -match ‘^….keyword…-….$’}

      Hope that helps!

      Kind regards,

      Matthew

  2. Garion said

    I am trying to follow this example, but I’m confused as to what is required in the Monitor Configuration for the configuration XML. I’ve chosen the Windows!Microsoft.Windows.CheckNTServiceStateMonitorType as it seemed logical but getting build errors that I believe are regarding the configuration xml as I haven’t put anything in there. This is my first attempt at advanced MP authoring and would appreciate if you could offer some insight into what is required for the config xml. Thanks!

    Error 19 Failed to verify Discovery [CTCServiceMP.Class.Service.guardian]
    Failed to verify referenced module : ID=DSInvalid configuration specified for Module [DS]Schema Validation Failed.The element ‘Configuration’ has invalid child element ‘ClassID’. List of possible elements expected: ‘ClassId’. C:\Program Files (x86)\MSBuild\Microsoft\VSAC\Microsoft.SystemCenter.OperationsManager.targets 204 6 CTCServiceMP

    Error 20 Failed to verify Unit monitor with ID: CTCServiceMP.Monitor.Service.Availability.ServiceMonitor
    Schema Validation Failed.The element ‘Configuration’ has incomplete content. List of possible elements expected: ‘ComputerName’. Monitors\Monitors.Service.mptg.mpx 6 9 CTCServiceMP

    • Matthew said

      Hi Garion,

      The second build error is indeed related to your ServiceMonitor configuration, but quickly i’d just like to address the one above. XML is case sensitive (and in the case of Management Packs, order dependent) and you’ve got ClassID rather than ClassId.

      As for the config XML, this will be whatever is defined by the module (in this case, a monitortype) that you are using. The great thing about Visual Studio is that Intellisense is enabled for configuration XML when using the template groups, and can automatically detect the configuration required.. So if you open the config XML dialog and place your cursor between the elements and start typing an element name (or hit CTRL+SPACE) it will pop up with a listing. It will unfortunately only show you the next valid configuration parameter, so you’ll need to repeat this process until all required elements are set.

      You can also see the listing upfront of all the required elements by opening the Management pack browser (From the view menu) and changing the “Browse” dropdown to “My management Packs and References”. Open the management pack that contains your module (In this case, Microsoft.Windows.Library) and then expand “Type Library” and MonitorTypes. Select the monitortype you are using in the listing (Microsoft.Windows.CheckNTServiceStateMonitorType) and if you check the “Configuration” section of the XML shown, you’ll get all the configuration elements you need to specify, what their expected type is, and if they are optional or required.

      Remember that you must specify them exactly as they are written (case sensitive) and in the order they are defined.

      The short answer to your question, if you are following the example above, is:

        <ComputerName>$Target/Property[Type="YourClassIdGoesHere"]/ServerName$</ComputerName>
        <ServiceName>$Target/Property[Type="YourClassIdGoesHere"]/ServiceName$</ServiceName>
        <CheckStartupType>true</CheckStartupType>
      

      Obviously you’ll want to insert the class ID you’ve used in your MP into the above lines. If you’ve called your service name and computer name class properties something different, you’ll need to change those as well.

      Setting the CheckStartupType to true means that if the service is not set to automatic and is stopped, supress all alerting. If you need to alert on the service, regardless of it’s startup type (checked each time the monitor is run, so if someone changes this the new value is detected immediately) then set this to false.

      Hope that helps!

      Kind regards,

      Matthew

    • Matthew said

      Sorry, just updated my previous reply as I forgot to include the tags so wordpress stripped the XML part of the answer away!

  3. Alaguraj said

    Hi Matthew,

    I am also running into a situation where I should create a custom management pack to discover and monitor all windows local services with startup type “Automatic” and trigger alerts when they “Stopped” or “Not running”. I have gone through the above post but at the end, am not able to finish it properly since I am stuck with coding part. It would be more helpful if you could share the MP with me.

    • Matthew said

      Hi Alaguraj,

      The list of services that we built this from was actually a sample I received from a customer, and didn’t include all windows services (it was a static list). If you want to dynamically monitor all automatic windows services, you’d probably be better off creating a single script monitor targeted at your server that checks the running state of all services whose startup type is Automatic. This is easily achievable in both VBScript and Powershell, and will have the added advantage of –

      -The MP won’t need to be updated every time you want to add/remove a service from the list
      -You won’t be discovering hundreds of new objects into the SCOM DB
      -If someone changes the startup type of a service, you won’t have to wait for the long discovery cycle before the monitoring configuration is updated.
      -If multiple services are stopped on a machine, you can have a single alert listing all failed services, rather than many alerts for the same potential root cause (dependant service stopped).

      Hope that helps!

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