如何使用PowerShell多线程实现多网段同时Ping的资产发现功能
PowerShell多网段并行Ping扫描实现方案
普通的ForEach-Object和foreach循环都是单线程串行执行的,Ping操作大部分时间在等待网络响应,所以效率极低,你可以根据你的PowerShell版本选择以下方案实现并行扫描:
方案1:PowerShell 7+ 推荐方案(内置并行参数)
PowerShell 7及以上版本内置了ForEach-Object -Parallel参数,可以直接实现多线程并行处理,代码简洁易维护:
$Hosts = @{} $Time = Get-Date $Networks = @{ Network_X = 1..254 | ForEach-Object{ "192.168.50.$_"} Network_Y = 1..254 | ForEach-Object{ "192.168.63.$_"} Network_Z = 1..254 | ForEach-Object{ "192.168.65.$_"} } # 拉平所有网段的IP地址 $AllIPs = $Networks.Values | ForEach-Object { $_ } # 并行执行Ping扫描,可通过ThrottleLimit调整最大并发数 $AliveIPs = $AllIPs | ForEach-Object -Parallel { if (Test-Connection -ComputerName $_ -Count 1 -TimeoutSeconds 1 -Quiet -ErrorAction SilentlyContinue) { $_ } } -ThrottleLimit 64 # 存活IP存入结果哈希表 foreach ($ip in $AliveIPs) { $Hosts[$ip] = $true }
-ThrottleLimit参数控制最大并行线程数,内网扫描建议设置为32~128,避免网络拥塞,3个C段扫描通常3秒内即可完成。
方案2:兼容PowerShell 5.1 方案
如果使用的是Windows自带的PowerShell 5.1版本,可以直接用Test-Connection的批量处理能力,内部已优化并行逻辑,性能远高于自定义串行循环:
$Hosts = @{} $Time = Get-Date $Networks = @{ Network_X = 1..254 | ForEach-Object{ "192.168.50.$_"} Network_Y = 1..254 | ForEach-Object{ "192.168.63.$_"} Network_Z = 1..254 | ForEach-Object{ "192.168.65.$_"} } $AllIPs = $Networks.Values | ForEach-Object { $_ } # 批量执行Ping操作,内部自动并行处理 $PingResults = Test-Connection -ComputerName $AllIPs -Count 1 -TimeoutSeconds 1 -ErrorAction SilentlyContinue # 提取存活IP存入哈希表 foreach ($result in $PingResults) { $Hosts[$result.Address.IPAddressToString] = $true }
如果需要更高的自定义能力(比如自定义ICMP包、端口扫描联动),可以使用RunspacePool实现更精细的并发控制,性能比Start-Job方案高5~10倍,适合超大网段扫描场景。
内容的提问来源于stack exchange,提问作者Seyed Muhammad Alavi
相关产品推荐
相关产品推荐

