Piping the results of an invoke-restmethod in powershell - 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.

Related

Issue with for each loop with Invoke-RestMethod

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

Is there a Powershell equivalent to JavaScript Console Log?

I have a powershell script, which is calling a third party API and getting some response data back. I'd like to just log the response object to see what exactly is returning. I've tried
Write-Host ($item | Format-List | Out-String)
But that doesn't seem to be working. The API says it will return JSON but I'm not sure how to verify the return at all.
Full script is something like this.
$queryURL = "xyz"
$apiResponse = Invoke-RestMethod -Uri $queryURL -Method Get -ContentType "application/json" -Headers $header
You can pipe the Invoke-RestMethod to the ConvertFrom-Json cmdlet, this will convert the output into an object you can easily query:
https://learn.microsoft.com/en-us/powershell/module/microsoft.powershell.utility/convertfrom-json?view=powershell-7.1
$j = Invoke-WebRequest 'https://api.github.com/repos/PowerShell/PowerShell/issues' | ConvertFrom-Json
Calling $j will output the object created from the JSON.

Why do two files viewed through the Dropbox API have the same id?

I'm querying the Dropbox API using PowerShell successfully and getting all the files and folders using https://api.dropboxapi.com/2/files/list_folder. I'm putting the files and folders in separate arrays, but when trying to pull a single file by id out of them, there are a couple ids that reference two different files. Why is this?
Here's the snippet where it's happening:
try {
$request = Invoke-RestMethod -Uri $list_folder_url -Method Post -Headers $headers -ContentType "application/json" -Body (ConvertTo-Json -InputObject $body)
} catch {
$_.Exception.Response
}
$folders += $request.entries[0]
while ($request.has_more) {
$cursor = $request.cursor
$body = #{
cursor="$cursor"
}
$request = Invoke-RestMethod -Uri $folder_continue_url -Method Post -Headers $headers -ContentType "application/json" -Body (ConvertTo-Json -InputObject $body)
$folders += $request.entries | ? { $_.'.tag' -eq "folder"}
$files += $request.entries | ? { $_.'.tag' -eq "file"}
}
$file = $files | ? { $_.id -eq "id:**************" } ## Returns two very different files with the same id
Dropbox files IDs are case-sensitive, and some Dropbox file IDs may vary only by case.
In this code, you're using PowerShell's -eq operator, but according to the PowerShell documentation:
By default, all comparison operators are case-insensitive.
So, you may be getting multiple entries where the file IDs are only different by case. Try using -ceq instead of -eq:
To make a comparison operator case-sensitive, add a c after the -. For example, -ceq is the case-sensitive version of -eq.

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.

Powershell - Invoke-Webrequest on every row of a datatable

I have working powershell code that gets data from a database, I then loop through the rows, convert the row to Json using ConvertTo-Json and then call Invoke-WebRequest using the Json body that was created.
I was curious if I could simplify this task?
I know I can do something like this to create JSON out of each row:
($UserToUpdate.Tables[0].Rows | select $UserToUpdate.Tables[0].Columns.ColumnName ) | ConvertTo-Json
I Was thinking I might be able to do something like
($UserToUpdate.Tables[0].Rows | select $UserToUpdate.Tables[0].Columns.ColumnName ) | ConvertTo-Json | Invoke-WebRequest -Headers $headers -Method $method -Uri $uri -Body $body
However I am not sure how to use the results of the previous ConvertTo-Json as the $body in the Invoke-Webrequest.
I may be barking up the wrong tree, but thought it was worth trying!
The Powershell pipeline passes a full copy of your JSON Object through to Invoke-WebRequest, but Invoke-WebRequest doesn't know how to deal with it by default.
the easiest thing to do is pipe it into a Foreach-Object, (aliases of ForEach or just %, any work) and then operate on it from there.
... | ConvertTo-Json | Foreach { Invoke-WebRequest -Body $_ -Uri $Uri }
the piped object (in this case your JSON string) will be represented by the $_ variable within the {} scriptblock after the Foreach
hopefully that helps you get this working.