计算从 powershell 中的作业返回的对象?

Counting returned objects from jobs in powershell?

快速提问,我有一个简短的小脚本可以创建 2 个后台作业并 ping 一些网站,现在由于作业不能 return 变量显然我想我会尝试如下(这可能是一种愚蠢的做法,但没关系)。 现在奇怪的是它似乎有点工作?但是 returns 的计数远不及应有的值,它非常随机,有时停在 2,有时停在 3,谁能告诉我我做错了什么? $i 不应该等于 7 吗? 最初我想要并行运行空间,但几周来我一直在努力思考这个问题,我得出的结论是我显然太笨了。 我在这里尝试做的事情是否可行?

 = @('google.com', 'bing.com', 'yahoo.com', 'startpage.com')
 = @('reddit.com', 'facebook.com', 'nonexistent.com')

function run {
  $pwd = Get-Location
  $i = 0

  $list = {
    function list1 (, $pwd) {
      foreach ($ping in ) {
        "&"
        if (Test-Connection -ComputerName $ping -Count 1 -Quiet) {
          "$pwd\" + "$ping"              
        } 
      } 
    }
    function list2 (, $pwd) {

      foreach ($ping in ) {
        "&"
        if (Test-Connection -ComputerName $ping -Count 1 -Quiet) {
          "$pwd\" + "$ping"
        } 
      } 
    }
  }

  echo "ping?`nyes or no`n"; $y = Read-Host
  if ($y -eq 'y') {
    Start-Job -ScriptBlock { list1 $using:1 $using:pwd } -InitializationScript $list
    Start-Job -ScriptBlock { list2 $using:2 $using:pwd } -InitializationScript $list

    While (Get-Job | Where-Object HasMoreData) {
      Get-Job | Where-Object HasMoreData | Receive-Job | Where-Object { $_ -notlike "&" } | Tee-Object -FilePath ping.txt -Append 
      Get-Job | Where-Object HasMoreData | Receive-Job | Where-Object { $_ -like "&" } | Foreach-Object { $i += 1 }
    }
    $i | Add-Content totalcount.txt
  }
}

修复脚本如下。

每次使用 Receive-Job 时,它都会从流中获取数据并显示出来。显示后,该数据将无法再通过 Receive-job 访问。要解决此问题,请使用 -Keep 开关或将从 Receive-Object 获取的数据存储在变量中以多次使用它。

if ($y -eq 'y') {
    Start-Job -ScriptBlock { list1 $using:1 $using:pwd } -InitializationScript $list
    Start-Job -ScriptBlock { list2 $using:2 $using:pwd } -InitializationScript $list

    While (Get-Job | Where-Object HasMoreData) {
      Get-Job | Where-Object HasMoreData | Receive-Job -Keep | Where-Object { $_ -notlike "&" } | Tee-Object -FilePath ping.txt -Append 
      Get-Job | Where-Object HasMoreData | Receive-Job | Where-Object { $_ -like "&" } | Foreach-Object { $i += 1 }
    }
    $i | Add-Content totalcount.txt
  }

不过,我会推荐一条与您的路线略有不同的路线。而不是在检查作业是否完成时获取数据,运行 循环并以这种方式输出,

if ($y -eq 'y') {
    Start-Job -ScriptBlock { list1 $using:1 $using:pwd } -InitializationScript $list
    Start-Job -ScriptBlock { list2 $using:2 $using:pwd } -InitializationScript $list

    While ((Get-Job | ? {$_.State -eq "Running" }).Count -gt 0) {
      # wait for all jobs to complete...
      Start-Sleep 1
    }

    #Once all the jobs are done, you can check the results.
    $data = Get-Job | Receive-Job | Where-Object { $_ -notlike "&" } 
    $data | Tee-Object -FilePath ping.txt -Append 
    $data.Count | Add-Content totalcount.txt

    Get-Job | Remove-Job # Dont forget to clean up.

  }