SCOM: Advanced SNMP Monitoring Part IV: Making the Cisco MP SP1 Compatible
September 17, 2009 3 Comments
As previously mentioned, the Cisco Management Pack that I have been describing in the past several posts is specific to OpsMgr R2, due to its reliance on the capability of the System.SnmpProbe’s function to return multiple items in an SNMP walk, which is a feature introduced in R2. My intention was to design the management pack so that it could easily be made SP1 compatible by substituting the discovery methodology, but keeping the classes and monitoring objects intact. I am still doing more testing to finalize the SP1 version, but in this post, I am going to introduce the discovery methods that I have implemented for SP1 compatibility.
In general, when dealing with SNMP objects stored in tables, options in SCOM 2007 SP1 are a bit limited. If the table objects are static, rules could be configured targeting specific OID’s, but this is unlikely to be a common scenario. Another option (and a quite good one) would be to segregate monitoring duties between SCOM (for servers and applications) and a task-specific SNMP monitoring tool like SolarWinds or JalaSoft for SNMP device monitoring. But for the purposes of this management pack, the option I pursued involves wrapping an external SNMP provider in WSH scripts to perform the discovery. I chose to use the WMI provider because of its easy use in VBscripts and object-oriented capabilities, but something like the Net-SNMP binaries could be called with ShellExec methods in a vbs script to accomplish the same goal.
Before I get into the use of the WMI SNMP provider in this MP, there is some background information that should be discussed. Firstly, when the WMI SNMP provider is installed, it includes support only for the RFC-1213 MIB. In order to use the WMI SNMP provider for OID’s not in the RFC-1213 MIB, the MIB files must be converted to MOF files with smi2smir.exe and then imported with mofcomp.exe. This can get a bit tricky, largely depending on how well constructed the vendor’s MIB is and the dependencies of the MIB. Once these steps are completed, the WMI SNMP provider exposes SNMP objects as collections that can be accessed natively in VBscripts. However, the WMI provider is not terribly scalable and when overloaded with requests, WMI will cease to function in a timely fashion. I had done some testing with using the WMI SNMP provider for rules and monitors, but decided against this approach due to the ease with which the provider can be overloaded when monitoring a handful of objects with reasonably aggressive frequencies. On the other hand, discoveries are not as time-sensitive as monitors/rules and don’t need to run as frequently, so by using the WMI SNMP provider for discoveries, and the System.SnmpProbe provider for monitors and rules, this hybrid approach should remain pretty scalable.
Installing the WMI SNMP Provider
The WMI SNMP Provider can be installed through the Control Panel’s Add/Remove Programs (or Program and Features for 2008) applet, by select Add/Remove Windows Features, then selecting the WMI SNMP Provider (and SNMP if it isn’t installed) under Management and Monitoring Tools.
Registering MIB’s with the WMI Provider
To register MIBS with the WMI SNMP Provider, they must first be converted to MOF files with smi2smir.exe and then imported with mofcomp.exe. Both of these can be found under the %systemroot%\system32\wbem\ directory, with smi2smir.exe being in the \snmp subdirectory. If the MIB file has dependencies on other MIBs, they must also be available and specified in the smi2smir.exe command. To illustrate this, to create an MOF file for the CISCO-ENVMON-MIB, the command ends up as:
%SYSTEMROOT%\system32\wbem\snmp\smi2smir.exe /g CISCO-ENVMON-MIB.mib CISCO-SMI.mib > CISCO-ENVMON.MOF
Then the mofcomp.exe import can be run with:
For the purposes of this management pack, all WMI SNMP discovered objects are available in the RFC-1213, Cisco-EnvMon, and Cisco-Memory-Pool mibs, so only two MIBs have to be imported. The monitors/rules will continue to use the System.SnmpProbe, which can target an OID without importing the MIB.
Querying the Snmp Provider
Once the MOF is registered with the WMI SNMP provider, a VBScript can instantiate the provider and represent an SNMP table as a collection object, such as:
Set objWMILocator = CreateObject(“WbemScripting.SWbemLocator”)
Set objWMIServices = objWMiLocator.ConnectServer(“”,”root\snmp\localhost”)
Set objWmiNamedValueSet = CreateObject(“WbemScripting.SWbemNamedValueSet”)
objWmiNamedValueSet.Add “AgentAddress”, cstr(DeviceIP)
objWmiNamedValueSet.Add “AgentReadCommunityName”, cstr(CommStr)
Set colPowerSupplies = objWmiServices.InstancesOf(“SNMP_CISCO_ENVMON_MIB_ciscoEnvMonSupplyStatusTable”, , objWMINamedValueset)
For each objItem in colPowerSupplies
sDesc = objItem.ciscoEnvMonSupplyStatusDescr
nIndex = objItem.ciscoEnvMonSupplyStatusIndex
By using this in a script discovery probe, the values retrieved from WMI SNMP can be used to discover objects and properties all in one script. Continuing with teh Cisco power supply example, the objectdiscovery portion of the script would look something like:
set oInst = oDiscoveryData.CreateClassInstance(“$MPElement[Name=’CiscoSNMP.Class.CiscoDevice.PowerSupply’]$”)
call oInst.AddProperty(“$MPElement[Name=’MicrosoftSystemCenterNetworkDeviceLibrary!Microsoft.SystemCenter.NetworkDevice’]/IPAddress$”, DeviceIP)
call oInst.AddProperty(“$MPElement[Name=’CiscoSNMP.Class.CiscoDevice.PowerSupply’]/Index$”, cdbl(nIndex))
call oInst.AddProperty(“$MPElement[Name=’System!System.Entity’]/DisplayName$”, sDesc)
At the risk of going too far off on a tangent, I’ve come upon a few idiosyncrasies in working with the WMI SNMP provider for this MP. The first peculiarity is that the index value in the Cisco EnvMon tables is properly populated. When browsing the Cisco EnvMon objects with a MIB browsing utility or using the System.SnmpProbe, these index values are not populated, so I’m not sure why it works with WMI SNMP and not these other more traditional methods. The second peculiarity is that I have found that in some cases, octetstrings are not properly converted to text strings when using the WMI SNMP Provider. Specifically, the names of some of the Cisco EnvMon objects would be returned as hex strings for some objects and text strings for others. To work around this issue, I added a little function in the discovery scripts that attempts to convert the names from hex to strings, and only uses the converted value if no errors were trapped in the conversion (which should indicate that it is actually a hex string). This function looks like:
on error resume next
sOutput = “”
For x = 1 To len(str) Step 2
sChar = Chr(Clng(“&h” & Mid(str,x,2)))
sOutput = sOutput & sChar
if err.number = 0 then
HexToString = sOutput
HexToString = str
Other than the discoveries, everything else in the MP should remain pretty much unchanged (unless something unexpected is exposed in testing).