Powershell parallel processing : How to set value in a global varible

Viewed 333

I am calling an API 500 times with 10 parallel threads as part of load testing. I want to capture the result of API call in a global variable (a counter outside script block scope) so, that I can process further for validation.

Example- In below code , I want to check if all 500 API call is success or not.

PFB code snippet-

$invokeAPI =
{
  try {
    $bodyContent = Get-Content $Using:inputFilepath
    $Response = (Invoke-WebRequest -Method 'Post' -Uri $Using:headUri -Headers $Using:blobHeaders  -Body $bodyContent).StatusCode
    
    Write-Host -BackgroundColor Green "status Code :" $Response
  }
  catch [System.Exception] {
    Write-Host -ForegroundColor Red "Exception caught while invoking API :" $_.ErrorDetails.Message
    [int]$_.Exception.Response.StatusCode
  }
} 

1..500 | ForEach-Object -Parallel $invokeAPI -ThrottleLimit 10

<# ToDo...Capture API invocation Result to validate results#>
1 Answers

Updated:

Turns out I overcomplicated my initial answer by thinking jobs would be necessary. But it looks like they aren't. It appears it should be as simple as just outputting to a variable.

Sample script which will randomly test various HTTP statuses:

$invokeAPI = {
  try {
    $statusCode = 200,200,200,200,200,301,400,404,500 | Get-Random;
    (iwr "http://httpbin.org/status/$statusCode").StatusCode;
  }
  catch {
    [int]$_.Exception.Response.StatusCode;
  };
};

$statuscodes = 1..20 | % -Parallel $invokeAPI -ThrottleLimit 5;

$statuscodes;

OLD - I thought Jobs would be needed, turns out you don't, see edit above

Change this:

1..500 | ForEach-Object -Parallel $invokeAPI -ThrottleLimit 10

To this:

$output = 1..500 | ForEach-Object -Parallel $invokeAPI -ThrottleLimit 10 -AsJob | Wait-Job | Receive-Job
$output

Explanation:

  • -AsJob - Causes it to run each task as a PowerShell job in the background
  • Wait-Job - Wait for the jobs to finish
  • Receive-Job - Get the return data for all the jobs

By running -AsJob, it will store the results in the background. You can then retrieve the job, which is the stored results of that jobs output.

Thanks to: https://devblogs.microsoft.com/powershell/powershell-foreach-object-parallel-feature/

In fact, your example is very very similar to this example in the documentation: https://docs.microsoft.com/en-us/powershell/module/microsoft.powershell.core/foreach-object?view=powershell-7.1#example-13--run-in-parallel-as-a-job

Related