Issue with for each loop with Invoke-RestMethod - powershell

I am currently having issues creating a powershell script that taks to an api with Invoke-RestMethod and a loop, I have spent all day trying to figure out where i am going wrong but i have not managed to come up with something.
Here is the code that i am trying to make
$url = "/api/Rest/v1"
$Body = #{
Username = ""
Password = ""
Privatekey = ""
}
$apikey = Invoke-RestMethod -Method 'Post' -Uri $url/Authenticate -Body $body
$headers = #{
'Authorization' = $apikey
}
$allusers = Invoke-RestMethod -Uri $url/Users -Method Get -Headers $headers | ft -HideTableHeaders Id
foreach ($userid in $allusers)
{
echo $userid
Invoke-RestMethod -Uri $url/Users/$userid -Method Get -Headers $headers
echo "test"
}
I am not having issues with the veriables $apikey and $allusers as they seem to output what i need but i think my issue is to do with the outbut being in format table but i have tried other methods for the for each and i have no clue where i am going wrong
So i have tested the Invoke-RestMethod commands on there own and they work as exspected but when i try the script above i get the following.
Invoke-RestMethod : {"Message":"User with specified id was not found."}
the output of $allusers displays something like the following for the user ID
dce502ed-e4b6-4b5e-a047-0bf3b34e98c6
dc1e60c1-99a7-479a-a7d6-0dc618c8dd5e
1bd98bb0-a9ee-46b5-8e2e-0e3146aab6b3
AKA the following work with no issues and outputs what i need
Invoke-RestMethod -Uri $url/Users/1bd98bb0-a9ee-46b5-8e2e-0e3146aab6b3 -Method Get -Headers $headers
I would really appreciate some kind of guidance on this.

The standard advice applies:
Format-* cmdlets (such as Format-Table, whose built-in alias is ft) emit output objects whose sole purpose is to provide formatting instructions to PowerShell's for-display output-formatting system.
In short: only ever use Format-* cmdlets to format data for display, never for subsequent programmatic processing - see this answer for more information.
Therefore, remove the | ft -HideTableHeaders Id pipeline segment and use member-access enumeration to extract all .Id property values as data.
$allusers = (Invoke-RestMethod -Uri $url/Users -Method Get -Headers $headers).Id

Related

Correctly format JSON for Powershell Post? (Missing '=' operator after key in hash literal.)

I am attempting to use Powershell to perform some "POST" requests. However, I can't seem to get the JSON correctly formatted. How do I accomplish this?
>> $JSON=#{name:"TestName"}
>> Invoke-WebRequest -Uri http://localhost:7071/api/HttpTrigger1 -Method POST -Body $JSON
>> $response = Invoke-WebRequest -Uri "http://localhost:7071/api/HttpTrigger1" -Method Post -Body $JSON -ContentType "application/json"
ParserError:
Line |
1 | $JSON=#{name:"TestName"}
| ~
| Missing '=' operator after key in hash literal.
So, there are two ways you can do this:
The first, as suggested by Santiago, is
$json = '{name:"TestName"}'
$response = Invoke-WebRequest -Uri "http://localhost:7071/api/HttpTrigger1" `
-Method Post -Body $json -ContentType "application/json"
The second, using (roughly) the syntax you were using, is
#create a Powershell object (note the use of '=' instead of ':' for assignment)
#(such a simple example is not an improvement over the example above)
$json = #{ name = "TestName" } | ConvertTo-JSON
$response = Invoke-WebRequest -Uri "http://localhost:7071/api/HttpTrigger1" `
-Method Post -Body $json -ContentType "application/json"
The first method is certainly cleaner and more direct. The second is useful when the source data for the request comes as the result of manipulating Powershell objects, and you want to convert them for use in a web request.

Powershell API Data Extraction

