Writing a custom class for your network devices




While there is built in monitoring for network devices in SCOM – there are scenarios where we want to create custom classes for specific network device types.  Perhaps you want to create your own SNMP based polling monitors, and run them against specific network device types, such as a specific firewall brand, or router.

Creating your custom class is quite simple – based on a common System OID that the devices will share.

This concept was documented by Daniele Grandini, https://nocentdocent.wordpress.com/2013/05/21/discovery-identifying-the-device-snmp-mp-chap-2-sysctr-scom/  I am simply taking it a step further, in publishing a full MP example for you to work by.


In the first step – we need to define the MP manifest, and add a reference to the System.NetworkManagement.Library since we will be targeting the “Node” class from that MP:


<Manifest> <Identity> <ID>Example.Network</ID> <Version></Version> </Identity> <Name>Example Network</Name> <References> <Reference Alias="Network"> <ID>System.NetworkManagement.Library</ID> <Version>7.1.10226.0</Version> <PublicKeyToken>31bf3856ad364e35</PublicKeyToken> </Reference> <Reference Alias="Windows"> <ID>Microsoft.Windows.Library</ID> <Version>6.0.4837.0</Version> <PublicKeyToken>31bf3856ad364e35</PublicKeyToken> </Reference> <Reference Alias="System"> <ID>System.Library</ID> <Version>6.0.4837.0</Version> <PublicKeyToken>31bf3856ad364e35</PublicKeyToken> </Reference> <Reference Alias="SC"> <ID>Microsoft.SystemCenter.Library</ID> <Version>6.0.4837.0</Version> <PublicKeyToken>31bf3856ad364e35</PublicKeyToken> </Reference> <Reference Alias="Health"> <ID>System.Health.Library</ID> <Version>6.0.4837.0</Version> <PublicKeyToken>31bf3856ad364e35</PublicKeyToken> </Reference> </References> </Manifest>


Next, we will define our class.  We will use Node as the Base Class.


<TypeDefinitions> <EntityTypes> <ClassTypes> <ClassType ID="Example.Network.Device" Accessibility="Public" Abstract="false" Base="Network!System.NetworkManagement.Node" Hosted="false" Singleton="false" Extension="false" /> </ClassTypes> </EntityTypes>


Then – a datasource module that will be used for each discovery for a unique device type.  We try to make datasource modules reusable – and have each workflow simply pass the necessary items instead of hard coding them:


<ModuleTypes> <DataSourceModuleType ID="Example.Network.Device.Discovery.DS" Accessibility="Internal" Batching="false"> <Configuration> <xsd:element minOccurs="1" name="IntervalSeconds" type="xsd:integer" /> <xsd:element minOccurs="0" name="SyncTime" type="xsd:string" /> <xsd:element name="OID" type="xsd:string" /> <xsd:element name="DisplayName" type="xsd:string" /> <xsd:element name="Model" type="xsd:string" /> <xsd:element name="Vendor" type="xsd:string" /> </Configuration> <OverrideableParameters> <OverrideableParameter ID="IntervalSeconds" ParameterType="int" Selector="$Config/IntervalSeconds$"/> <OverrideableParameter ID="SyncTime" ParameterType="string" Selector="$Config/SyncTime$"/> </OverrideableParameters> <ModuleImplementation Isolation="Any"> <Composite> <MemberModules> <DataSource ID="Scheduler" TypeID="System!System.Discovery.Scheduler"> <Scheduler> <SimpleReccuringSchedule> <Interval>$Config/IntervalSeconds$</Interval> <SyncTime>$Config/SyncTime$</SyncTime> </SimpleReccuringSchedule> <ExcludeDates /> </Scheduler> </DataSource> <ConditionDetection ID="MapToDiscovery" TypeID="System!System.Discovery.FilteredClassSnapshotDataMapper"> <Expression> <SimpleExpression> <ValueExpression> <Value>$Target/Property[Type="Network!System.NetworkManagement.Node"]/SystemObjectID$</Value> </ValueExpression> <Operator>Equal</Operator> <ValueExpression> <Value Type="String">$Config/OID$</Value> </ValueExpression> </SimpleExpression> </Expression> <ClassId>$MPElement[Name='Example.Network.Device']$</ClassId> <InstanceSettings> <Settings> <Setting> <Name>$MPElement[Name='System!System.Entity']/DisplayName$</Name> <Value>$Config/DisplayName$</Value> </Setting> <Setting> <Name>$MPElement[Name='Network!System.NetworkManagement.Node']/DeviceKey$</Name> <Value>$Target/Property[Type="Network!System.NetworkManagement.Node"]/DeviceKey$</Value> </Setting> <Setting> <Name>$MPElement[Name='Network!System.NetworkManagement.Node']/Model$</Name> <Value>$Config/Model$</Value> </Setting> <Setting> <Name>$MPElement[Name='Network!System.NetworkManagement.Node']/Vendor$</Name> <Value>$Config/Vendor$</Value> </Setting> </Settings> </InstanceSettings> </ConditionDetection> </MemberModules> <Composition> <Node ID="MapToDiscovery"> <Node ID="Scheduler" /> </Node> </Composition> </Composite> </ModuleImplementation> <OutputType>System!System.Discovery.Data</OutputType> </DataSourceModuleType> </ModuleTypes>


