我相当确定让 Windows 更新代理搜索更新应该可以清除 UI 中的错误。这应该为您做到这一点:
$WUSess = new-object -ComObject Microsoft.Update.Session
$Searcher=$WUSess.CreateUpdateSearcher()
$SearchResults = Try{$Searcher.Search("IsInstalled=0 and Type='Software'")}Catch{[pscustomobject]@{'Updates'=@()}}
这是我用来通过 Windows Update 安装更新而无需单击 UI 的较大脚本的一部分。整个脚本在这里:
#region UACElevation
# Elevate UAC if not already running As Administrator
# Get the ID and security principal of the current user account
$myWindowsID=[System.Security.Principal.WindowsIdentity]::GetCurrent()
$myWindowsPrincipal=new-object System.Security.Principal.WindowsPrincipal($myWindowsID)
# Get the security principal for the Administrator role
$adminRole=[System.Security.Principal.WindowsBuiltInRole]::Administrator
# Check to see if we are currently running "as Administrator"
if (!$myWindowsPrincipal.IsInRole($adminRole))
{
# We are not running "as Administrator" - so relaunch as administrator
# Create an encoded string to re-launch the script bypassing execution policy
$Code = ". '$($myInvocation.MyCommand.Definition)'"
$Encoded = [Convert]::ToBase64String([Text.Encoding]::Unicode.GetBytes($code))
# Indicate that the process should be elevated
Start-Process PowerShell.exe -Verb RunAs -ArgumentList "-EncodedCommand",$Encoded
# Exit from the current, unelevated, process
exit
}
#endregion UACElevation
#region Functions
Function Invoke-Pause ($text){
[reflection.assembly]::LoadWithPartialName('Windows.Forms')|out-null
If($psISE){
[Windows.Forms.MessageBox]::Show("$Text", "Script Paused", [Windows.Forms.MessageBoxButtons]"OK", [Windows.Forms.MessageBoxIcon]"Information") | ?{(!($_ -eq "OK"))}
}Else{
Write-Host $Text
Write-Host "Press any key to continue ..."
$x = $host.UI.RawUI.ReadKey("NoEcho,IncludeKeyDown")
}
}
Function Show-MsgBox ($Text,$Title="",[Windows.Forms.MessageBoxButtons]$Button = "OK",[Windows.Forms.MessageBoxIcon]$Icon="Information"){
[Windows.Forms.MessageBox]::Show("$Text", "$Title", [Windows.Forms.MessageBoxButtons]::$Button, $Icon) | ?{(!($_ -eq "OK"))}
}
#endregion Functions
$WUSess = new-object -ComObject Microsoft.Update.Session
$Searcher=$WUSess.CreateUpdateSearcher()
$SearchResults = Try{$Searcher.Search("IsInstalled=0 and Type='Software'")}Catch{[pscustomobject]@{'Updates'=@()}}
If($SearchResults.Updates.Count -eq 0){Invoke-Pause "No updates found at this time.`nScript will now exit.";Return}
If($($SearchResults.updates).Where({!($_.isdownloaded)})){
Write-Host "Downloading $($($SearchResults.updates).Where({!($_.isdownloaded)}).Count) updates to install."
$ToDownload = New-Object -ComObject Microsoft.Update.UpdateColl
$SearchResults.updates|?{!($_.isdownloaded)}|%{[void]$ToDownload.Add($_)}
$Downloader = $WUSess.CreateUpdateDownloader()
$Downloader.Updates = $ToDownload
[void]$Downloader.Download()
}
$SearchResults = $Searcher.Search("IsInstalled=0 and Type='Software'")
$ToInstall = New-Object -ComObject Microsoft.Update.UpdateColl
$SearchResults.Updates|?{$_.isDownloaded -and $_.EULAAccepted}|%{[void]$ToInstall.Add($_)}
$Installer = $WUSess.CreateUpdateInstaller()
$Installer.Updates = $ToInstall
Write-Host "Installing $($ToInstall.Count) udpates."
$InstResults = $Installer.Install()
If($InstResults.RebootRequired){Write-Warning "One or more of the updates installed require the system to be rebooted to complete its installation.`nPlease reboot now"}
$ResultCodes = @{
0 = 'Not Started'
1 = 'In Progress'
2 = 'Succeeded'
3 = 'Succeeded With Errors'
4 = 'Failed'
5 = 'Aborted'
}
If($InstResults.ResultCode -gt 3){Write-Warning "One or more update failed to install.`nIf this is the first time you have seen this message please reboot and try again"}
$(For($i=0;$i -lt $ToInstall.Count;$i++){[pscustomobject]@{'Result'=$ResultCodes[$InstResults.GetUpdateResult($i).ResultCode];'Update Title'=$ToInstall.Item($i).Title}})|FT -AutoSize
If(($InstResults.ResultCode -gt 3 -or $InstResults.RebootRequired) -and (Show-MsgBox -Text 'Would you like to reboot now?' -Title 'Reboot?' -Button YesNo -Icon Question ) -eq 'Yes'){Restart-Computer -Force}
Invoke-Pause -Text 'Finished installing updates, the script will now exit.'