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://gallery.technet.microsoft.com/SCOM-Custom-Network-device-b2b16959