检查是否正在安装 Windows 更新

检查是否正在安装 Windows 更新

我有一个 powershell 脚本,供 IT 支持部门用于在工作站上远程安装软件。该脚本支持安装多个产品(一个接一个),因此可能需要很长时间才能运行。

昨天,一名技术人员使用该脚本在一台已关闭几天的机器上远程安装了多个软件产品。

我们有一个针对所有工作站的 Windows 更新 GPO,它配置为每周三晚上 9 点安装更新。如果工作站错过了此预定的安装日期,则更新将在机器下次开启后 60 分钟安装。

当技术人员针对远程工作站安装软件时,Windows 更新重新安排开始生效。因此,他的安装和 Windows 更新现在同时安装。这导致他正在安装的产品 (SQL Server Management Studio) 崩溃。

我想修改我的脚本以检查 Windows 更新当前是否正在安装。如果是,则警告技术人员并中止脚本。如果没有,则停止并禁用 Windows 更新服务 (wuauserv),这将防止它在脚本使用时启动,然后在脚本结束时启动并重新启用该服务。

我找不到一种可靠的方法来检查 Windows 更新是否正在安装。

欢迎任何建议;我很乐意使用对象、命令行工具、WMI、读取注册表等......

更新 1. 06/04/13:我希望能够以某种方式查询 Windows 更新服务的状态。如果当前正在安装更新,我倾向于尊重更新正在安装的事实并建议技术人员稍后再回来。我目前正在进行一些测试,以确定在以下情况下停止 wuauserv 服务的效果:

  1. 在安装更新之前停止服务。
  2. 在安装更新时停止服务。

更新 2. 06/04/13: 我有一个 Windows 7 VM,已经有好几天没有打开了,因此我能够模拟技术人员前几天遇到的情况。我能够利用快照进行多项不同的测试。

我应该指出,我修改了负责我们的 Windows 更新设置的 GPO,将工作站开启后的重新安排时间从 60 分钟减少到 10 分钟(以使测试更容易一些)。

测试 1) 在安装更新之前停止 wuauserv 服务。

更新将于 12:40 安装。

我使用 powershell 远程停止了 wuauserv。我跟踪了 WindowsUpdate.log,发现出现以下内容:

2013-04-06      12:36:00:287     984    e68     Service *********
2013-04-06      12:36:00:287     984    e68     Service **  END  **  Service: Service exit [Exit code = 0x240001]
2013-04-06      12:36:00:287     984    e68     Service *************

我一直等到 12:40,希望该服务能够通过某种神奇的方式重新启动。但事实并非如此。

我启动了该服务,并且以下内容被写入 WindowsUpdate.log,确认该服务已再次启动。

2013-04-06    12:42:07:571     984    e70    Misc    ===========  Logging initialized (build: 7.6.7600.256, tz: +0100)  ===========
2013-04-06    12:42:07:571     984    e70    Misc      = Process: C:\Windows\system32\svchost.exe
2013-04-06    12:42:07:571     984    e70    Misc      = Module: c:\windows\system32\wuaueng.dll
2013-04-06    12:42:07:571     984    e70    Service    *************
2013-04-06    12:42:07:571     984    e70    Service    ** START **  Service: Service startup
2013-04-06    12:42:07:571     984    e70    Service    *********

日志还确认 10 分钟的重新安排已再次生效:

Success    Content Install    Installation Ready: The following updates are downloaded and ready for installation. This computer is currently scheduled to install these updates on 06 April 2013 at 12:52

测试 2)在更新安装期间停止了 wuauserv 服务

这是我停止服务之前 WindowsUpdate.log 的摘录:

2013-04-06      13:25:00:372    1004    4dc     DnldMgr Preparing update for install, updateId = {F13298D7-7EC1-4D33-9A57-A367F54BA4DA}.106.
2013-04-06      13:25:00:372    3472    790     Handler :::::::::::::
2013-04-06      13:25:00:372    3472    790     Handler :: START ::  Handler: CBS Install
2013-04-06      13:25:00:372    3472    790     Handler :::::::::
2013-04-06      13:25:00:372    3472    790     Handler Starting install of CBS update F13298D7-7EC1-4D33-9A57-A367F54BA4DA
2013-04-06      13:25:00:419    3472    790     Handler CBS package identity: Package_for_KB2698365~31bf3856ad364e35~amd64~~6.1.1.2
2013-04-06      13:25:00:434    3472    790     Handler Installing self-contained with source=C:\Windows\SoftwareDistribution\Download\8fff2597df465a2957121c20dbd4bcec\windows6.1-kb2698365-x64.cab, workingdir=C:\Windows\SoftwareDistribution\Download\8fff2597df465a2957121c20dbd4bcec\inst

这是我停止服务时记录的内容:

