MP authoring samples - NT service based discovery
One of the things that I have been wanting to cover in this blog is advanced MP authoring. Lately I have been spending a fair bit of time doing MP related work so I am going to start blogging on this subject. My main focus will be to provide samples as well as share some thoughts that come to my mind when doing MP related work.
One of the problems that I see pretty frequently is people only want to target a particular set of computers when creating a new rule or monitor. A lot of times these computers perform a common function. Perhpas the most correct way to do this is define a new type and the discover instances of this type. This can be done using the Authoring Console or using raw XML. In this blog post I will show how you can do this by checking if a particular service is installed and not disabled on a computer as in many cases this is a easy way to identify a server as performing a particular function.
One the goals of providing the XML is so that you can easily tweak this to your needs and use it.
If you find this sort of samples usefull, please let me know and I will post more. If you have questions about the MP below please post comments and I will try to address them.
<ManagementPack ContentReadable="true" xmlns:xsd="https://www.w3.org/2001/XMLSchema" xmlns:xsl="https://www.w3.org/1999/XSL/Transform">
<Manifest>
<Identity>
<ID>NTServiceBasedDiscoverySample.MP</ID>
<Version>2.0.0.0</Version>
</Identity>
<Name>NTServiceBasedDiscoverySample.MP</Name>
<References>
<Reference Alias="SC">
<ID>Microsoft.SystemCenter.Library</ID>
<Version>6.0.5000.0</Version>
<PublicKeyToken>31bf3856ad364e35</PublicKeyToken>
</Reference>
<Reference Alias="System">
<ID>System.Library</ID>
<Version>6.0.5000.0</Version>
<PublicKeyToken>31bf3856ad364e35</PublicKeyToken>
</Reference>
<Reference Alias="Windows">
<ID>Microsoft.Windows.Library</ID>
<Version>6.0.5000.0</Version>
<PublicKeyToken>31bf3856ad364e35</PublicKeyToken>
</Reference>
<Reference Alias="Health">
<ID>System.Health.Library</ID>
<Version>6.0.5000.0</Version>
<PublicKeyToken>31bf3856ad364e35</PublicKeyToken>
</Reference>
</References>
</Manifest>
<TypeDefinitions>
<EntityTypes>
<ClassTypes>
<ClassType ID="Sample.ServerRole" Accessibility="Public" Abstract="false" Base="Windows!Microsoft.Windows.ComputerRole" Hosted="true" Singleton="false"/>
</ClassTypes>
<RelationshipTypes>
</RelationshipTypes>
</EntityTypes>
<ModuleTypes>
<!--
This data source is composed of three module:
Scheduler - This will kick off the discovery which uses this datasource every N seconds
Probe - This will check if the specified service exists and is not disabled
Mapper - This will cause discovery data to be created
-->
<DataSourceModuleType ID="Sample.Discovery.DataSource" Accessibility="Internal" Batching="false">
<Configuration>
<xsd:element name="IntervalSeconds" type="xsd:unsignedInt" />
</Configuration>
<OverrideableParameters>
<OverrideableParameter ID="IntervalSeconds" Selector="$Config/IntervalSeconds$" ParameterType="int" />
</OverrideableParameters>
<ModuleImplementation Isolation="Any">
<Composite>
<MemberModules>
<DataSource ID="Scheduler" TypeID="System!System.Discovery.Scheduler">
<Scheduler>
<SimpleReccuringSchedule>
<Interval Unit="Seconds">$Config/IntervalSeconds$</Interval>
</SimpleReccuringSchedule>
<ExcludeDates />
</Scheduler>
</DataSource>
<ProbeAction ID="Probe" TypeID="Sample.Discovery.Probe">
<ComputerName>$Target/Property[Type='Windows!Microsoft.Windows.Computer']/NetworkName$</ComputerName>
<!--
This is where we specify which service to look for.
In this case its the Alerter service.
-->
<ServiceName>Alerter</ServiceName>
</ProbeAction>
<ConditionDetection ID="Mapper" TypeID="System!System.Discovery.ClassSnapshotDataMapper">
<ClassId>$MPElement[Name="Sample.ServerRole"]$</ClassId>
<InstanceSettings>
<Settings>
<Setting>
<Name>$MPElement[Name="Windows!Microsoft.Windows.Computer"]/PrincipalName$</Name>
<Value>$Target/Property[Type="Windows!Microsoft.Windows.Computer"]/PrincipalName$</Value>
</Setting>
<Setting>
<!--This is going to be the display name of the object created. As an example I am putting in the computer on which its running-->
<Name>$MPElement[Name="System!System.Entity"]/DisplayName$</Name>
<Value>$Target/Property[Type="Windows!Microsoft.Windows.Computer"]/PrincipalName$</Value>
</Setting>
</Settings>
</InstanceSettings>
</ConditionDetection>
</MemberModules>
<Composition>
<Node ID="Mapper">
<Node ID="Probe">
<Node ID="Scheduler" />
</Node>
</Node>
</Composition>
</Composite>
</ModuleImplementation>
<OutputType>System!System.BaseData</OutputType>
</DataSourceModuleType>
<!--This composite probe module consists of two modules:
1 - Probe module which queries the service control manager for info about the specified service
2 - Condition detection module which checks whether the startup type of the service is not set to "Disabled"
See https://blogs.msdn.com/sampatton/archive/2008/03/10/win32serviceinformation-modules.aspx for more info
-->
<ProbeActionModuleType ID="Sample.Discovery.Probe" Accessibility="Public" Batching="false" PassThrough="false">
<Configuration>
<xsd:element name="ComputerName" type="xsd:string" />
<xsd:element name="ServiceName" type="xsd:string" />
</Configuration>
<ModuleImplementation Isolation="Any">
<Composite>
<MemberModules>
<ProbeAction ID="Probe" TypeID="Windows!Microsoft.Windows.ExistingWin32ServiceInformationProbe">
<ComputerName>$Config/ComputerName$</ComputerName>
<ServiceName>$Config/ServiceName$</ServiceName>
</ProbeAction>
<ConditionDetection ID="CD" TypeID="System!System.ExpressionFilter">
<Expression>
<!--
This is where we specify that we only care if the service startup mode is not disabled
-->
<SimpleExpression>
<ValueExpression>
<XPathQuery Type="Integer">Property[@Name='StartMode']</XPathQuery>
</ValueExpression>
<Operator>NotEqual</Operator>
<ValueExpression>
<Value Type="Integer">4</Value>
</ValueExpression>
</SimpleExpression>
</Expression>
</ConditionDetection>
</MemberModules>
<Composition>
<Node ID="CD">
<Node ID="Probe" />
</Node>
</Composition>
</Composite>
</ModuleImplementation>
<OutputType>System!System.PropertyBagData</OutputType>
<InputType>System!System.BaseData</InputType>
</ProbeActionModuleType>
</ModuleTypes>
</TypeDefinitions>
<Monitoring>
<Discoveries>
<Discovery ID="Sample.Discovery" Enabled="true" Target="Windows!Microsoft.Windows.Computer" ConfirmDelivery="false" Remotable="true" Priority="Normal">
<Category>Discovery</Category>
<DiscoveryTypes>
<DiscoveryClass TypeID="System!System.Entity">
<Property TypeID="System!System.Entity" PropertyID="DisplayName"/>
</DiscoveryClass>
<DiscoveryClass TypeID="Sample.ServerRole"/>
</DiscoveryTypes>
<DataSource ID="DiscoveryDataSource" TypeID="Sample.Discovery.DataSource">
<IntervalSeconds>120</IntervalSeconds>
</DataSource>
</Discovery>
</Discoveries>
</Monitoring>
<Presentation>
<Views>
<View ID="Sample.View" Accessibility="Public" Enabled="true" Target="Sample.ServerRole" TypeID="SC!Microsoft.SystemCenter.StateViewType" Visible="true">
<Category>Operations</Category>
<Criteria>
<InMaintenanceMode>false</InMaintenanceMode>
</Criteria>
<Presentation>
<ColumnInfo Index="0" SortIndex="0" Width="100" Grouped="false" Sorted="true" IsSortable="true" Visible="true" SortOrder="Descending">
<Name>State</Name>
<Id>Sample.ServerRole</Id>
</ColumnInfo>
<ColumnInfo Index="1" SortIndex="-1" Width="100" Grouped="false" Sorted="false" IsSortable="true" Visible="true" SortOrder="Ascending">
<Name>Maintenance Mode</Name>
<Id>InMaintenanceMode</Id>
</ColumnInfo>
<ColumnInfo Index="2" SortIndex="-1" Width="100" Grouped="false" Sorted="false" IsSortable="true" Visible="true" SortOrder="Ascending">
<Name>Name</Name>
<Id>Name</Id>
</ColumnInfo>
<ColumnInfo Index="3" SortIndex="-1" Width="100" Grouped="false" Sorted="false" IsSortable="true" Visible="true" SortOrder="Ascending">
<Name>Path</Name>
<Id>Path</Id>
</ColumnInfo>
<ColumnInfo Index="4" SortIndex="-1" Width="100" Grouped="false" Sorted="false" IsSortable="true" Visible="false" SortOrder="Ascending">
<Name>Display Name</Name>
<Id>DisplayName</Id>
</ColumnInfo>
</Presentation>
<Target />
</View>
</Views>
<Folders>
<Folder ID="Sample.Folder" Accessibility="Public" ParentFolder="SC!Microsoft.SystemCenter.Monitoring.ViewFolder.Root" />
</Folders>
<FolderItems>
<FolderItem ElementID="Sample.View" Folder="Sample.Folder" />
</FolderItems>
</Presentation>
<LanguagePacks>
<LanguagePack ID="ENU" IsDefault="true">
<DisplayStrings>
<DisplayString ElementID="NTServiceBasedDiscoverySample.MP">
<Name>NT Service Based Discovery Sample MP</Name>
</DisplayString>
<DisplayString ElementID="Sample.ServerRole">
<Name>Sample Server Role</Name>
</DisplayString>
<DisplayString ElementID="Sample.Discovery">
<Name>Sample NT Service based discovery</Name>
</DisplayString>
<DisplayString ElementID="Sample.Folder">
<Name>Sample MP</Name>
</DisplayString>
<DisplayString ElementID="Sample.View">
<Name>Sample objects state (will be unmonitored as there are no monitors in the MP)</Name>
<Description />
</DisplayString>
</DisplayStrings>
</LanguagePack>
</LanguagePacks>
</ManagementPack>
Comments
- Anonymous
April 03, 2008
Thanks for this MP! It is very useful. Keep them coming. -T - Anonymous
April 03, 2008
This is great info Boris. Keep it coming. //Pontus Blomqvist - Anonymous
April 06, 2008
amazing man, keep up the good work.. ill go checking on it later - Anonymous
April 06, 2008
Hey,I was wondering, how do you work with this,I've tried importing this MP and putting it in authoring console, both of the tries output errors, please let me know, this looks very promising and helpful, and i have much use of this mp xml!Thanks mate! - Anonymous
April 09, 2008
Copy the xml code from Boris and past it into notepad. Save the document "NTServiceBasedDiscoverySample.MP.xml" then you can open it with the Authoring Console.//Pontus Blomqvist - Anonymous
April 09, 2008
Copy the xml code from Boris and paste it into Notepad. Save the document "NTServiceBasedDiscoverySample.MP.xml" and then you can open it with the Authoring Console.//Pontus Blomqvist - Anonymous
April 11, 2008
Boris great sample.... Keep up the great work.... - Anonymous
June 22, 2008
Is it possible to do the wildcard on this service discovery? I have multiple services with the first couple characters are the same. Thanks. - Anonymous
October 22, 2008
Hello Boris,We have implemented the service-based discovery and it working great as long as our other server admins name the service exactly the same. My question is can wildcards be used at all, such as Alert* or Alert% in order to discover servers that contain services with variations of that name? Thank you. - Anonymous
November 01, 2008
Hey Boris, thanks for this post! I was wondering if you could advise how I would go about modifying this discovery to target Microsoft.Windows.Server and ignore discovery on instances where IsVirtualNode = true? I'm not exactly sure where the expression for this would go?Thanks for your help in advance!-Colin - Anonymous
November 01, 2008
You need to add a condition detection module and check the property value. - Anonymous
November 02, 2008
I added the following condition detection module to be a member module of the sample.discovery.datasource as follows:<ConditionDetection ID="IsVirtual" TypeID="System!System.ExpressionFilter"> <Expression> <SimpleExpression> <ValueExpression> <XPathQuery>$Config/IsVirtual$</XPathQuery> </ValueExpression> <Operator>NotEqual</Operator> <ValueExpression> <XPathQuery>true</XPathQuery> </ValueExpression> </SimpleExpression> </Expression> </ConditionDetection>I get the following error in the event log of the agent attempting to run the module:The Microsoft Operations Manager Expression Filter Module could not initialize properly. The passed in expression could be invalid.Error: 0x80070057Can you help? - Anonymous
November 02, 2008
I got it finally. I did not need the $config values, just the $target property in the expression filter and it worked. Thanks! - Anonymous
November 02, 2008
Great! I am glad to hear you were able to get this to work. - Anonymous
February 24, 2009
The comment has been removed - Anonymous
February 25, 2009
The comment has been removed