多台Windows Server缺失更新查询PowerShell脚本优化求助
用PoshRSJob并行查询多台Windows Server的缺失更新
核心对比逻辑
先统一两个关键数据集的格式,避免因格式差异导致对比失效:
- 当月更新列表:确保每条记录包含
KB(统一格式为KBxxxxxxx)、Title,以及匹配OS版本的标识(比如2008/2012R2/2016/2019) - 已安装更新:通过
Get-HotFix获取后,统一将HotFixID转换为KBxxxxxxx格式
对比逻辑:针对单台服务器,先根据其OS版本筛选出对应当月更新列表,再排除已安装的KB,剩余条目即为缺失更新。
用PoshRSJob并行执行实现
1. 准备前置数据
假设你已完成以下数据预处理:
# 目标服务器列表 $serverList = @("Server01", "Server02", "Server03", "Server04") # 按OS版本分组的当月更新(示例结构,需替换为你从MSCatalog获取的实际数据) $updatesByOS = @{ "2008" = Get-Content "2008_monthly_updates.json" | ConvertFrom-Json "2012" = Get-Content "2012_monthly_updates.json" | ConvertFrom-Json "2012R2" = Get-Content "2012R2_monthly_updates.json" | ConvertFrom-Json "2016" = Get-Content "2016_monthly_updates.json" | ConvertFrom-Json "2019" = Get-Content "2019_monthly_updates.json" | ConvertFrom-Json }
2. 导入PoshRSJob模块
Import-Module PoshRSJob -ErrorAction Stop
3. 启动并行任务
# 启动并行作业处理每台服务器 $jobs = $serverList | Start-RSJob -ScriptBlock { param($serverName, $osUpdateMap) # 初始化结果对象 $output = [PSCustomObject]@{ ServerName = $serverName MissingUpdates = @() ErrorMessage = $null } try { # 获取服务器OS版本信息 $os = Get-CimInstance -ComputerName $serverName -ClassName Win32_OperatingSystem -ErrorAction Stop $osTag = switch -Wildcard ($os.Version) { "6.1*" { "2008" } "6.2*" { "2012" } "6.3*" { "2012R2" } "10.0.14393*" { "2016" } "10.0.17763*" { "2019" } default { "Unknown" } } if ($osTag -eq "Unknown") { $output.ErrorMessage = "不支持的OS版本: $($os.Version)" return $output } # 获取已安装KB(统一格式为KBxxxxxxx) $installedKBs = Get-HotFix -ComputerName $serverName -ErrorAction Stop | ForEach-Object { "KB$($_.HotFixID.Replace('KB', ''))" } # 匹配对应OS的当月更新 $targetUpdates = $osUpdateMap[$osTag] if (-not $targetUpdates) { $output.ErrorMessage = "未找到对应OS版本的当月更新: $osTag" return $output } # 筛选缺失更新 $output.MissingUpdates = $targetUpdates | Where-Object { $_.KB -notin $installedKBs } | Select-Object KB, Title } catch { $output.ErrorMessage = $_.Exception.Message } return $output } -ArgumentList $_ , $updatesByOS -ThrottleLimit 10 # 可根据服务器数量调整并发数 # 等待所有作业完成并取回结果 $finalResults = $jobs | Wait-RSJob | Receive-RSJob # 清理作业资源 $jobs | Remove-RSJob
4. 格式化输出结果
# 输出正常查询的服务器缺失更新 $finalResults | Where-Object { -not $_.ErrorMessage } | ForEach-Object { Write-Host "`n=== 服务器: $($_.ServerName) 缺失更新 ===" -ForegroundColor Cyan if ($_.MissingUpdates.Count -eq 0) { Write-Host "无缺失的当月更新" -ForegroundColor Green } else { $_.MissingUpdates | Format-Table KB, Title -AutoSize } } # 输出查询失败的服务器信息 $finalResults | Where-Object { $_.ErrorMessage } | ForEach-Object { Write-Host "`n=== 服务器: $($_.ServerName) 查询错误 ===" -ForegroundColor Red Write-Host $_.ErrorMessage -ForegroundColor Red }
关键注意事项
- 权限要求:执行脚本的账号需拥有目标服务器的管理员权限,确保能远程访问CIM服务和读取更新信息
- OS版本匹配:Win32_OperatingSystem的Version字段可能因系统补丁略有变化,需根据实际环境调整
switch逻辑 - 数据格式一致性:务必保证MSCatalog获取的KB格式与
Get-HotFix提取的格式完全一致,避免漏判 - 并发数调整:通过
-ThrottleLimit参数控制并行任务数量,避免因并发过高导致网络或服务器资源耗尽
内容的提问来源于stack exchange,提问作者Koobah84
相关产品推荐
相关产品推荐