2013-04-06      13:25:19:957    3472    3e4     Handler CUHCbsHandler::Cancel called with fReleaseThreadNow=0
2013-04-06      13:25:19:957    1004    ed0     AU      ###########  AU: Uninitializing Automatic Updates  ###########
2013-04-06      13:25:19:973    3472    3e4     Handler CUHCbsHandler::Cancel called with fReleaseThreadNow=1
2013-04-06      13:25:19:973    3472    790     Handler WARNING: CBS handler has been told to exit immediately.
2013-04-06      13:25:19:973    3472    790     Handler FATAL: Completed install of CBS update with type=2, requiresReboot=0, installerError=0, hr=0x80242008
2013-04-06      13:25:19:973    3472    790     Handler :::::::::
2013-04-06      13:25:19:973    3472    790     Handler ::  END  ::  Handler: CBS Install
2013-04-06      13:25:19:973    3472    790     Handler :::::::::::::
2013-04-06      13:25:19:988    1004    4dc     Agent     * WARNING: Exit code = 0x8024000B
2013-04-06      13:25:19:988    1004    4dc     Agent   *********
2013-04-06      13:25:19:988    1004    4dc     Agent   **  END  **  Agent: Installing updates [CallerId = AutomaticUpdates]
2013-04-06      13:25:19:988    1004    4dc     Agent   *************
2013-04-06      13:25:19:988    1004    4dc     Agent   WARNING: WU client failed installing updates with error 0x8024000b
2013-04-06      13:25:20:004    1004    ed0     Report  REPORT EVENT: {72199C19-359E-4D78-A075-4EAA44C368D9}    2013-04-06 13:25:19:973+0100  1186     101     {D5FD720E-0F2C-4363-AA87-6AD4A6D11B0E}  106     8024000b        AutomaticUpdates        Success Content Install User cancelled the installation.
2013-04-06      13:25:20:035    1004    ed0     Report  CWERReporter::HandleEvents - WER report upload completed with status 0x8
2013-04-06      13:25:20:035    1004    ed0     Report  WER Report sent: 7.6.7600.256 0x8024000b D5FD720E-0F2C-4363-AA87-6AD4A6D11B0E Install 101 Managed
2013-04-06      13:25:20:035    1004    ed0     Report  CWERReporter finishing event handling. (00000000)
2013-04-06      13:25:20:160    1004    ed0     Service *********
2013-04-06      13:25:20:160    1004    ed0     Service **  END  **  Service: Service exit [Exit code = 0x240001]
2013-04-06      13:25:20:160    1004    ed0     Service *************

如您所见,它记录了当前正在安装的更新已被取消的事实。

我只是希望正在进行的安装能以一种正常的方式取消?但我真的不知道答案...由于大多数 Windiws 更新都使用 MSI,我希望它们能够使用其回滚文件和注册表更改的功能,从而使工作站处于稳定状态。

答案1

停止 wuauserv

无论它是否正在运行,该命令完成后它都不会运行。

脚本完成时

启动wuauserv

答案2

我现在不在域机器上来验证名称,但我处理这个问题的方式是:

查找正在运行的进程:

  1. 执行程序
  2. 安装程序
  3. SCCM 进程 - 我忘记了确切的名称,请将其终止。
  4. SMS 进程 - 名称也忘记了,请终止它

我检查前两个程序是否正在运行(还有一个是 CompanyNameSetup.exe),看看是否有当前安装。如果没有,则终止 SCCM 和 SMS 进程,这样就不会推送新的安装。

完成安装然后重新启动,或者重新启动 SCCM 和 SMS 进程/服务。

在下面的评论之后:我认为这将是伪路线:

while (msiexec.exe isRunning OR Setup.EXE isRunning)
{wait for completion}
net stop wuauserv  #Prevent installs
taskkill /im Wuauclt.exe /f  #Kill an empty Wuauclt.exe

然后你就可以调用你的脚本了,安装完成后,你所要做的就是调用

net start wuauserv  #Start WSUS service

答案3

我不建议在安装过程中终止这些进程,正如您和 AthomSfere 讨论的那样。但是,考虑到 Windows 中要查找的两个主要安装名称,msiexec.exesetup.exe可以在 powershell 脚本中查找它们,如果这些进程正在运行,则创建一个循环,让脚本休眠,直到这两个进程都关闭。类似于(伪代码):

while($(get-process -like msiexec.exe).count -gt 1 -or $(get-process -like setup.exe).count -gt 1){
    sleep 300
}

我只是部分推荐这个解决方案,因为有可能需要重新启动已安装的更新,如果需要重新启动,并且如果有待重新启动,则脚本安装的软件将无法安装,那么无论如何这都是失败的完美风暴。

理想情况下,如果你有足够大的基础设施来利用 sccm 之类的东西进行软件部署那么这就是您想要的,并且最终可以防止这些冲突(至少从我的经验来看,从 sccm 安装的软件和更新不会冲突,它们是连续安装的而不是同时安装的)。

答案4

对于 Windows 更新服务 IsBusy 状态,您可以使用:

$objInstaller=New-Object -ComObject "Microsoft.Update.Installer"
$objInstaller.IsBusy

如果你想等到服务完成,你可以这样做while ($objInstaller.IsBusy) { Start-Sleep -s 1 }

取自https://www.powershellgallery.com/packages/PSWindowsUpdate/1.5.2.2/Content/Get-WUInstallerStatus.ps1

相关内容