PowerShell脚本调用Get-DbaInstalledPatch无输出的问题排查
问题:多实例循环执行Get-DbaInstalledPatch时变量无数据填充
使用DBATools工具编写PowerShell脚本,通过数字选项(1-5)收集多台SQL Server实例的补丁信息,其中选项3为检查补丁。单实例在终端执行Get-DbaInstalledPatch -ComputerName SQLINSTANCENAME可正常输出,但脚本中循环多实例(Server1、Server2)时,$patchLevel变量无有效内容输出,仅显示空的补丁级别信息。
可正常运行的命令:
Get-DbaInstalledPatch -ComputerName SQLINSTANCENAME
无法正常输出的脚本代码:
# Define a list of SQL Server instances $instances = @( "Server1", "Server2" ) # Iterate through the list of instances foreach ($instance in $instances) { Write-Host "Checking patch level for instance: $instance" # Retrieve the latest patch level for the instance $patchLevel = Get-DbaInstalledPatch -ComputerName $instance # Output the patch level if ($patchLevel) { Write-Host "Latest patch level: $patchLevel" } else { Write-Host "Unable to retrieve patch level for instance: $instance" } }
脚本执行输出:
Select Operation...: 3 Checking patch level for instance: Server1 Latest patch level: Checking patch level for instance: Server2 Latest patch level:
原因分析与解决办法
核心原因
Get-DbaInstalledPatch返回的是自定义对象集合,每个对象包含HotFixID、InstalledOn、Description等多个属性。单实例在终端执行时,PowerShell会自动格式化对象并显示属性列表;但脚本中直接用Write-Host输出对象时,PowerShell无法自动展开属性,导致显示为空。
解决办法
需要明确指定要输出的对象属性,或者对返回的对象进行格式化处理。以下是修正后的脚本:
# Define a list of SQL Server instances $instances = @( "Server1", "Server2" ) # Iterate through the list of instances foreach ($instance in $instances) { Write-Host "`nChecking patch level for instance: $instance" # Retrieve all installed patches for the instance $patchLevel = Get-DbaInstalledPatch -ComputerName $instance # Output patch information if ($patchLevel) { # 取最新安装的补丁(按安装时间倒序排序) $latestPatch = $patchLevel | Sort-Object InstalledOn -Descending | Select-Object -First 1 Write-Host "Latest patch: HotFixID = $($latestPatch.HotFixID), Installed on = $($latestPatch.InstalledOn)" # 可选:输出所有补丁信息 Write-Host "All installed patches:" $patchLevel | Format-Table HotFixID, InstalledOn, Description -AutoSize | Out-Host } else { Write-Host "Unable to retrieve patch level for instance: $instance" } }
关键说明
- 用
$($latestPatch.HotFixID)这种语法可以直接访问对象的属性值,确保输出有效内容。 - 如果需要查看所有补丁,使用
Format-Table或Format-List格式化后,通过Out-Host输出,避免Write-Host的限制。 if ($patchLevel)的判断逻辑是有效的,因为只要有补丁返回,$patchLevel就是非空的对象集合。
内容的提问来源于stack exchange,提问作者rickandm00rty
相关产品推荐
相关产品推荐