I'm getting data back from an API for a system of ours using Powershell but it doesn't quite return it correctly. It is putting the data all under one header as seen below. I'm trying to extract the downloadLink part only
Tried converting to JSON to see if I could get anywhere else with it.
$token = ".."
$web = Invoke-RestMethod -uri $url -Method Get -Headers #{'Authorization' = $token}
echo $web
I get this as the outcome:
documents
---------
{#{documentName=Name.docx.pdf; downloadLink=https://app.xxx.com/api/docs/employees/111/shared/111}, {#{documentName=Name.docx.pdf; downloadLink=https://app.xxx.com/api/docs/employees/111/shared/111} ...
What I need to get is the downloadLink, but as it's all coming under the documents header I can't do a simple select or get on it.
Have you tried converting the results from JSON using ConvertFrom-Json? See the code example below.
Please note the change I made to the ContentType to the Invoke-RestMethod as well.
$token = ".."
$web = Invoke-RestMethod -uri $url -Method Get -ContentType "application/json" -Headers #{'Authorization' = $token}
$webResults = $web | ConvertFrom-Json
echo ($json | ConvertFrom-Json).downloadLink

Using powershell's Invoke-RestMethod cmdlet is only returning the word "success" as a result

I have written 2 scripts. One in python and one in powershell. Python is able to call a rest api and is returned the string "JSESSIONID=8kfv0fi1bc84gtw2xvnqsrt4;Path=/;Secure;HttpOnly ". When I use the following code in powershell, it returns "success". What am I doing wrong?
$getEncCode = "Er6TmdhXn09Y9C1I"
$dataPart1 = #{EncCode=$getEncCode}
$dataPart = $dataPart1 | ConvertTo-Json
$uri = "https://10.164.42.77:8092/getEnc/2252953/login"
[Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12
[System.Net.ServicePointManager]::ServerCertificateValidationCallback = {$true}
$result = Invoke-RestMethod -Method Post -Body $dataPart -uri $uri -ContentType "application/json"
Write-Host $result
Write-Host $result uses the $result.ToString() method to display that object as a string.
Likely there is more data there to show. Simply remove Write-Host to see it. Or do something like Get-Member -InputObject $result to see all immediate properties, methods etc.
Have a look at Printing object properties in Powershell to see other ways to deal with this.

Piping the results of an invoke-restmethod in powershell

I'm trying to write some powershell scripts for managing calls to an api, if I store the results in a variable I can iterate over them nicely, but I'd like to get an understanding of how to do it via piping.
This works
#This uri returns an array of objects that describe searches via the api
$reports = Invoke-RestMethod -uri $(root)/search -Method get -UseDefaultCredentials
foreach($r in $reports){
#can do stuff here
}
And if I do this I get the results displayed in the console window
$reports = Invoke-RestMethod -uri $(root)/search -Method get -UseDefaultCredentials | select
But I can't find a way of using the contents of the results after the pipe
#nothing displayed in the console for this
$reports = Invoke-RestMethod -uri $(root)/search -Method get -UseDefaultCredentials | ForEach-Object { Write-Host $_.Id }
What is the correct way of accesing the items in the piped results?
You are doing it right, just pipe it to the Foreach-Object cmdlet:
Invoke-RestMethod -uri $(root)/search -Method get -UseDefaultCredentials | ForEach-Object {
# $_ equals $r in your first example
}
If you assign the result to a variable, you will get the pipeline result of the Foreach-Object.

Assign a REST method response to a value

I have a powershell script and I am trying to assign the response of the GET method to value $a. Bellow I have my code but it does not work. How can I assign the response to this value?
Thank you
$a = Invoke-RestMethod -Uri "https://cloud.skytap.com/templates/555949" -Method GET -ContentType "application/json" -Headers $headers | out-null
Write-Host "$a"
You're sending your code to out-null, which removes the output!
Remove | Out-Null and you'll find that your assignment to $a is working. Or perhaps you'll find an error message instead. If so, let me know and I'll do my best to help you.
To clarify, you should be running this instead.
$a = Invoke-RestMethod -Uri "https://cloud.skytap.com/templates/555949" -Method GET -ContentType "application/json" -Headers $headers