Referring back to the previous VSAE Fragment post regarding the Windows Timed Script Discovery Provider, you can see this module can be implemented directly in a new discovery. In most cases, this works very well. In some cases, you may want to create a custom discovery provider in order to expose configuration elements as separate parameters – particularly override parameters.
Example of override parameters by implementing the built-in module type in your discovery
Zooming in on the script arguments, you can see this:
$MPElement$ $Target/Id$ $Target/Host/Property[Type=”Windows!Microsoft.Windows.Computer”]/PrincipalName$ c:\ScomSkillsDemo.csv
This isn’t very friendly to an operator that is setting a discovery override, and presents greater opportunity for override mistakes. The only parameter an operator might need to change is the CSV File Location.
So, how can this be improved from an operator perspective? One option is to create a new module type. If you have multiple parameters you want separated in the Operations console, this is probably the best option, as the built-in provider only allows for a single string of arguments.
This example is purely to offer a better experience for the operator creating overrides – there is really no difference in how instances will be discovered under the hood. The result will be new override parameters available in the Operations console.
Example of override parameters by implementing a custom discovery provider
What does this do?
This performs the same discovery as the previous fragment, but creates custom override parameters in the Operations console.
Fragment 1: Custom discovery module type
<ManagementPackFragment SchemaVersion="2.0" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<TypeDefinitions>
<ModuleTypes>
<DataSourceModuleType ID="SCOMskills.Demo.TimedScript.DiscoveryProvider.Custom" Accessibility="Public">
<Configuration>
<xsd:element minOccurs="1" name="Interval" type="xsd:integer" />
<xsd:element minOccurs="1" name="CsvFileLocation" type="xsd:string" />
<xsd:element minOccurs="1" name="PrincipalName" type="xsd:string" />
<xsd:element minOccurs="1" name="Timeout" type="xsd:integer" />
</Configuration>
<OverrideableParameters>
<OverrideableParameter ID="Interval" ParameterType="int" Selector="$Config/Interval$"/>
<OverrideableParameter ID="CsvFileLocation" ParameterType="string" Selector="$Config/CsvFileLocation$"/>
<OverrideableParameter ID="Timeout" ParameterType="int" Selector="$Config/Timeout$"/>
</OverrideableParameters>
<ModuleImplementation Isolation="Any">
<Composite>
<MemberModules>
<DataSource ID="Scheduler" TypeID="System!System.Scheduler">
<Scheduler>
<SimpleReccuringSchedule>
<Interval>$Config/Interval$</Interval>
</SimpleReccuringSchedule>
<ExcludeDates />
</Scheduler>
</DataSource>
<ProbeAction ID="Script" TypeID="Windows!Microsoft.Windows.ScriptDiscoveryProbe">
<ScriptName>SCOMskills.Demo.Discovery.vbs</ScriptName>
<Arguments>$MPElement$ $Target/Id$ $Config/PrincipalName$ $Config/CsvFileLocation$</Arguments>
<ScriptBody>
<![CDATA[
Option Explicit
Dim oArgs
Set oArgs = WScript.Arguments
if oArgs.Count < 4 Then
Wscript.Quit -1
End If
Dim SourceID, ManagedEntityId, TargetComputer, SourceFile
SourceId = oArgs(0)
ManagedEntityId = oArgs(1)
TargetComputer = oArgs(2)
SourceFile = oArgs(3)
Dim oAPI, oDiscoveryData, oInst
Set oAPI = CreateObject("MOM.ScriptAPI")
set oDiscoveryData = oAPI.CreateDiscoveryData(0, SourceId, ManagedEntityId)
Dim oFso, oFile, aField
Set oFso = CreateObject("Scripting.FileSystemObject")
If (oFso.FileExists(SourceFile)) Then
Set oFile = oFso.OpenTextFile(SourceFile)
aField = split(oFile.ReadLine,",")
set oInst = oDiscoveryData.CreateClassInstance("$MPElement[Name='SCOMskills.Demo.ApplicationComponent.Class']$")
call oInst.AddProperty("$MPElement[Name='Windows!Microsoft.Windows.Computer']/PrincipalName$", TargetComputer)
call oInst.AddProperty("$MPElement[Name='SCOMskills.Demo.ApplicationComponent.Class']/CsvField1$", aField(0))
call oInst.AddProperty("$MPElement[Name='SCOMskills.Demo.ApplicationComponent.Class']/CsvField2$", aField(1))
call oInst.AddProperty("$MPElement[Name='System!System.Entity']/DisplayName$", TargetComputer)
call oDiscoveryData.AddInstance(oInst)
Else
Wscript.Quit -1
End If
Call oAPI.Return(oDiscoveryData)
]]>
</ScriptBody>
<TimeoutSeconds>$Config/Timeout$</TimeoutSeconds>
</ProbeAction>
</MemberModules>
<Composition>
<Node ID="Script">
<Node ID="Scheduler" />
</Node>
</Composition>
</Composite>
</ModuleImplementation>
<OutputType>System!System.Discovery.Data</OutputType>
</DataSourceModuleType>
</ModuleTypes>
</TypeDefinitions>
<LanguagePacks>
<LanguagePack ID="ENU" IsDefault="true">
<DisplayStrings>
<DisplayString ElementID="SCOMskills.Demo.TimedScript.DiscoveryProvider.Custom">
<Name>SCOMskills Custom Timed Script Discovery</Name>
</DisplayString>
<DisplayString ElementID="SCOMskills.Demo.TimedScript.DiscoveryProvider.Custom" SubElementID="CsvFileLocation">
<Name>CSV File Location</Name>
</DisplayString>
</DisplayStrings>
</LanguagePack>
</LanguagePacks>
</ManagementPackFragment>
Fragment 2: Implementing the custom discovery module
<ManagementPackFragment SchemaVersion="2.0" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<Monitoring>
<Discoveries>
<Discovery ID="SCOMskills.Demo.TimedScript.Custom.Discovery" ConfirmDelivery="false" Enabled="true" Priority="Normal" Remotable="true" Target="SCOMskills.Demo.LocalApplication.Class">
<Category>Discovery</Category>
<DiscoveryTypes>
<DiscoveryClass TypeID="SCOMskills.Demo.ApplicationComponent.Class">
<Property TypeID="SCOMskills.Demo.ApplicationComponent.Class" PropertyID="CsvField1"/>
<Property TypeID="SCOMskills.Demo.ApplicationComponent.Class" PropertyID="CsvField2"/>
<Property TypeID="System!System.Entity" PropertyID="DisplayName"/>
</DiscoveryClass>
</DiscoveryTypes>
<DataSource ID="DS" TypeID="SCOMskills.Demo.TimedScript.DiscoveryProvider.Custom">
<Interval>60</Interval>
<CsvFileLocation>c:\ScomSkillsDemo.csv</CsvFileLocation>
<PrincipalName>$Target/Host/Property[Type="Windows!Microsoft.Windows.Computer"]/PrincipalName$</PrincipalName>
<Timeout>60</Timeout>
</DataSource>
</Discovery>
</Discoveries>
</Monitoring>
<LanguagePacks>
<LanguagePack ID="ENU" IsDefault="true">
<DisplayStrings>
<DisplayString ElementID="SCOMskills.Demo.TimedScript.Custom.Discovery">
<Name>SCOMskills Timed Script Custom Discovery</Name>
</DisplayString>
</DisplayStrings>
</LanguagePack>
</LanguagePacks>
</ManagementPackFragment>
_