如何在Get-ADComputer遍历中忽略离线计算机,避免执行报错
解决方案
方法一:先检测在线状态再执行命令
先通过Test-Connection快速验证计算机是否在线,只有在线的机器才进入后续执行逻辑,从根源上避免离线机器触发错误或无效操作。
示例脚本:
Get-ADComputer -Filter * | ForEach-Object { # 发送1个数据包,2秒超时,快速判断在线状态 if (Test-Connection -ComputerName $_.Name -Count 1 -Quiet -TimeoutSeconds 2) { # 仅在线时执行目标命令 Get-CimInstance -ComputerName $_.Name -ClassName Win32_OperatingSystem # 这里添加其他需要执行的后续代码 } # 离线机器直接跳过,不执行任何剩余逻辑 }
说明:-Quiet参数让命令返回布尔值(在线为True,离线为False),-TimeoutSeconds缩短等待时长,提升批量处理效率。
方法二:捕获命令错误并跳过当前迭代
如果不想提前检测,也可以在执行Get-CimInstance/Get-WmiObject时主动捕获错误,一旦触发离线或连接失败,直接用continue跳过当前循环的剩余代码。
针对Get-CimInstance的示例(推荐使用):
Get-ADComputer -Filter * | ForEach-Object { try { # 将非终止错误转为终止错误,确保能被catch捕获 $osInfo = Get-CimInstance -ComputerName $_.Name -ClassName Win32_OperatingSystem -ErrorAction Stop # 只有命令成功才会执行以下代码 Write-Host "$($_.Name) 在线,系统版本:$($osInfo.Caption)" # 其他后续操作 } catch { # 捕获到错误(如离线、权限不足),直接进入下一个循环 Write-Verbose "$($_.Name) 无法连接" continue } }
针对Get-WmiObject的示例:
Get-ADComputer -Filter * | ForEach-Object { try { $osInfo = Get-WmiObject -ComputerName $_.Name -Class Win32_OperatingSystem -ErrorAction Stop Write-Host "$($_.Name) 在线,系统版本:$($osInfo.Caption)" # 其他后续操作 } catch { Write-Verbose "$($_.Name) 无法连接" continue } }
额外优化建议
- 优先用
Get-CimInstance:它是WMI的现代替代方案,支持更多特性,错误处理更灵活,性能也更优。 - 批量处理提升效率:如果域内机器数量多,可以先筛选出在线机器,再用
Invoke-Command批量执行(需要目标机器启用WinRM):
# 先筛选在线机器 $onlineComputers = Get-ADComputer -Filter * | Where-Object { Test-Connection -ComputerName $_.Name -Count 1 -Quiet -TimeoutSeconds 2 } # 批量执行命令,设置并发数为10 Invoke-Command -ComputerName $onlineComputers.Name -ScriptBlock { Get-CimInstance -ClassName Win32_OperatingSystem } -ThrottleLimit 10
内容的提问来源于stack exchange,提问作者Wayne
相关产品推荐
相关产品推荐

