1

There's been a few similar posts on this but none quite the same (or they don't describe the issue clearly, if they are the same).

I've got a script which makes one API call using Invoke-RestMethod and then iterates over the result of that call making other calls with values from it. The value substitution etc is fine, and I can see (both by dumping the Uri out with Write-Host, and also from the API logs itself) that the calls are being made successfully.

If I do this:

$team = @{ "id" = 5 }
$response = Invoke-RestMethod -Uri https://theUri/$($team.id) -Headers $header -Method Get

then $response is populated as you'd expect and contains the json response from the API endpoint. Response time is a few hundred milliseconds.

If, on the other hand, I have an array of team objects and do this:

foreach ($team in $teams)
{
    $response = Invoke-RestMethod -Uri https://theUri/$($team.id) -Headers $header -Method Get
    Write-Host $response
}

then it iterates over the whole of the $teams array and outputs empty values on each of the Write-Host lines (the same occurs no matter what you do with it, I'm just using Write-Host as an example here; sending it to Select-Object etc shows it's still blank).

Is this deliberate? I assume no, because it's mad. I've got a temporary workaround by (yes, it's this awful...) writing out the results of the first Api call to a file, then iterating over that list calling a script that does the subsequent calls without the foreach loop in the script for each row. Is there a better way?

I've tried -DisableKeepAlive - no difference. I've tried setting the -TimeoutSec value to a small number, a big number, etc - no difference. I've tried -OutFile and that writes out a bunch of empty files.

It feels - without any evidence for this - that when called inside the loop it's waiting for the HTTP response (which is a 200) and then not downloading any of the response body.

This is Powershell 7.1.3, btw.

Cheers in advance!

  • 1
    I'm unable to replicate this behavior. `Invoke-RestMethod` is a blocking function call – Maximilian Burszley Mar 19 '21 at 14:01
  • @MaximilianBurszley - same thing happens for me whether I run it from inside VS Code in debug mode, inside VS Code without the debugger attached, or from a PowerShell command window. I've rebooted in case it was something weird, but haven't tried a different machine (yet). It acts as a blocking call when not inside a foreach loop but acts all async-y (technical term!) when inside the loop. I'm actually making 5 different calls to different endpoints inside the loop & all behave the same; the responses are empty objects at the end of each loop iteration and each iteration is almost instant. – Kevin Evans Mar 19 '21 at 14:18
  • (character limit, 2/2) I'd expect the time taken to loop over all 5 calls to be in the order of 1-2 seconds given each call takes 300-500 milliseconds when run outside the loop, but it's nowhere near that when run inside it. At least I know it's not intentional behaviour! – Kevin Evans Mar 19 '21 at 14:21
  • This could be rate-limiting or error behavior by the server. Try another server and/or hook up a packet sniffer like Wireshark. The possibility that the call logic itself is somehow different when run in a `foreach` is so much less probable compared to the alternatives that it can be safely ignored until other things have been eliminated. – Jeroen Mostert Mar 19 '21 at 14:57
  • What happens if really slow it down by putting `Sleep 5` before the Write-Host? – Scepticalist Mar 19 '21 at 15:07
  • @JeroenMostert - server side logs are fine, show the executions successfully succeeding in 300-500ms. No rate limiting (this is an internally owned API, the script is meant to be testing it) etc in place. – Kevin Evans Mar 19 '21 at 15:13
  • @Scepticalist - same effect. I put in some Sleep statements before it, after it, and before and after... same behaviour. – Kevin Evans Mar 19 '21 at 15:15
  • Interestingly I just had one of the guys at work run the same script; on his machine it behaves as expected - the Invoke-RestMethod call is blocking inside the loop and the response objects are populated with the appropriate data. Exact same script against the same server instance etc. – Kevin Evans Mar 19 '21 at 15:16
  • Make sure he;s on the same Powershell version, check traffic routing etc. As above comments you may need to use Wireshark to diagnose why your instance differs. – Scepticalist Mar 19 '21 at 15:25
  • So, in a fit of desperation I uninstalled and reinstalled PowerShell 7 this weekend. The problem no longer happens - the exact same script now blocks on those same calls, takes roughly 200-400ms on each one as you'd expect etc. I'm utterly at a loss. No changes to the API (I can see the last deployment date, it's before the weekend) etc. Mystified, and unhappy at not knowing why it happened - but it's resolved. Thanks for the help & suggestions everyone - was really helpful to know it's not intentional behaviour! – Kevin Evans Mar 23 '21 at 13:05
  • I'm observing the same problem, but from Windows PowerShell ISE. – Chris Gillum May 20 '21 at 00:58

0 Answers0