Do-untill loop getting error (powershell)

266 views Asked by At

Try to convert a web request from JSON but always get the below error:

Method invocation failed because [Microsoft.PowerShell.Commands.BasicHtmlWebResponseObject] does not contain a method named 'op_Addition'.
At C:\Users\gmicskei\Desktop\lastlogin_users_azureAD.ps1:39 char:17
+                 $QueryResults += $Results
+                 ~~~~~~~~~~~~~~~~~~~~~~~~~
    + CategoryInfo          : InvalidOperation: (op_Addition:String) [], RuntimeException
    + FullyQualifiedErrorId : MethodNotFound

Here is my code:

do {
            $Results = Invoke-WebRequest -Headers $authHeader1 -Uri $Uri -UseBasicParsing -Method "get" -ContentType "application/json"

        if ($Results.value) {
            $QueryResults += $Results.value
        } else {
            $QueryResults += $Results
        }

        $uri = $Results.'@odata.nextlink'
    } until (!($uri)) 

    $QueryResultsjson = $QueryResults | ConvertFrom-Json

Can you please advise?

Thanks, Gabor

1

There are 1 answers

2
mklement0 On BEST ANSWER

The objects returned by Invoke-WebRequest -UseBasicParsing are of type Microsoft.PowerShell.Commands.BasicHtmlWebResponseObject:

  • This type has no .Value property.

  • Using it as-is, which your code therefore does, is the source of the problem:

    • In the first loop iteration, $QueryResults += $Results stores the $Results variable as-is.
    • In subsequent loop iterations, += tries to "add" to an instance, but no such operation is defined for this type.

As an aside: In order to collect the $Results values in an array, $QueryResults would have to be initialized as an array before entering the loop, but note that building an array iteratively with += should be avoided, due to its inefficency - see this answer.


You can solve all problems by using Invoke-RestMethod instead, which automatically parses JSON responses into objects ([pscustomobject] instances):

$results = do {

  # Calls the web service and automatically parse its JSON output
  # into an object ([pscustomobject] instance).
  $result = Invoke-RestMethod -Headers $authHeader1 -Uri $Uri -Method "get" -ContentType "application/json"

  # Output the result at hand, to be collected across all
  # iterations in the $results variable being assigned to.
  # (.value is assumed to be a top-level property in the JSON data received).
  $result.value 
 
  # Determine the next URI, if any.
  # Since $result is now an *object*, property access should work.
  $uri = $result.'@odata.nextlink'

} while ($uri)