PowerShell使用作业快速Ping子网

问题描述 投票:2回答:4

以下功能将使用PingRange 1 254 ping我的子网以检查IP:

function PingRange ($from, $to) {
    $from..$to | % {"192.168.0.$($_): $(Test-Connection -BufferSize 2 -TTL 5 -ComputerName 192.168.0.$($_ ) -quiet -count 1)"}
}

但是,这很慢,所以我想知道是否可以同时对它们全部执行ping操作,然后收集结果。我想这将意味着:

  1. 在每个Test-Connection上使用Start-Job(我可以做,那部分很容易)。

  2. 等待所有人完成。

  3. 仅收集ping成功结果并将其排序。

    function PingRange $from $to { $from..$to | % {Start-Job { "192.168.0.$($_): $(Test-Connection -BufferSize 2 -TTL 5 -ComputerName 192.168.0.$($_ ) -quiet -count 1)"} } Wait-Job *some test to check if all jobs are complete* Receive-Job some way to get each result, discard all failures, then sort and output to screen }

是否有一种简便的方法来完成等待工作,该等待工作将等待all生成的作业完成?

接收信息似乎也很棘手,当我尝试接收信息时,我总是会从Receive-Job中得到任何东西(通常是一个讨厌的错误)。希望有更多关于PowerShell Jobs的专家知道如何轻松获得这些结果?

powershell ping jobs
4个回答
1
投票

在PowerShell v7 +中,您将能够使用ForEach-Object -Parallel,通过使用不同的threadsparallel中运行命令,可以大大简化您的功能。 :

ForEach-Object -Parallel
  • function PingRange ($from, $to) { $from..$to | ForEach-Object -Parallel { "192.168.0.$_`: $(Test-Connection -BufferSize 2 -TTL 5 -ComputerName 192.168.0.$_ -quiet -count 1)" } -ThrottleLimit ($to - $from + 1) 2>$null -ErrorVariable err | Sort-Object } 默认为-ThrottleLimit,这意味着最多有5个命令并行运行,其他的<>,直到前一个命令完成后,池中的一个线程再次可用。

      这里,我选择允许
    • all

    线程并行运行,但是您必须测试该线程是否在实际中起作用-它可能适用于诸如此类的网络绑定任务,但不正确CPU限制任务的选择;请参见5以获取指导。
  • [this blog post使错误输出静音,但是2>$null收集变量-ErrorVariable err中的任何错误以供以后检查:
    • 注意:从v7.0开始,只有$err用于消除错误;不支持通用的2>$null参数(-ErrorAction-WarningAction-InformationAction都不支持);请注意,如果-PipelineVariable恰好生效,则2>$null会触发脚本终止错误。
  • 线程的输出将以

    无保证顺序

  • 到达,但将在到达时打印。
      考虑到您想对输出进行排序,在这里这不是问题。
    • 如果确实需要
    • 输入顺序
    • 的输出,请使用$ErrorActionPreference = 'Stop'参数,将结果作业对象与-AsJob一起使用以等待所有线程完成,此时可以调用Wait-Job来按输入顺序接收所有输出。

    在PowerShell

    v6-中,最好使用Receive-JobStart-ThreadJob,因为线程作业的开销要比基于后台进程的标准后台作业少得多。注意:PowerShell 6.x附带实现的Start-Job模块;在Windows PowerShell中,您可以按需安装它;例如。:ThreadJob

    Install-Module ThreadJob -Scope CurrentUser

    注意,需要function PingRange ($from, $to) {
      $from..$to | ForEach-Object {
        Start-ThreadJob -ThrottleLimit ($to - $from + 1) { 
          "192.168.0.$using:_`: $(Test-Connection -BufferSize 2 -TTL 5 -ComputerName 192.168.0.$using:_ -quiet -count 1)" 
        }
      } | Receive-Job -Wait -AutoRemove -ErrorAction SilentlyContinue -ErrorVariable err |
          Sort-Object 
    }
    来引用封闭的$using:_脚本块的ForEach-Object变量。

    虽然$_使用

    线程

    (运行空间)运行其作业,但是可以使用标准作业cmdlet(即Start-ThreadJobWait-JobReceive-Job)管理所得的作业对象。

    1
    投票
    Remove-Job返回作业中命令的每个输出。这意味着,如果在作业内部抛出错误,则错误也会显示在Receive-Job旁边。要解决此问题,请通过例如管道连接到receive-job来紧密控制命令生成的输出。

    0
    投票
    您可以使用它添加asJob参数:

    0
    投票
    您可以像这样测试整个列表。如果大多数都启动,它将非常快。如果IP已启用,则ResponseTime属性将为非null。
    © www.soinside.com 2019 - 2024. All rights reserved.