"Collects Windows Update Agent information for the Update Assessment Intelligence Pack

CollectDeviceInformation (Rule)

Element properties:

TargetMicrosoft.Windows.Computer
CategoryCustom
EnabledFalse
Alert GenerateFalse
RemotableFalse

Member Modules:

ID Module Type TypeId RunAs 
DS DataSource TimedPowershellPropertyBagProvider Default
WA2 WriteAction Microsoft.SystemCenter.UpdateAgentInformationDataWriteAction Default

Source Code:

<Rule ID="CollectDeviceInformation" Enabled="false" Target="Windows!Microsoft.Windows.Computer" ConfirmDelivery="false" Remotable="false">
<Category>Custom</Category>
<DataSources>
<DataSource ID="DS" TypeID="TimedPowershellPropertyBagProvider">
<IntervalSeconds>43200</IntervalSeconds>
<SyncTime/>
<ScriptName>CollectLastUpdateTime</ScriptName>
<ScriptBody><Script>function XmlEscapeString($string)
{
return [System.Security.SecurityElement]::Escape($string);
}

function GetOldestMissingUpdateValuesInternal($changeWebProxy)
{
$settings = @{};

$Session = New-Object -ComObject Microsoft.Update.Session;

if ($changeWebProxy -eq $true)
{
$Session.WebProxy.AutoDetect = $false;
}

$Searcher = $Session.CreateUpdateSearcher();

$SearchResults = $Searcher.Search("IsInstalled=0 AND BrowseOnly=0")

if ($SearchResults.Updates.Count -gt 0)
{
$oldestUTC = [System.DateTime]::MaxValue.ToUniversalTime();

foreach ($u in $SearchResults.Updates)
{
if ($u.LastDeploymentChangeTime -lt $oldestUTC)
{
$oldestUTC = $u.LastDeploymentChangeTime;
}
}

$now = [System.DateTime]::UtcNow;

$settings.DateUTC = $oldestUTC;
$settings.Days = ($now - $oldestUTC).Days;

$months = ($now.Year - $oldestUTC.Year) * 12 + ($now.Month - $oldestUTC.Month);

switch ($months)
{
0 { $settings.Bucket = "Not updated in over 10 days"; }
1 { $settings.Bucket = "Not updated in over 30 days"; }
2 { $settings.Bucket = "Not updated in over 60 days"; }
3 { $settings.Bucket = "Not updated in over 90 days"; }
4 { $settings.Bucket = "Not updated in over 120 days"; }
default { $settings.Bucket = "Older"; }
}
}
else
{
$settings.DateUTC = [System.DateTime]::UtcNow;
$settings.Days = 0;
$settings.Bucket = "Up-to-date";
}

return $settings;
}

function GetOldestMissingUpdateValues()
{
try
{
$settings = GetOldestMissingUpdateValuesInternal $false;
return $settings;
}
catch [System.Exception]
{
}

try
{
$settings = GetOldestMissingUpdateValuesInternal $true;
return $settings;
}
catch [System.Exception]
{
}

$settings = @{};
return $settings;
}

function GetLastUpdateValues()
{
$settings = @{};

$Session = New-Object -ComObject Microsoft.Update.Session;
$Searcher = $Session.CreateUpdateSearcher();
$HistoryCount = $Searcher.GetTotalHistoryCount();
if ($HistoryCount -gt 0)
{
$LastUpdates = $Searcher.QueryHistory(0,1);

$LastDate = $null;
foreach ($o in $LastUpdates)
{
$LastDate = $o.Date;
}

$LastUpdateUTC = [System.DateTime]::SpecifyKind($LastDate, [DateTimeKind]::Utc);
}
else
{
$LastUpdateUTC = [System.DateTime]::MinValue.ToUniversalTime();
}

$settings.DaysSinceLastUpdate = ([System.DateTime]::UtcNow - $LastUpdateUTC).Days

$settings.DaysSinceLastUpdateBucket = "Up-to-date";

if ($settings.DaysSinceLastUpdate -gt 60)
{
$settings.DaysSinceLastUpdateBucket = "Not updated in over 60 days";
}
elseif ($settings.DaysSinceLastUpdate -gt 30)
{
$settings.DaysSinceLastUpdateBucket = "Not updated in over 30 days";
}
elseif ($settings.DaysSinceLastUpdate -gt 10)
{
$settings.DaysSinceLastUpdateBucket = "Not updated in over 10 days";
}

$settings.LastUpdateUTC = $LastUpdateUTC;

return $settings;
}

function GetAutomaticUpdateSettings()
{
$settings = @{};

$AU = New-Object -com "Microsoft.Update.AutoUpdate"
if ($AU.Settings.NotificationLevel -eq 0)
{
$settings.AutomaticUpdateEnabled = "Manual";
$settings.AutomaticUpdateValue = "Not configured";
}
elseif ($AU.Settings.NotificationLevel -eq 1)
{
$settings.AutomaticUpdateEnabled = "Enabled";
$settings.AutomaticUpdateValue = "Disabled";
}
elseif ($AU.Settings.NotificationLevel -eq 2)
{
$settings.AutomaticUpdateEnabled = "Enabled";
$settings.AutomaticUpdateValue = "Notify before download";
}
elseif ($AU.Settings.NotificationLevel -eq 3)
{
$settings.AutomaticUpdateEnabled = "Enabled";
$settings.AutomaticUpdateValue = "Notify before installation";
}
elseif ($AU.Settings.NotificationLevel -eq 4)
{
$settings.AutomaticUpdateEnabled = "Enabled";
$settings.AutomaticUpdateValue = "Scheduled installation";
}
else
{
$settings.AutomaticUpdateEnabled = "Unknown";
$settings.AutomaticUpdateValue = "Unknown";
}

return $settings;
}

