Windows Server补丁需滚动更新而非全量推送,因IIS、SQL Server等服务对KB累积更新敏感,易致0x80070643失败或w3svc重启;须禁用自动重启、逐节点安装验证、NLB摘机延时、应用池预停、SQL补丁专项处理,并依赖PSWindowsUpdate脚本化控制全流程。
Windows Server 补丁更新为什么不能直接全量推送
因为生产环境的 iis、sql server、.net 运行时等服务对补丁敏感,
这类累积更新可能触发
安装失败,或导致
意外重启。滚动更新不是为了“更酷”,而是避免单点故障扩散——你没法接受所有 web 服务器在同一分钟内蓝屏。
关键原则:每次只更新一个节点,验证通过后再推进下一个
必须关闭自动重启策略,用
手动控制
下的
和
补丁安装前检查
输出中是否有
(依赖缺失)或
(权限不足)
SQL Server 实例所在机器要额外确认
是否已由 SQL Server 安装中心预载,否则
模块会跳过 SQL 相关补丁
用 PSWindowsUpdate 模块实现可控滚动更新
别碰 GUI 界面或 WSUS 控制台做滚动——它们不暴露节点级执行顺序和回滚钩子。
是目前唯一能脚本化控制「下载→安装→静默重启→等待服务就绪」全流程的方案,但默认行为危险,必须重写逻辑。
先用
安装模块(PowerShell 5.1+ 环境)
禁用默认自动重启:
,否则
会绕过你的控制
逐台执行时,用
,并配合
和
做就绪判断
注意
的
参数只支持单个 KB 号,批量指定要用数组传参,否则静默跳过
滚动窗口期间如何防止负载倾斜失效
如果你用 NLB 或 Windows 负载均衡器,
和
不是原子操作——节点从禁用到真正退出流量转发有 3–8 秒延迟,这期间新连接仍可能打进来。
在补丁前执行
后,必须跟
,再确认
返回状态为
IIS 应用程序池要提前设为
,并在补丁完成后用
显式拉起,避免热启动失败被忽略
若使用 Azure Load Balancer 或 F5,不能依赖 Windows 自带 NLB 命令,得调用对应 REST API 或
动态摘除后端池
验证阶段至少采集两个指标:HTTP 200 响应率(用
轮询)、以及
是否恢复基线值
回滚失败补丁的实操底线
补丁失败后想“一键还原”?Windows 没有真正的事务式回滚。所谓卸载,只是调用
卸载更新包,但无法恢复被覆盖的 DLL 签名或注册表键值——尤其当
更新失败时,
可能显示混乱版本。
滚动更新前必须对系统盘做
快照,且验证
中
可读
卸载失败补丁时,先停掉所有依赖服务:
,否则
会返回
如果
查不到记录,说明补丁根本没写入系统,此时不要尝试卸载,应查
中最近 100 行的
错误定位组件存储损坏
最坏情况需用
修复,但该命令会中断所有 Windows Update 操作长达 20 分钟以上,必须安排在维护窗口内
滚动更新真正的复杂点不在命令怎么敲,而在于你得同时盯住三件事:NLB 节点状态是否真实退出、IIS 应用池是否完成冷启动、SQL Server Agent 是否恢复作业调度——任何一个环节卡在“半中间”,监控就失效了。
kb50042370x80070643w3svcSet-ItemPropertyHKLM:\SOFTWARE\Policies\Microsoft\Windows\WindowsUpdate\AUNoAutoRebootWithLoggedOnUsersAUOptionsGet-WindowsUpdateLog0x8024A1050x80070005setup.exe /action=patchPSWindowsUpdatePSWindowsUpdateInstall-Module PSWindowsUpdate -Force -SkipPublisherCheckGet-WUServiceManager | Where-Object {$_.ServiceID -eq '7971f918-a847-4430-9f79-f0789f08115d'} | Remove-WUServiceManagerInstall-WindowsUpdateInvoke-Command -ComputerName $server -ScriptBlock { Install-WindowsUpdate -AcceptAll -IgnoreReboot }Test-NetConnection $server -Port 443Get-Service w3svc | Where-Object Status -eq 'Running'Install-WindowsUpdate-KBArticleIDEnable-NlbClusterNodeDisable-NlbClusterNodeDisable-NlbClusterNode -HostName $server -ForceStart-Sleep -Seconds 10Get-NlbClusterNode -HostName $serverDrainingAutoStart=FalseStart-WebAppPoolaz network lb address-pool updateInvoke-RestMethodGet-Counter '\ASP.NET Applications(*)\Requests/Sec'wusa /uninstall /kb:5004237.NET Framework 4.8dotnet --list-runtimeswbadmin start backupGet-WBBackupSetBackupTargetStop-Service w3svc, MSSQLSERVER, W3SVCwusa0x80070422Get-HotFix | Where-Object HotFixID -eq 'KB5004237'C:\Windows\Logs\CBS\CBS.log0x80073712DISM /Online /Cleanup-Image /RestoreHealth