This ModuleType uses VBScript to discover the list of patches installed on Agents

Microsoft.SystemCenter.Agent.PatchDiscoveryProvider (DataSourceModuleType)

This moduletype runs as a part of a Discovery and finds the list of all Operations Manager patches installed on Agents.

Element properties:

TypeDataSourceModuleType
IsolationAny
AccessibilityInternal
RunAsSystem.PrivilegedMonitoringAccount
OutputTypeSystem.Discovery.Data

Member Modules:

ID Module Type TypeId RunAs 
DiscoveryDataSource DataSource Microsoft.Windows.TimedPowerShell.DiscoveryProvider Default

Overrideable Parameters:

IDParameterTypeSelectorDisplay NameDescription
IntervalSecondsint$Config/IntervalSeconds$Interval Seconds
SyncTimestring$Config/SyncTime$Synchronization Time
TimeoutSecondsint$Config/TimeoutSeconds$Timeout Seconds

Source Code:

<DataSourceModuleType ID="Microsoft.SystemCenter.Agent.PatchDiscoveryProvider" Accessibility="Internal" RunAs="System!System.PrivilegedMonitoringAccount" Batching="false">
<Configuration>
<xsd:element name="IntervalSeconds" type="xsd:integer"/>
<xsd:element name="SyncTime" type="xsd:string"/>
<xsd:element name="ComputerName" type="xsd:string"/>
<xsd:element name="TimeoutSeconds" type="xsd:integer"/>
</Configuration>
<OverrideableParameters>
<OverrideableParameter ID="IntervalSeconds" Selector="$Config/IntervalSeconds$" ParameterType="int"/>
<OverrideableParameter ID="SyncTime" Selector="$Config/SyncTime$" ParameterType="string"/>
<OverrideableParameter ID="TimeoutSeconds" Selector="$Config/TimeoutSeconds$" ParameterType="int"/>
</OverrideableParameters>
<ModuleImplementation Isolation="Any">
<Composite>
<MemberModules>
<DataSource ID="DiscoveryDataSource" TypeID="Windows!Microsoft.Windows.TimedPowerShell.DiscoveryProvider">
<IntervalSeconds>$Config/IntervalSeconds$</IntervalSeconds>
<SyncTime>$Config/SyncTime$</SyncTime>
<ScriptName>DiscoverAgentPatches.ps1</ScriptName>
<ScriptBody><Script>
#Connect to Windows Installer object
param($SourceId, $ManagedEntityId, $TargetComputerID)

function CheckIfNano() #As Boolean
{
$isNano = Get-ItemProperty "HKLM:\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Server\ServerLevels"
$isNano = $isNano.NanoServer
if($isNano -ne $null)
{
return $true;
}
return $false;
}

function DoPatchDiscovery($oDisc)
{
$installer = $null
$momAgentComponentID = "{60ADDA03-1710-4954-B299-A9F42DD889A6}"
try
{
$installer = new-object -comobject "WindowsInstaller.Installer"
}
catch
{
CheckError $Error $installer
}

$product, $productList, $count, $path, $patch, $patchList, $patchListString, $oHealthServiceinstance
try
{
$productList = @($installer.GetType().InvokeMember("ProductsEx", "GetProperty", $null, $installer,('', '', 4)))
}
catch
{
CheckError $Error $installer
}



$patchListString = ""
for($count = 0;$count -lt $productList.Count; $count++)
{
$product = $productList[$count];
$ProductCode=$product.GetType().InvokeMember("ProductCode", "GetProperty", $null, $product, 1)
$path=$installer.GetType().InvokeMember("ComponentPath", "GetProperty", $null, $installer,($ProductCode, $momAgentComponentID))

If($path -ne "" -and $path -ne $null)
{
$patchList=$installer.GetType().InvokeMember("PatchesEx", "GetProperty", $null, $installer,($productCode, "", 7, 1))
foreach($patch in $patchList)
{
$patchListString = $patchListString + $patch.GetType().InvokeMember("PatchProperty", "GetProperty", $null, $patch,("DisplayName")) + "; ";
}
}
}

$productList = $null

$oHealthServiceinstance = $oDisc.CreateClassInstance("$MPElement[Name='SCLibrary!Microsoft.SystemCenter.HealthService']$");
$oHealthServiceinstance.AddProperty("$MPElement[Name='Windows!Microsoft.Windows.Computer']/PrincipalName$", $TargetComputerID);
$oHealthServiceinstance.AddProperty("$MPElement[Name='SCLibrary!Microsoft.SystemCenter.HealthService']/PatchList$", $patchListString);
$oDisc.AddInstance($oHealthServiceinstance);
}

function CheckError($Error, $installer)
{
$message
$errRec = $null
$message = $Error.Source + " : " + $Error[0].Exception.GetType().FullName + ": " + $Error.Description;
If($installer -ne $null){
$errRec = $installer.LastErrorRecord
}
If($errRec -ne $null) {
$message = $message + "\n" + $errRec;
}
Write-Host message
Exit 2;
}


#A script that enumerates Software Updates for MOM Agent (not MOM 2005 but higher versions)
#For use with Windows Scripting Host, CScript.exe or WScript.exe
#Copyright (c) Microsoft Corporation. All rights reserved.
#does NOT work agentlessly


Set-Variable msiInstallStateNotUsed -7 &#x2013;option Constant
Set-Variable msiInstallStateBadConfig -6 &#x2013;option Constant
Set-Variable msiInstallStateIncomplete -5 &#x2013;option Constant
Set-Variable msiInstallStateSourceAbsent -4 &#x2013;option Constant
Set-Variable msiInstallStateInvalidArg -2 &#x2013;option Constant
Set-Variable msiInstallStateUnknown -1 &#x2013;option Constant
Set-Variable msiInstallStateBroken 0 &#x2013;option Constant
Set-Variable msiInstallStateAdvertised 1 &#x2013;option Constant
Set-Variable msiInstallStateRemoved 1 &#x2013;option Constant
Set-Variable msiInstallStateAbsent 2 &#x2013;option Constant
Set-Variable msiInstallStateLocal 3 &#x2013;option Constant
Set-Variable msiInstallStateSource 4 &#x2013;option Constant
Set-Variable msiInstallStateDefault 5 &#x2013;option Constant

Set-Variable momAgentComponentID "{60ADDA03-1710-4954-B299-A9F42DD889A6}" &#x2013;option Constant

$oAPI = new-object -comobject "MOM.ScriptAPI"
$oAgentPatchDiscoveryData = $oAPI.CreateDiscoveryData(0, $SourceId, $ManagedEntityId);
$isNano = CheckIfNano
if($isNano)
{
Write-Host "Write this method when patching is enabled on Nano."
}else{
DoPatchDiscovery $oAgentPatchDiscoveryData
$oAgentPatchDiscoveryData
}
</Script></ScriptBody>
<Parameters>
<Parameter>
<Name>SourceId</Name>
<Value>$MPElement$</Value>
</Parameter>
<Parameter>
<Name>ManagedEntityId</Name>
<Value>$Target/Id$</Value>
</Parameter>
<Parameter>
<Name>TargetComputerID</Name>
<Value>$Config/ComputerName$</Value>
</Parameter>
</Parameters>
<TimeoutSeconds>$Config/TimeoutSeconds$</TimeoutSeconds>
</DataSource>
</MemberModules>
<Composition>
<Node ID="DiscoveryDataSource"/>
</Composition>
</Composite>
</ModuleImplementation>
<OutputType>System!System.Discovery.Data</OutputType>
</DataSourceModuleType>