function GetUpdateAgentInformation()
{
$settings = @{};

$WUA = New-Object -ComObject "Microsoft.Update.AgentInfo"
$settings.ProductVersion = XmlEscapeString($WUA.GetInfo("ProductVersionString"));
$os = Get-WmiObject Win32_OperatingSystem
$settings.OsVersion = XmlEscapeString($os.Caption);

return $settings;
}

function GetWindowsUpdateServer()
{
$GroupPolicyKey = 'HKLM:\SOFTWARE\Policies\Microsoft\Windows\WindowsUpdate'
$StandardKey = 'HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\WindowsUpdate'
$WUServer = "";

if (Test-Path $GroupPolicyKey)
{
$WindowsUpdateRegistryKey = Get-Item $GroupPolicyKey;
$WUServer = $WindowsUpdateRegistryKey.GetValue("WUServer");
}
elseif (Test-Path $StandardKey)
{
$WindowsUpdateRegistryKey = Get-Item $StandardKey;
$WUServer = $WindowsUpdateRegistryKey.GetValue("WUServer");
}

return XmlEscapeString($WUServer);
}

function GetNeededUpdatesInternal($changeWebProxy)
{
$Session = New-Object -ComObject Microsoft.Update.Session;

if ($changeWebProxy -eq $true)
{
$Session.WebProxy.AutoDetect = $false;
}

$Searcher = $Session.CreateUpdateSearcher();
$SearchResults = $Searcher.Search("IsInstalled=0 AND BrowseOnly=0");

$updates = @();

foreach ($u in $SearchResults.Updates)
{
$update = @{};
$update.UpdateTitle = XmlEscapeString($u.Title);
$update.UpdateSeverity = XmlEscapeString($u.MsrcSeverity);
$update.PublishDate = $u.LastDeploymentChangeTime;
$update.Product = "";
$update.UpdateClassification = "";

$firstProduct = $true;
$productString = "";
foreach ($c in $u.Categories) {
if ($c.Type -eq "Product")
{
if ($firstProduct -eq $true)
{
$productString += $c.Name;
$firstProduct = $false;
}
else
{
$productString += ";";
$productString += $c.Name;
}
}
if ($c.Type -eq "UpdateClassification")
{
$update.UpdateClassification = XmlEscapeString($c.Name);
}
}

$update.Product = XmlEscapeString($productString);

$firstKB = $true;
$kbString = "";
foreach ($kb in $u.KBArticleIDs)
{
if ($firstKB -eq $true)
{
$kbString += $kb;
$firstKB = $false;
}
else
{
$kbString += ";";
$kbString += $kb;
}
}

$update.KBID = XmlEscapeString($kbString);

$updates += $update;
}

return $updates;
}

function GetNeededUpdates()
{
try
{
$updates = GetNeededUpdatesInternal $false;
return $updates;
}
catch [System.Exception]
{
}

try
{
$updates = GetNeededUpdatesInternal $true;
return $updates;
}
catch [System.Exception]
{
}

$updates = @();
return $updates;
}

$LastUpdateValues = GetLastUpdateValues;
$AutomaticUpdateSettings = GetAutomaticUpdateSettings;
$UpdateAgentInformation = GetUpdateAgentInformation;
$WUServer = GetWindowsUpdateServer;
$OldestMissingSecurityUpdateValues = GetOldestMissingUpdateValues;

$nowUTC = [DateTime]::UtcNow;
$nowDateStampUTC = $nowUTC.Date;

$oAPI = new-object -comObject "MOM.ScriptAPI";
$oPropertyBag = $oAPI.CreatePropertyBag();
$oPropertyBag.AddValue("DateStampUTC", $nowDateStampUTC);
$oPropertyBag.AddValue("LastUpdateUTC", $LastUpdateValues.LastUpdateUTC);
$oPropertyBag.AddValue("DaysSinceLastUpdate", $OldestMissingSecurityUpdateValues.Days);
$oPropertyBag.AddValue("DaysSinceLastUpdateBucket", $OldestMissingSecurityUpdateValues.Bucket);
$oPropertyBag.AddValue("AutomaticUpdateEnabled", $AutomaticUpdateSettings.AutomaticUpdateEnabled);
$oPropertyBag.AddValue("AutomaticUpdateValue", $AutomaticUpdateSettings.AutomaticUpdateValue);
$oPropertyBag.AddValue("WindowsUpdateAgentVersion", $UpdateAgentInformation.ProductVersion);
$oPropertyBag.AddValue("WSUServer", $WUServer);
$oPropertyBag.AddValue("Device", "$Target/Property[Type="Windows!Microsoft.Windows.Computer"]/PrincipalName$");
$oPropertyBag.AddValue("OsVersion", $UpdateAgentInformation.OsVersion);

$oPropertyBag;

</Script></ScriptBody>
<TimeoutSeconds>600</TimeoutSeconds>
</DataSource>
</DataSources>
<WriteActions>
<WriteAction ID="WA2" TypeID="Types!Microsoft.SystemCenter.UpdateAgentInformationDataWriteAction"/>
</WriteActions>
</Rule>