News

SCOM MPs: Nicks and Nags of registry discoveries

For better monitoring of software SOTEC provides management packs for System Center Operations Management (SCOM) from Microsoft. In addition to our own products we also author management packs for existing third party software. However authoring those management packs can be tricky at times.

Recently I ran into a problem with my usual way of writing a discovery. My prefered way to discover an installed application was to query the registry for the right value. An example of the discovery script (VBScript) is shown below.

SourceId = WScript.Arguments(0)
ManagedEntityId = WScript.Arguments(1)
sComputerName = WScript.Arguments(2)
const HKEY_LOCAL_MACHINE = &H80000002
Set oAPI = CreateObject("MOM.ScriptAPI")
Set oDiscoveryData = oAPI.CreateDiscoveryData(0, SourceId, ManagedEntityId)
Set oReg=GetObject("winmgmts:{impersonationLevel=impersonate}!\\" & sComputerName & "\root\default:StdRegProv")
const strKeyPath = "SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall"
const strValueName = "DisplayName"
const strValue = "Application Name"
oReg.EnumKey HKEY_LOCAL_MACHINE, strKeyPath, arrSubKeys
dim count
count = 1
For Each subkey In arrSubKeys
strKeyPathNew = strKeyPath & "\" & subkey
ret = oReg.GetStringValue(HKEY_LOCAL_MACHINE,strKeyPathNew,strValueName,displayName)
If (ret = 0) Then
if (InStr(displayName,strValue) > 0) Then
' get version
ret = oReg.GetStringValue(HKEY_LOCAL_MACHINE,strKeyPathNew,"DisplayVersion",displayVersion)
if (ret = 0) Then
Set oInstance = oDiscoveryData.CreateClassInstance("$MPElement[Name='MP.Object.Name']$")
oInstance.AddProperty "$MPElement[Name='Windows!Microsoft.Windows.Computer']/PrincipalName$",
sComputerName
oInstance.AddProperty "$MPElement[Name='MP.Object.Name']/Version$", displayVersion
oDiscoveryData.AddInstance(oInstance)
End If
End If
Else
Err.Clear
End If
Next
oAPI.Return(oDiscoveryData)

However this method of discovery proved to be unreliable when you’re monitoring applications in an environment where you have Windows Vista and Windows 7 in use. The registry values of the installed software seems to be randomly distributed in the Keys for 64Bit and 32Bit for these operation systems. Instead of searching the subkeys for each architechture I decided to use the WMI (Windows Management Interface). To be more flexible with the discovery I wrapped it into VBScript. You can see an example of the new discovery script below.

SourceId = WScript.Arguments(0)
ManagedEntityId = WScript.Arguments(1)
sComputerName = WScript.Arguments(2)

Set oAPI = CreateObject("MOM.ScriptAPI")
Set oDiscoveryData = oAPI.CreateDiscoveryData(0, SourceId, ManagedEntityId)

strSoftwareName = """Software Name"""
Set objWMIService = GetObject("winmgmts{impersonationLevel=impersonate}!\\" & sComputerName & "\root\cimv2")
Set colSoftware = objWMIService.ExecQuery("Select * from Win32_Product WHERE Name = " & strSoftwareName)
For Each objItem in colSoftware
Set oInstance = oDiscoveryData.CreateClassInstance("$MPElement[Name='MP.Object.Name']$")
With oInstance
.AddProperty "$MPElement[Name='Windows!Microsoft.Windows.Computer']/PrincipalName$", sComputerName
.AddProperty "$MPElement[Name='MP.Object.Name']/Version$", objItem.Version
End With
oDiscoveryData.AddInstance(oInstance)
Next
oAPI.Return(oDiscoveryData)