powershellpowershell-2.0

Powershell Receive-Job: Quota violation when invoking command (test-connection) as a job


I am trying to execute a cmdlet (test-connection) against multiple machines in parallel using the background jobs mechanism. The function below is fine until I pass more than 649 hostnames (at least on this machine) before an exception is thrown:

PS > .\test.ps1 .\650_hostnames.txt

Receive-Job : Quota violation
At H:\Development\Powershell\test.ps1:13 char:13
+ Receive-Job <<<< |
+ CategoryInfo " InvalidResult: (:) [Receive-Job], ManagementException
+ FullyQualifiedErrorId : JobStateFailed,Microsoft.PowerShell.Commands.ReceiveJobCommand

I would like to still execute the cmdlet as a background job for performance reasons, but control the number of jobs kicked off at a given time. I cannot control the input so I could get a list of many thousands to a few hundred. Any suggestions are appreciated!

test.ps1

$wkslist = $args[0]

function IsAlive {
  param(
      [Parameter(
      Mandatory = $true,
      Position = 0)]
      $computername
  )
  test-connection -count 1 -ComputerName $computername -TimeToLive 30 `
  -ThrottleLimit 10 -asJob |
  Wait-Job |
  Receive-Job |
  Where-Object { $_.StatusCode -eq 0 } |
  Select-Object -ExpandProperty Address
}

$ips = [System.IO.File]::ReadAllLines("$wkslist")
IsAlive -computername $ips

Solution

  • Looks like this has nothing to do with the fact that you're using jobs; it seems to be with the size of the input being passed to test-connection. I can reproduce the quota violation with this code:

    $ra = @(0..1000) | %{ $env:computername };
    test-connection -computername $ra;
    

    Seems to be something internal to test-connection, which ends up creating Win32_Ping WMI objects methinks. I can also get the code to work by slicing out part of the input array:

    $ra = @(0..1000) | %{ $env:computername };
    test-connection -computername $ra[0..500];
    

    Note that 650 does not appear to be a magic number - I can query up to about 800 hostnames without encountering the error.

    Since the exception is a Management exception and not a PowerShell internal exception, I'd say you've found one of the many magical limits of WMI. Also sounds like something that test-connection should manage internally, but doesn't. I've logged an issue on Connect here, if you want to upvote it: test-connection throws quota exception when passed large list of computernames

    I would try your job code as-is, but slice the list of hostnames into smaller segments:

    $i = 100;
    $j = 0;
    while( $i -le $ra.length )
    { 
       test-connection -computername $ra[$j..$i] ... ;
       $j = $i + 1;
       $i += 100;
    }