Menu Close

Writing a custom class for your network devices


image

 

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>1.0.0.2</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>.1.3.6.1.4.1.8072.3.2.10</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:

https://github.com/thekevinholman/CustomNetworkDeviceClass

5 Comments

  1. Jon Haugen

    Hi Kevin,

    I want to create a similar MP, but instead use our CMDB MP which basicly extends the Windows Computer properties.
    The goal here is to take one property from the CMDB MP which is called Implementations, and create a set of classes based on the name of the implementation.

    As a user of MP author I’m not too familiarized with handling all the components which a MP is built upon.
    When creating the DataSource ModuleType and defining the System.Discovery.FilteredClassSnapshotDataMapper, do you have any tips on which target I should use?

  2. Jon Haugen

    Thanks for the reply, the end goal here is to create a set of classes based on the property we have named “Implementations” which is the definition of our applications. From there I can add the monitors for each Application.

    So the simplified flow would be:

    1. Create a seed class based on the servers which has the implementation property, that is already discovered in our CMDB MP.
    2. Create a class/discovery for each application, which targets the seed discovery. For example Visma Business, and another one for Visma Global
    3. Create monitors that target each invidual application classes.

    The point here is that our CMDB MP is really heavy, and I dont want SCOM to run two discoveries towards the CMDB as I already have the data in SCOM. Hope this will clearify.

    • Kevin Holman

      In that case, what I would do is target the extended class with your application discovery, and create an instance of each class, if the property equals “Visma Business”, etc…. Now you have your application classes published, and no need to go back to the CMDB.

  3. Andy Perry

    Firstly, I know this is an old thread now, so apologies for that.

    We have a scenario at the moment where we need to monitor some storage devices. We can add the devices as Network devices in the usual way, but the issue is because it doesn’t find the Device Key where it is expecting it to, we have been told that the discovery randomly searches for all MAC addresses and then picks the first on the list.

    The issue we are having is that (or we have been told that) when the discovery runs each time, because the list of MAC addresses comes back with a different one in “first place”, SCOM then adds another Network Device, essentially duplicating the same device for each MAC address related with the device.

    Because this is not coming back as CERTIFIED, MS advised that there is little that can be done support wise, although they have agreed to discuss with PG (but not hopeful). The suggestion from the PG was to create our own pack/discovery, which is fine, but we still have the same issue as it will ultimately have a base of the Network Device Node.

    Would it be possible to use this example to basically filter as you say, but in a way that defines the uniqueness further based on the name and the IP being the same? The idea being so that in our custom class, we don’t end up with the duplications.

    Thanks

Leave a Reply

Your email address will not be published.