Updated: April 16, 2010
Applies To: System Center Operations Manager 2007
Discovery scripts are used when complex logic is required for discovery of a particular class or relationship, or when required information cannot be accessed from the registry or WMI. The script collects data from information on the agent and creates discovery data by using the MOM.ScriptAPI object that is installed with the Operations Manager 2007 agent.
Creating Discovery Scripts
Discovery scripts may be written in any script language that can access the MOM.ScriptAPI object. The most common languages used are VBScript, JScript, and Windows PowerShell. Discovery scripts that use VBScript or Jscript can be created by using modules in management pack libraries and wizards in the Authoring console. Modules are available for discovery scripts that are written in Windows PowerShell in Operations Manager R2 but are not supported by wizards in the Authoring console. A custom discovery would have to be created using the appropriate module.
Management packs that require support by Operations Manager 2007 SP1 cannot use the Windows PowerShell modules, because they are only installed with the Operations Manager R2 agent. Discovery scripts that use Windows PowerShell can be created by using modules that run a command and configure them to build the powershell.exe command line.
Discovery data must include the GUID of the target object that the discovery is running against and the GUID of the discovery itself. The value for each is required when the script calls the CreateDiscoveryData method. They will be unknown when the script is written. However, they can be accessed through variables and sent into the script through arguments. The GUID of the discovery is accessed by the $MPElement$ variable, whereas the GUID of the target object is accessed with $Target/Id$.
Other arguments can be sent into the script as required for the particular discovery.
Basic Script Structure
The following sample shows a discovery script with the following characteristics.
The script discovers a single instance of a class named MyMP.MyClass.
The class is hosted by Windows Computer.
The class has a key property named Name.
The class has a non-key property named Version.
SourceId = WScript.Arguments(0) ManagedEntityId = WScript.Arguments(1) sComputerName = WScript.Arguments(2) Set oAPI = CreateObject("MOM.ScriptAPI") Set oDiscoveryData = oAPI.CreateDiscoveryData(0, SourceId, ManagedEntityId) Set oInstance = oDiscoveryData.CreateClassInstance("$MPElement[Name='MyMP.MyClass']$") oInstance.AddProperty "$MPElement[Name='Windows!Microsoft.Windows.Computer']/PrincipalName$", sComputerName oInstance.AddProperty "$MPElement[Name='MyMP.MyClass']/Name$", "svr01.contoso.com" oInstance.AddProperty "$MPElement[Name='MyMP.MyClass']/Version$", "1.0" oDiscoveryData.AddInstance(oInstance) oAPI.Return(oDiscoveryData)
Details of each section of the script are discussed here.
SourceId = WScript.Arguments(0) ManagedEntityId = WScript.Arguments(1) sComputerName = WScript.Arguments(2)
The first two lines of the script accept the GUID for the discovery and the target object. These lines should stay unchanged in most discovery scripts, but they will typically be followed by other variables accepting arguments specific to the particular script. The next line gets a value for the computer name that is used for the key property of the hosting Windows Computer object.
Set oAPI = CreateObject("MOM.ScriptAPI") Set oDiscoveryData = oAPI.CreateDiscoveryData(0, SourceId, ManagedEntityId)
The next two lines create a discovery data object by using the provided GUIDs. These lines will also be unchanged in most discovery scripts. The main purpose of the rest of the script will be to add detail to the discovery data object by using data collected from the agent computer.
Set oInstance = oDiscoveryData.CreateClassInstance("$MPElement[Name='MyMP.MyClass']$")
After the discovery data object is created, it can be used to create a new class instance. This requires an $MPElement variable that uses the name of the class. This variable translates to the appropriate GUID representing the class. This line would presumably be preceded by code that would collect data from the agent computer to determine whether one or more instances should be created in addition to populating variables for the instances properties that are populated with the following lines.
oInstance.AddProperty "$MPElement[Name='Windows!Microsoft.Windows.Computer']/PrincipalName$", sComputerName oInstance.AddProperty "$MPElement[Name='MyMP.MyClass']/Name$", sName oInstance.AddProperty "$MPElement[Name='MyMP.MyClass']/Version$", sVersion
With the instance now created, its properties can be populated. Any key properties of the class being discovered and the key properties of any of its parents must be provided. Values for other properties are optional. In this example, the class being discovered is hosted by Windows Computer and the key property of that class is added to the instance.
After the instance is created and its properties populated, the instance is added to the discovery data object. If the script created multiple instances, a loop could be used that added each instance as it was created and configured. If this line is left out of the script, the instance is never added to the discovery data object.
After all instances are created and configured, the discovery data is returned into the workflow. This line is required, and without it the discovery data is discarded when the script ends. A discovery script may output only a single set of discovery data. If multiple instances are being discovered, the line appears only one time at the end of the script after all instances are added.
The following script is the Windows PowerShell equivalent of the VBScript sample discovery script shown previously. Both scripts use the same MOM.ScriptAPI object and methods.
param($sourceId,$managedEntityId$computerName) $api = New-Object -comObject 'MOM.ScriptAPI' $discoveryData = $api.CreateDiscoveryData(0, $sourceId, $managedEntityId) $instance = $discoveryData.CreateClassInstance("$MPElement[Name='Demo.StoreApp.CentralQueue']$") $instance.AddProperty("$MPElement[Name='Windows!Microsoft.Windows.Computer']/PrincipalName$", $computerName) $instance.AddProperty("$MPElement[Name='MyMP.MyClass']/Name$", "svr1.contoso.com") $instance.AddProperty("$MPElement[Name='MyMP.MyClass']/Version$", "1.0") $discoveryData.AddInstance($instance) $discoveryData
Other than obvious syntax, there are two primary differences between the VBScript and Windows PowerShell scripts, as follows.
The first difference is in the means of retrieving script arguments. Windows PowerShell can accept positional arguments as VBScript does, but named parameters that use the param command better support the Windows PowerShell modules included with Operations Manager 2007 R2. These modules let parameters be separately specified in the module configuration where they are retrieved by the script as named parameters.
Another important difference is the way that the discovery data is returned to the workflow. In VBScript, the Return method of the MOM.ScriptAPI object is used. In Windows PowerShell , this method will not return the data correctly. The Return method sends the discovery data to the Standard Out (StdOut) stream, whereas Windows PowerShell requires the data to be sent to the output pipeline. This is achieved by typing the discovery data variable on its own line.
Empty Discovery Data
If a discovery script does not return discovery data, an error will be generated on the agent. Even if no instances of the class are found, empty discovery data should be created and returned by the script. If no data is returned, Operations Manager cannot determine if any instances that were previously discovered have now been removed.