The above datasource is probably the most complicated part of this.  We are creating a composite DS, combining the System.Discovery.Scheduler module, with the System.Discovery.FilteredClassSnapshotDataMapper module.

The scheduler is simple – we pass in the interval.

The System.Discovery.FilteredClassSnapshotDataMapper is more complicated – it basically allows you to create a filtered discovery of existing objects, based on an expression matching on a class property.  In this case, if the System OID equals a specific OID we pass in the discovery, it is a match and we will create an instance of the class.  Since all your desired network devices will share a common System OID, this is the perfect property to match on.

In this DS, I also included the ability to pass the Model and Vendor – you can inherit whatever is present from the Node property if the discovered network device is CERTIFIED, or provide your own custom ones in the discovery, if GENERIC.


Last – we define our discovery.


<Discoveries> <Discovery ID="Example.Network.Device.Discovery" Enabled="true" ConfirmDelivery="false" Remotable="true" Priority="Normal" Target="Network!System.NetworkManagement.Node"> <Category>Discovery</Category> <DiscoveryTypes> <DiscoveryClass TypeID="Example.Network.Device" /> </DiscoveryTypes> <DataSource ID="DS" TypeID="Example.Network.Device.Discovery.DS"> <IntervalSeconds>14400</IntervalSeconds> <SyncTime /> <OID>.</OID> <DisplayName>$Target/Property[Type="Network!System.NetworkManagement.Node"]/sysName$</DisplayName> <Model>$Target/Property[Type="Network!System.NetworkManagement.Node"]/Model$</Model> <Vendor>$Target/Property[Type="Network!System.NetworkManagement.Node"]/Vendor$</Vendor> </DataSource> </Discovery> </Discoveries>


The discovery is simple – we simply call the datasource module, and pass any necessary parameters to the discovery.  In this case, each discovery will include a Class Type which we are trying to discover, a System OID for the device type/class, map the existing display name, and then include the model and vendor.  You can hard code the model and vendor as text in each discovery if desired.  The OID in my example is for a Linux system, you will need to change this.

You should add multiple discoveries for each different class type you want to create.  These can be placed in unique MP’s for each network device type, or combine them all into one MP, up to you.


You can download a copy of the entire example mp here:


Comments (1)

  1. Jason says:

    Its a good base to work from to discover the device. A novice could use this as their base and then simply create basic SNMP probes etc in the SCOM GUI console and target this class, saving the probes in this same management pack. They will get alerts, health explorer status and performance etc.
    I have found its not enough if you want to do something decent.
    You need to target the base class for further discoveries like the article you referenced.
    Also, the OTB Monitor types have issues because your parent class can only ever be un-hosted off the “Node” class. The Monitor types are expecting to drill down to the root hosted class and return the OID, PortNumber, SNMPAddress, VirtualCommunitySuffix and SNMPVersion as properties in order to make the probe / walk but they can only ever get as far as your base class.
    The work around is simply add the properties above into your parent class and then in the discovery simply map these MP element properties from same properties in the Node you are discovering.
    This doesn’t solve all problems. People may still need to create their own Monitor types. MSDN provide some good examples to work off but it needs time to learn. Patience is the key.

Skip to main content