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.
Related
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
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.
I am using Invoke-RestMethod to make a post request to create a new document in CosmosDB. So far I followed theses links: Invoking Rest API using PowerShell - CosmosDb
, Add a Document to CosmosDB via the REST API using PowerShell and the official documentation.
My script retrieves an object like this from external service:
{
"ObjectId": "bd33f6b5-a066-4f0f-8d1b-291a6a2b90ba",
"Date": "\/Date(1589379850000)\/",
"Data": "{\"CreationTime\":\"2019-06-13T13:21:55\",\"Id\":\"e985f142-9359-4ebf-a319-7fa30b6c9987\", \"Fields\":[{\"Name\":\"foo\",\"Value\":\"bar\"}]}"
}
My objective is to post the field Data into cosmos. To this I extract this field using: $payload | Select-Object -expand Data. (I have the above json as PowerShell object). Since this extracted object is a string, I passed it to Invoke-RestMethod:
Invoke-RestMethod -Method $Verb -Uri $queryUri -Headers $headers -Body $payload
But I keeping getting a Bad Request status. I've also tried the following:
Invoke-RestMethod -Method $Verb -Uri $queryUri -Headers $headers -Body ($payload | ConvertTo-Json -Depth 100)
Invoke-RestMethod -Method $Verb -Uri $queryUri -Headers $headers -Body ($payload | ConvertFrom-Json | ConvertTo-Json -Depth 100)
Note: I was able to deserialize this string in C# using newtonsoft (I made a function to receive the PowerShell request). I also was able to insert this document via Postman. Looks like the issue is in the body of the request, since using the PowerShell code generated by Postman worked for me.
Edit: I am passing the content type ("application/json") in header of the request. It also fails when pass it I directly to the Invoke-RestMethod
Can someone give a light? To me it should work fine.
Your payload is missing the required id attribute:
Remember that the REST API is for the Core SQL API operations. Your payload seems to be for a Mongo document?
Make sure you are also passing the partition key. Reference: https://github.com/Azure/azure-cosmos-dotnet-v3/blob/master/Microsoft.Azure.Cosmos.Samples/Usage/PowerShellRestApi/PowerShellScripts/CreateItem.ps1
The data seems to be double converted, to extract it you can use this:
$json = '{"ObjectId": "bd33f6b5-a066-4f0f-8d1b-291a6a2b90ba", "Date": "\/Date(1589379850000)\/", "Data": "{\"CreationTime\":\"2019-06-13T13:21:55\",\"Id\":\"e985f142-9359-4ebf-a319-7fa30b6c9987\", \"Fields\":[{\"Name\":\"foo\",\"Value\":\"bar\"}]}"}'
$data = $json | ConvertFrom-Json | Select-Object -ExpandProperty "Data" | ConvertFrom-Json
$body = $data | ConvertTo-Json -Depth 10
So now $body is a proper JSON object which can be send by the Invoke-RestMethod:
Invoke-RestMethod -Method $verb -Uri $queryUri -Headers $headers -Body $payload -ContentType "application/json"
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.
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.