即使 WindowsUpdateService 已启动并正在运行,Windows 更新 UI 仍卡在遇到错误

Posted

技术标签:

【中文标题】即使 WindowsUpdateService 已启动并正在运行,Windows 更新 UI 仍卡在遇到错误【英文标题】:Windows Update UI stuck on Error Encountered even when WindowsUpdateService is up and running 【发布时间】:2022-01-12 22:05:08 【问题描述】:

我需要从 CMD/PowerShell 实现禁用/启用 Windows 更新。 为此,我使用以下命令禁用 WindowsUpdate:

sc config wuauserv start= disabled
sc stop wuauserv

为了启用,我使用以下命令:

sc config wuauserv start=auto
net start wuauserv

问题是在 WindowsUpdate 服务重新启动后,UI 仍然卡住(在重新启动后也是如此)并且 Windows 不会扫描或安装新更新,直到我手动单击“重试”按钮

是否有任何 CMD/PowerShell 可以将 Windows 更新状态恢复正常? (不点击重试按钮)又名:

【问题讨论】:

【参考方案1】:

我很确定让 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.'

【讨论】:

以上是关于即使 WindowsUpdateService 已启动并正在运行,Windows 更新 UI 仍卡在遇到错误的主要内容,如果未能解决你的问题,请参考以下文章

领域对象列表函数未定义,即使对象已定义且列表已填充

为啥即使磁盘已满PHP仍返回0

JmsListenerContainerFacotory 不可用:NoSuchBeanDefinitionException,即使已配置 DefaultJmsListenerContainerFact

即使设备已锁定方向,如何进行方向检测

警报,即使应用程序已关闭

我没有设置 CORS 标头,即使它已设置。为啥?