0

我需要从 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 更新状态恢复正常?(不点击重试按钮)又名:

在此处输入图像描述

4

1 回答 1

0

我相当确定让 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.'
于 2021-12-07T21:30:29.427 回答