跳转到主内容
websoft网络软件专家 - 深耕网络技术,打造实用软件!

怎么在Windows服务器环境实施系统补丁滚动更新

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

相关文章