Invoke-RestMethod Range Error, Possible Bug? - json

Example code that's generating error
$Headers = #{
"Token" = $Token;
"Range" = $Range
}
Invoke-RestMethod -Uri $Uri -Method GET -Headers $Headers -WebSession $WebSession
Error: Invoke-RestMethod : The 'Range' header must be modified using the appropriate property or method.
I believe this is due to a PowerShell Bug. So now I'm attempting with the below example code, and get generic 401 (not authorized) error.
$request = [System.Net.WebRequest]::Create($uri)
$request.Method = "GET"
$request.Headers.Add("Token", $Token)
$request.AddRange("items", 0, 50)
$reader = New-Object System.IO.StreamReader($request.GetResponse().GetResponseStream())
$data = ConvertFrom-Json $reader.ReadToEnd()
The API requires a sessionId which I am clarifying in the first example code block. Is there a way to pass this in the above (second example code block)?
Any other reason for this 401 error? The first code block example retrieves data without issue if range isn't specified.

Related

"Unexpected token" or "JSON parse error - trailing comma" when doing API call with PowerShell

I have the following PowerShell API script:
$VMname = "abcd"
$IP_address = '2.2.2.2'
$url = "https://ansibletower.xyz.com/api/v2/job_templates/12321/launch/"
$token = "9998980fsfdfsdfdf"
$headers = #{Authorization = "Bearer $token"}
$contentType = "application/json"
$method = "POST"
#### $body = '{"extra_vars": {"vm_name": "abc", "vm_ip_address": "2.2.2.2"}}'
$body = '{"extra_vars":{"vm_name":'$VMname', "vm_ip_address":'$IP_address'}}'
Invoke-RestMethod -ContentType "$contentType" -Uri $url -Method $method -Headers $headers -Body $body
When I try it with manually predefined values in the body (see the commented body line above) - it works. But when I try it with variables $VMname and $IP_address, I get the error:
Unexpected token '$VMname', "vm_ip_address":'$IP_address'}}''
expression or statement.
And if I remove single quotes before and after variables VMname and IP_address I get:
{"detail":"JSON parse error - Expecting value: line 1
column...Possible cause: trailing comma."}
It is obviously a problem with syntax and / or formatting but I cannot find the solution. Does anyone know?
Use ConvertTo-Json for this:
$VMname = "abcd"
$IP_address = '2.2.2.2'
$body = ConvertTo-Json -Compress -Depth 9 #{
extra_vars = #{
vm_name = $VMname
vm_ip_address = $IP_address
}
}
$Body
{"extra_vars":{"vm_name":"abcd","vm_ip_address":"2.2.2.2"}}
Btw, it is probably not even required to serialize your body to Json as Invoke-Restmethod is supposed to take care of that:
-body
When the input is a POST request and the body is a String, the value to the left of the first equals sign (=) is set as a key in the form data and the remaining text is set as the value. To specify multiple keys, use an IDictionary object, such as a hash table, for the Body.

Handling Forward Slashes ("//") In URL PowerShell

