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
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;
}