Skip to content

Instantly share code, notes, and snippets.

@p0w3rsh3ll
Created August 19, 2020 15:37
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save p0w3rsh3ll/4eafda6a42297b78f75239bc900f4c36 to your computer and use it in GitHub Desktop.
Save p0w3rsh3ll/4eafda6a42297b78f75239bc900f4c36 to your computer and use it in GitHub Desktop.
Function Start-WUOfflineScan {
<#
.SYNOPSIS
Start an offline WUA scan
.DESCRIPTION
Start an offline WUA (Windows Update Agent) scan using wsusscn2.cab.
.PARAMETER FilePath
Specifies the path to the wsusscn2.cab file to be used to perform the offline scan.
.PARAMETER IncludeSupersededUpdate
Specifies to include superseded updates in the results if any.
.EXAMPLE
Start-WUOfflineScan -FilePath C:\temp\wsusscn2.cab -Verbose
.NOTES
You can get the offline wsusscn2.cab from:
http://download.windowsupdate.com/microsoftupdate/v6/wsusscan/wsusscn2.cab
Official doc is:
https://docs.microsoft.com/en-us/windows/win32/wua_sdk/using-wua-to-scan-for-updates-offline
#>
[CmdletBinding()]
Param(
[Parameter(Mandatory)]
[ValidateScript({Test-Path -Path $_ -PathType Leaf})]
$FilePath,
[switch]$IncludeSupersededUpdate
)
Begin {
if ($FilePath -match '^~') {
$FilePath = $ExecutionContext.SessionState.Path.GetUnresolvedProviderPathFromPSPath($FilePath)
}
try {
$UpdateSvc = New-Object -ComObject Microsoft.Update.ServiceManager
} catch {
Write-Warning -Message "Failed to query if server is configured against a WSUS server because $($_.Exception.Message)"
}
Function Test-WUARebootRequired {
try {
(New-Object -ComObject 'Microsoft.Update.SystemInfo').RebootRequired
} catch {
Write-Warning -Message "Failed to query COM object because $($_.Exception.Message)"
}
}
}
Process {
if (-not(Test-WUARebootRequired)) {
try {
# Create a session
$Session = New-Object -ComObject Microsoft.Update.Session
# Import the the offline cab
$UpdateService = $UpdateSvc.AddScanPackageService('Offline Sync Service',"$($FilePath)", 1)
$Searcher = $Session.CreateUpdateSearcher()
$Searcher.ServerSelection = 3 #ssOthers
if ($IncludeSupersededUpdate) {
$Searcher.IncludePotentiallySupersededUpdates = $true
}
$Searcher.ServiceID = $UpdateService.ServiceID.ToString()
$Criteria = "IsInstalled=0 and DeploymentAction='Installation' or IsPresent=1 and DeploymentAction='Uninstallation' or IsInstalled=1 and DeploymentAction='Installation' and RebootRequired=1 or IsInstalled=0 and DeploymentAction='Uninstallation' and RebootRequired=1"
# Search for updates
$SearchResult = $Searcher.Search($Criteria)
} catch {
Write-Warning -Message "Failed to search for missing updates because $($_.Exception.Message)"
if ($SearchResult) {
Write-Warning -Message "The search result status code was $($SearchResult.ResultCode)"
}
break
}
if ($SearchResult.ResultCode -eq 2) {
# Output what was found
if (($SearchResult.Updates).Count -ne 0) {
$SearchResult.Updates |
ForEach-Object {
Write-Verbose -Message "Missing update: $($_.Title)"
$_
}
} else {
Write-Verbose -Message 'There are no updates to install' -Verbose
}
} else {
Write-Warning -Message 'Failed to search for updates'
Write-Warning -Message "The search result status code was $($SearchResult.ResultCode)"
}
} else {
Write-Warning -Message 'A reboot is pending'
}
}
End {}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment