In this blog post I’ll go over a basic seed class discovery. Basically a seed class is a class that normally utilizes a low cost discovery method (in this case a registry discovery) across a large group of servers to narrow the scope of which higher cost discoveries (A script in this case) then target in order to populate more classes.
So to further illustrate, say you have 1000 servers and an application that has 2 server types. You would like to create a class for each server type and you have a few things that can be used to identify the 2 server types:
- Both server types have a registry key “HKLM:SOFTWARE\Leibundgutski”
- One server type can be uniquely identified by the existence of a folder”C:\Leibundgutski”
- The other server type can be uniquely identified by the existence of a file “C:\Andy.tx”
OK, so assume you have 3 of each server type for a total of 6 servers that represent your application and you want one class for each server type (2 classes in total). You have some options to discover them:
- High Cost – You create 2 classes that utilize a scripted discovery that target something like Windows Server Computer. Scripts have a lot of overhead and are considered a high cost method of doing things so what would happen is you have 2 scripts running on each of the 1000 servers each time the discoveries are ran to populate the two classes. That’s a lot of scripts (2000 scripts ran)!
- Low Cost – You create 3 classes. One seed class that targets that same Windows Server Computer and then 2 more classes, one for each server type, that target the seed class. The seed class utilizes a registry discovery which is a very low cost method of discovery. The registry key only exists on the 6 (total) application servers so only those 6 servers are populated within the seed class. Then what you do is run the higher cost scripted discoveries against that seed class and now you’re only running 12 high cost scripted discoveries across your environment.
If you haven’t guessed number 2 is the way to go. What I’ll be going over today is how to author a basic seed class discovery with Visual Studio. The code can be found here: https://gallery.technet.microsoft.com/SCOM-Visual-Studio-394b6d37
Alright so we’ll start with the seed class
This is the class that represent all 6 application servers that we will then use as a target for the other two classes
- ID – This uniquely identifies the class within the management pack
- Comment – Comments about the class, put whatever you want in there
- Accessibility – Public, when set to true this class can be used by other management packs provided you seal this management pack
- Abstract – false, abstract classes have no instances and exist only to act as a base class for other classes. Don’t worry about this for now, consult the documentation if you want to know more (links to class documentation are in my MP)
- Base – This is the class you are basing your class off of
- Hosted – False, this is not hosted by another class
- Singleton – False, this class has unique instances that will be discovered (IE its not a group or anything like that. Each discovered server is separate)
Next, seed class discovery
This is a registry base discovery used to populate the seed class. It discovers a server instance when the registry key HKLM\Software\Leibundgutski is found.
- ID – BasicSeedDiscovery.LeibundgutskiRegKey.Discovery – This is the name used to uniquely identify this discovery in the management pack.
- Target – Windows!Microsoft.Windows.Server.Computer” – This is the class the discovery targets. “Windows” is a reference to the
Microsoft.Windows.Library management pack and “Microsoft.Windows.Server.Computer is a class within that mp.
- Remotable – true – this workflow can run for agentless monitoring.
- Enabled – true – this discovery is enabled. It will run by default once its imported.
DiscoveryClass – BasicSeedDiscovery.Seed.Class – This is the class the discovery will discover.
- ID – “DS” – This is the name that uniquely identifies this datasource within the scope of this discovery.
- TypeID – “Windows!Microsoft.Windows.FilteredRegistryDiscoveryProvider” – “Windows” is a reference to the
Microsoft.Windows.Library management pack and “Microsoft.Windows.FilteredRegistryDiscoveryProvider” is a registry discovery datasource within that management pack that I’m for this discovery.
- ComputerName – “$Target/Property[Type=”Windows!Microsoft.Windows.Computer”]/PrincipalName$” – This works out to be the computer name that the discovery is being ran on. Its a property of a parent class of Microsoft.Windows.Server.Computer.
- AttributeName – “LeibundgutskiKeyExists” – This uniquely identifies the value this registry attribute definition is pulling from the registry.
- Path – “SOFWARE\Leibundgutski” – This is the location in the registry that the registry attribute definition is looking at.
- PathType – “0” – zero specifies that we’re looking for a registry key.
- AttributeType – “0” – zero specifies that we are returning a true/false value (does it exist or not)
- Frequency – “86400” how often does the discovery run in seconds (once a day)
- ClassID – “$MPElement[Name=”BasicSeedDiscovery.Seed.Class”]$” – This reprisendts the class being discovered
- Name – “$MPElement[Name=”Windows!Microsoft.Windows.Computer”]/PrincipalName$” – The parent of our seed class “Microsoft.Windows.Computer” has a primary key of PrincipalName which is required to be discovered. This is referencing which value to populate
- Value – “$Target/Property[Type=”Windows!Microsoft.Windows.Computer”]/PrincipalName$” – It looks kind of weird but the class we are populating (the seed class) is based on the same class as the seed discovery targets. So we are referencing the PrincipalName of the discoveries target class to populate our seed class which in this case are the same.
- XPathQuery- “Values/LeibundgutskiKeyExists” – This represents the value we pulled in the RegistryAttributeDefinition.
- operation – “Equal” – The conditional parameter that is used to compare the XPathQuery and Value.
- Value – “true” – if the value held within the RegistryAttributeDefinition is true then discover the server.
Alright, that’s how you populate the seed class. Next we’ll go over the seedling classes and how they work.
So I’ll just go over major differences in these classes from the seed class. Each of these classes represent a particular type of server. One, a type of server that contains a folder c:\Leibundgutski, and the other which represents a type server that contains a file c:\Andy.txt. The other important difference is the base of these seedling classes is the seed class. Notice that instead of targeting all server computers like the seed class does I’m just targeting the seed class itself. In other words only the computers that contain the registry key HKLM\Software\Leibundgutski will have the logic that looks for the folder or file ran on it.
Now I’ll go over the seedling discovery script (LocationDiscovery.vbs)
This script is used by each of the seedling discoveries to populate their classes. It uses conditional if/then logic against the sLocation argument to determine whether to populate (see CreateClassInstance) either the folder or file class. Or both if they both happened to exist. Some of the SCOMey code and considerations to take note of in the script is that every script that is used in SCOM will need to bring in the SourceId and ManagedEntityID. I believe these are used to keep track of the workflow within SCOM. You’ll also need to initiate the “MOM.ScriptAPI” which the script uses to interact with SCOM. Notice the oAPI.CreateDiscoveryData. That is creating the object used to surface the discovery data to the class using the “CreateClassInstance” and then on to the “AddProperty” which is used to populate the key of a parent class (Microsoft.Windows.Computer). Note, you’ll need to populate the key property of any classes in the class hierarchy that contains a key property. At the end is the oAPI.Return which returns the discovery data to the workflow so it can populate the class. One last thing to note is the LogScriptEvent which creates a logging entry (if bDebug is true) in the Operations Manager event log on the target computer.
Alright, lastly is the discovery configuration for the seedling classes
Each of the discoveries individually call the LocationDiscovery.vbs script to populate their seedling class.
- ID – This is used to uniquely identify the discoveries within the management pack
- Target – This is the class the discovery targets (the seed discovery for both above)
- Remotable – Whether the discovery can be used for agentless monitoring
- Enabled – T/F is the discovery enabled by default
- ID – This is used to uniquely identify the datasource within the scope of the discovery
- TypeID – This is referencing to a datasource configuration in the “Microsoft.Windows.Library” MP “Microsoft.Windows.TimedScript.DiscoveryProvider” which run a script on a schedule
- IntervalSeconds – How often the script is ran in seconds
- ScriptName – The name of the script
- Arguments – These are the arguments passed to the script. See the description of how the script works above for information on the individual arguments
- ScriptBody – Although you could just put the script in here I create a script item in visual studio and use an IncludeFileContent (see the Scripts\VBScript folder in the project) to reference it.
- TimeoutSeconds – How many seconds before the script is set to time out.
That’s all for today, hope it was helpful. Next time I think I’ll skip around again and show you how to do a scripted monitor.