I have a script that successfully parses data from a URL featuring JSON data.
However, when I add a new URL, that includes a colon (":") followed by two forward slashes ("//"), the code errors out. I feel it's due to how the script is interpreting ("://") in the URL.
I tried to replace ("://") with (":%2F%2F") in the URL parameter but, that did not work either.
Here's the script:
$cred = "[MY TOKEN]"
$headers = #{ Authorization = "Bearer $cred"; Accept = "application/json" }
$Output = Invoke-RestMethod `
-Method Get `
-Headers $headers `
-ContentType: "application/json" `
-Uri "https://www.example.com/id_user://234kjh-2234jh-45645l"
$result = $Output | ConvertTo-Json
$result
The error is as follows:
Invoke-RestMethod : {"baseType":"error","code":"ServerError","message":"users.com
\"234kjh-2234jh-45645l\" not found","status":500,"type":"error"}
At line:4 char:13
+ $Output = Invoke-RestMethod `

How do I fix a "cannot bind parameter 'uri'. Cannot convert the...." when converting json in powershell?

I am doing a Get-Weather project in powershell, where I pull data down from weatherapi.com . I am able to successfully connect to the website using an API key but, when I try to convert it from json in the script it doesn't work. The error I get is:
"Cannot bind parameter 'Uri'. Cannot convert the..."
I have tried so many different ways to write this:
$response = Invoke-RestMethod -uri $url -Method Get -ResponseHeadersVariable r -StatusCodeVariable s
$weatherobject = ConvertFrom-Json $url
The request for the website is:
$url = Invoke-WebRequest "http://api.weatherapi.com/v1/forecast.json?key=$key&q=$location&days=$Days"
Any help would be very much apperciated, thank you!
The input of the ConvertFrom-Json cmdlet is a JSON object. Look at the document below for more information
https://learn.microsoft.com/en-us/powershell/module/microsoft.powershell.utility/convertfrom-json?view=powershell-7.1#description
$url = "http://api.weatherapi.com/v1/forecast.json?key=$key&q=$location&days=$Days"
$response = Invoke-RestMethod -uri $url -Method Get -ResponseHeadersVariable r -StatusCodeVariable s
$weatherobject = ConvertFrom-Json $response

Do-untill loop getting error (powershell)

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
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)

Only see ' rows=System.Object[] ' when enumerating JSON results in Powershell

I am returning a web service call that supposedly comes back in json format, and it does indeed appear to be valid json. As a string, it looks like this:
{"total":10,"rows":[{"process":"VISIO.EXE","computer_id":57,"last_used":"2016-04-20T01:34:09Z"},{"process":"VISIO.EXE","computer_id":64,"last_used":"2016-04-01T04:09:35Z"},{"process":"VISIO.EXE","computer_id":181,"last_used":"2016-03-10T23:02:53Z"},{"process":"VISIO.EXE","computer_id":230,"last_used":"2016-04-19T05:31:32Z"},{"process":"VISIO.EXE","computer_id":237,"last_used":"2016-04-04T10:23:23Z"},{"process":"VISIO.EXE","computer_id":284,"last_used":"2016-04-15T10:54:29Z"},{"process":"VISIO.EXE","computer_id":8401,"last_used":"2016-05-12T21:55:39Z"},{"process":"VISIO.EXE","computer_id":9045,"last_used":"2016-05-12T08:10:40Z"},{"process":"VISIO.EXE","computer_id":9527,"last_used":"2016-05-11T00:49:11Z"},{"process":"VISIO.EXE","computer_id":10198,"last_used":"2016-05-06T06:59:29Z"}]}
I am trying to enumerate through the results, using the following script. I have tried all of the listed options 1-4 by uncommenting them out one at a time, but I cannot get more than one result to return.
Any ideas as to what I'm doing wrong?
$url = 'https://servername:port/api/sam/raw_app_usage_property_values?criteria={"and":[["process","=","visio.exe"]]}&limit=100&columns[]=process&columns[]=computer_id&columns[]=last_used'
# option 1. get all results, we see a full list of processes, full string returned
#$results = Invoke-WebRequest -Uri $url -Method GET -Headers $headers
#write-host $results
# option 2. get all results but break them down as part of the request. Only one result returned - #{total=10; rows=System.Object[]}
#$results = Invoke-WebRequest -Uri $url -Method GET -Headers $headers | ConvertFrom-Json
#write-host $results
# option 3. use a different method, which supposedly breaks down the request natively. Only one result returned - #{total=10; rows=System.Object[]}
#$results = Invoke-RestMethod -Uri $url -Method GET -Headers $headers
#write-host $results
# option 4. get content directly from file, only one result returned - #{total=10; rows=System.Object[]}
#$results = (Get-Content -path "C:\temp\raw_app_usage_property_values.json" -raw)
# is there anything in the array?
foreach ($result in $results) {
write-host $result
}
You seem to be getting the data back. Remember that the returned object has two properties, "total" and "rows".
Try:
foreach ($result in $results.rows) {
write-host $result
}