Wednesday, May 28, 2008

Example SNMP Management Pack for SCOM 2007

I've finished creating my first SNMP management pack for Microsoft System Center Operations Manager 2007 (SCOM/OpsMgr) using Raphael Burri's SNMP Discovery Provider. For some reason Microsoft failed to include a means of identifying different types of SNMP devices in OpsMgr (called a Discovery). Thankfully Raphael has written a quick MP to provide this functionality.

Here is a link to a simple discovery only template XML.
Here is a link to my full Ecosaire Air Conditioner SNMP Management Pack. *Note that this is provided as an example only. If you have an Ecosaire AC unit and want to use my MP, let me know and I'll give you a copy of the required SNMP config files for the Ecosaire unit.

If you take a look at the discovery only XML, you can see the following required sections:

First we see the reference to Raphael's SNMP Discovery provider. Obviously you need to have this MP installed on your OPS server.

<reference alias="CustomSNMP">

<id>Custom.SNMP.Library</id>
<version>1.0.0.1</version>
<publickeytoken>e5c80663d573f08c</publickeytoken>
</reference>


Next take a look at the ClassTypes sections. In the ClassTypes section, we identify the main class. Notice how its base class is Microsoft.SystemCenter.NetworkDevice.

<ClassTypes>
<ClassType ID="RBH.Ecosaire.AC.Management.Pack.SNMPDevice" Accessibility="Internal" Abstract="false" Base="NetLib!Microsoft.SystemCenter.NetworkDevice" Hosted="false" Singleton="false" />
</ClassTypes>

A few lines down you will find the corresponding Discovery section where we will discover our new class.

<DiscoveryTypes>
<DiscoveryClass TypeID="RBH.Ecosaire.AC.Management.Pack.SNMPDevice">
<Property TypeID="System!System.Entity" PropertyID="DisplayName" />
</DiscoveryClass>
</DiscoveryTypes>


Next you'll see the DataSource section of the discovery. Notice that the TypeID is set to use the CustomSNMP from Raphael's management pack.

<DataSource ID="DS" TypeID="CustomSNMP!Custom.SnmpQuery.FilteredOIDDiscoveryProvider">

Inside the DataSource you'll see the Interval (how often to run the discovery) along with some base SNMP properties. These base properties are set by the Microsoft Network Device management pack on any SNMP device you've added to your OpsMgr server. We can just use the previously discovered properties for those values here.

<Interval>3600</Interval>
<IP>$Target/Property[Type="NetLib!Microsoft.SystemCenter.NetworkDevice"]/IPAddress$</IP>
<CommunityString>$Target/Property[Type="NetLib!Microsoft.SystemCenter.NetworkDevice"]/CommunityString$</CommunityString>
<Version>$Target/Property[Type="NetLib!Microsoft.SystemCenter.NetworkDevice"]/Version$</Version>

The SnmpVarBinds section identifies the SNMP Object Identifier (OID) that we are going to check. If you think back to the Windows Registry based discovery wizard, you identify the registry key in one section, then create an expression to check the value of that key in a second section. We use the same concept here.

<SnmpVarBinds>
<SnmpVarBind>
<OID>1.3.6.1.2.1.1.2.0</OID>
<Syntax>0</Syntax>
<Value VariantType="8" />
</SnmpVarBind>
</SnmpVarBinds>


The OID listed above is a generic OID that will respond to an SNMP GET with the specific OID identifier of that device. For example, if I do an SNMP GET against my air conditioner it will always return 1.3.6.1.4.1.8072.3.2.10. Doing the same request against any of my Cisco 6509 switches will always return 1.3.6.1.4.1.9.1.283.

Next you will see the Expression section. This is where we perform the actual query to determine if the SNMP object is the right type. As mentioned above, we are checking to see if SNMPGET(1.3.6.1.2.1.1.2.0) == 1.3.6.1.4.1.8072.3.2.10.

