gpt4 book ai didi

powershell - PowerShell通过作业快速Ping子网

转载 作者:行者123 更新时间:2023-12-02 23:07:20 26 4
gpt4 key购买 nike

以下功能将使用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操作,然后收集结果。我想这意味着:
  • 在每个Test-Connection上使用Start-Job(我可以做到,这一部分很容易)。
  • 等待所有操作完成。
  • 仅收集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
    }

  • 是否有一种简便的方法来执行等待作业,该等待作业将等待所有生成的作业完成?

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

    最佳答案

    注意:在Windows PowerShell中,最简单的解决方案是使用Test-Connection -AsJob,如js2010's answer所示。但是,PowerShell [Core] 6+中不再支持-AsJob
    此答案侧重于与命令无关的方法,以实现与作业的并发。

    在PowerShell v7 + 中,您可以使用 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,这意味着最多可以并行运行5个命令,其他命令会排队等待,直到池中的一个线程再次可用为止。
  • 在这里,我选择允许所有线程并行运行,但是您必须测试一下它是否在实际中起作用-它可能适用于诸如此类的网络绑定(bind)任务,但对于CPU绑定(bind)不是正确的选择任务;请参阅this blog post以获取指导。
  • 2>$null使错误输出静音,但是-ErrorVariable err收集变量$err中的所有错误以供以后检查:
  • 注意:从v7.0开始,只有2>$null可以解决沉默错误;不支持常见的-ErrorAction参数(-WarningAction-InformationAction-PipelineVariable也不支持);请注意,如果2>$null恰好生效,则$ErrorActionPreference = 'Stop'可以触发脚本终止错误。
  • 线程的输出将以不保证的顺序到达,但将在到达时进行打印。
  • 既然您想要对输出进行排序,那么这不是问题。
  • 如果确实需要按输入顺序的输出,请使用-AsJob参数,将生成的作业对象与Wait-Job一起使用,以等待所有线程完成,此时,您可以调用Receive-Job接收输入顺序的所有输出。


  • 在PowerShell v6- 中,使用Start-ThreadJobStart-Job
    更好 ,因为线程作业的开销要比基于后台进程的标准后台作业少得多。

    注意:PowerShell 6.x附带了实现的ThreadJob模块。在Windows PowerShell中,您可以按需安装它;例如。: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脚本块的$_变量。

    虽然Start-ThreadJob使用线程(运行空间)运行其作业,但是可以使用标准作业cmdlet(即Wait-JobReceive-JobRemove-Job)管理生成的作业对象。

    Start-ThreadJob相比,使用Start-Job的优势:
  • Start-ThreadJob使用线程(通过PowerShell SDK在进程内的PowerShell运行空间)进行并发,而不是使用Start-Job的子进程。基于线程的并发速度更快,资源占用更少。
  • 有关Start-ThreadJob带来的性能提升的示例,请参见this answer
  • 线程作业的输出保留其原始类型。
  • 相比之下,在Start-Job作业中,输入和输出必须跨越进程边界,这需要在PowerShell远程处理中使用相同类型的基于XML的序列化和反序列化,在这种情况下,除了一些已知类型之外,类型保真度也会丢失:请参阅this answer
  • Start-ThreadJob的唯一一个(主要是假设性的)缺点是,崩溃的线程可能会使整个进程崩溃,但请注意,即使使用Throw创建的脚本终止错误也只会终止手头的线程(运行空间),而不是调用方。

    简而言之:仅在需要完全隔离进程时才使用Start-Job;也就是说,如果您需要确保以下几点:
  • 崩溃的作业不能使调用者崩溃。
  • 作业不应看到将.NET类型加载到调用者的 session 中。
  • 作业不能修改调用者的环境变量(在两种类型的作业中,都存在调用者的环境变量值,但在后台作业的情况下,它们是副本)。

  • 请注意,在Start-ThreadJobStart-Job作业中,就而言,作业均看不到调用者的状态:
  • 以交互方式或通过$PROFILE文件添加到调用者 session 中的变量,函数,别名或PSv5 +自定义类-作业不会加载$PROFILE文件。
  • 但是,线程作业的确看到了加载到调用者 session 中的.NET类(类型),并且与常规作业不同,它们不仅查看了调用者的环境变量的值,还可以对其进行修改。
  • 在PowerShell 6-中,作业的初始当前目录(文件系统位置)与调用者的目录不同。幸运的是,此问题已在v7 +中修复;一旦开始,作业将保持其自己的当前位置,并且对其进行更改不会影响 call 者。
  • 关于powershell - PowerShell通过作业快速Ping子网,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59434579/

    26 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com