<Expression>
<SimpleExpression>
<ValueExpression> <XPathQuery>/DataItem/SnmpVarBinds/SnmpVarBind[OID='1.3.6.1.2.1.1.2.0'][1]/Value</XPathQuery>
</ValueExpression>
<Operator>Equal</Operator>
<ValueExpression>
<Value Type="String">1.3.6.1.4.1.8072.3.2.10</Value>
</ValueExpression>
</SimpleExpression>
</Expression>


Note that if this is not specific enough for you, Raphael demonstrates how to query a specific OID and do a regex expression in his documentation. For example, if you need to distinguish between SNMP devices by some other means you might want to check some other SNMP value.

The ClassID and InstanceSettings sections round out the required sections. This is similar to the last page of the Registry Discovery wizard where you map discovered values onto properties of the class. Since this is just a demonstration, this section only includes the required DisplayName and IPAddress properties.

<ClassId>$MPElement[Name="RBH.Ecosaire.AC.Management.Pack.SNMPDevice"]$</ClassId>
<InstanceSettings>
<Settings>
<Setting>
<Name>$MPElement[Name="NetLib!Microsoft.SystemCenter.NetworkDevice"]/IPAddress$</Name>
<Value>$Target/Property[Type="NetLib!Microsoft.SystemCenter.NetworkDevice"]/IPAddress$</Value>
</Setting>
<Setting>
<Name>$MPElement[Name="System!System.Entity"]/DisplayName$</Name>
<Value>$Target/Property[Type="System!System.Entity"]/DisplayName$</Value>
</Setting>
</Settings>
</InstanceSettings>


With this discovery, I can now distinguish this SNMP device from all the other SNMP devices on my system.

Screenshots:

State View showing only my discovered SNMP device



Performance View showing only my discovered SNMP device stats



Authoring Window showing Monitors for my SNMP class



Add Rule Wizard in the Console showing the Rule target as my new class



I'm lazy and like to use the GUI to avoid working in the XML as much as possible. In my experience, once I have the base discovery added to the management pack, using the GUI tools to add rules, monitors, etc. works as expected. The functionality is different between the Authoring Console and the Operations Console, so if you can't do something in one try it in the other. For example, I was able to create an SNMP Trap Event Collection rule in the Operations Console, but I couldn't add an Alert onto that rule without using the Authoring Console.

Finally, some tips on creating your own rules/monitors.

When creating alerts for your rules and monitors, you can use the following variables (subsituting your own OIDs).

For a Rule:
$Data/EventData/DataItem/SnmpVarBinds/SnmpVarBind[OID='1.3.6.1.4.1.9839.2.1.2.2.0'][1]/Value$

For a Monitor:
$Data/Context/SnmpVarBinds/SnmpVarBind[OID='1.3.6.1.4.1.9839.2.1.2.2.0'][1]/Value$

When creating an expression inside a monitor, use this variable for the parameter name:
/DataItem/SnmpVarBinds/SnmpVarBind[1]/Value

For more help with SNMP Monitors check out David Allen's Guide to SNMP Probe Based Monitors. For examples, check out the completed management pack above.

This sample management pack is licensed under the Creative Commons Attribution 3.0 License. To view a copy of this license, visit http://creativecommons.org/licenses/by/3.0/ or send a letter to Creative Commons, 543 Howard Street, 5th Floor, San Francisco, California, 94105, USA.

4 comments:

Martin said...

Hi Scott,
Your example got me started with an MP for the air conditioner at our site thank you. I notice the "Path" column of the performance graphs is empty. How would I populate the path column with the device name please?
Regards
Martin

Tolga BALCI said...
This comment has been removed by the author.
Tolga BALCI said...

Hi Scott,

Thank you very much for the wonderful post. Just a quick question: how do you display the monitor graphically under the diagram view?

Thanks!
Tolga

Emma Kille said...

Hi Scott,
Thanks a lot for this awesome post! What's your next?