Powershell Invoke-Webrequest Body Rest-API - powershell

I wanted to add a Body in a Invoke-Webrequest
I am a newbie in Powershell Rest API Request...
So here is the example what i need to create it in a Body into a Powershell Scipt:
Body:
{
"select":[
"SERVICE.ID"
],
"parameter":[
{
"field":"SERVICE.NAME",
"value":HOSTNAME
}
]
}
How can i convert these into a Powershell Body ??

You can use a JSON Body directly with Invoke-Webrequest
$Body = #'
{
"select":[
"SERVICE.ID"
],
"parameter":[
{
"field":"SERVICE.NAME",
"value": "HOSTNAME"
}
]
}
'#
Invoke-WebRequest -Uri [...] -Method Post -Body $Body
And you can convert it to PS Object using ConvertFrom-Json like this:
$Obj = $Body | ConvertFrom-Json
$Obj
select parameter
------ ---------
{SERVICE.ID} {#{field=SERVICE.NAME; value=HOSTNAME}}

Related

Looping through PSObject from JSON response

I am running Invoke-RestMethod to get a response from an API. That response is in JSON format and I am trying to figure out how to get access to the individual properties in my Powershell code.
Given these two lines:
$response = Invoke-RestMethod -Uri $paymentJournalUri -Method 'GET' -Headers $headers | ConvertTo-Json
Write-Host $response
my output looks like this:
{
"#odata.context": "https://api....yments",
"value": [
{
"#odata.etag": "W/\"JzI....Dsn\"",
"id": "b86ac....8fab",
"journalId": "59....b3ca",
"journalDisplayName": "EFT",
"lineNumber": 30000,
"vendorId": "a4c...552",
...
So how can I loop over the 'value' array and get access to each of those properties?
I have tried something like this:
$PSObj = $response | ConvertTo-Json
#Write-Host $PSObj
$PSObj.value | ForEach-Object {
Write-Host $_.journalDisplayName
}

Powershell reading Json

I'm getting the following response through an API and I'm trying to pull data out of the JSON response. I'm interested in only pulling the clone.href when clone.name = ssh.
response: {
"links": {
"clone": [
"#{href=ssh://sampleurl.com; name=ssh}",
"#{href=https://sampleurl.com; name=http}"
],
"self": [
"#{href=https://sampleurl.com}"
]
}
}
I'm using the following to call the API:
Invoke-RestMethod -Uri $uri -Headers $Header -Method POST -Body $Body|ConvertTo-Json
You can do this:
$result = Invoke-RestMethod -Uri $uri -Headers $Header -Method POST -Body $Body|ConvertTo-Json
$href = $result.links.clone | Where-Object Name -eq ssh | ForEach-Object href
$href # Output to console
This uses Where-Object to filter the clone array and ForEach-Object to extract the href property, using short form of ForEach-Object -MemberName href.
Alternatively you can use the following syntax:
$href = $result.links.clone.Where{ $_.Name -eq 'ssh' }.href
It uses PowerShell intrinsic method Where for filtering.

Powershell Invoke-RestMethod POST has issues with json

I am trying to use a REST API to configure some alerts in RecoverPoint for Virtual Machines (RP4VM). I am trying to enter multiple filters at the same using json. The json file looks like this:
[
{
"JsonSubType": "SystemEventLogsFilter",
"level": "WARNING",
"scope": "NORMAL",
"eventsIDs": [],
"filterUID": {
"id": 1570417688566256135
},
"name": "RPA_issue",
"topic": "RPA",
"groupsToInclude": null
},
{
"JsonSubType": "SystemEventLogsFilter",
"level": "WARNING",
"scope": "ADVANCED",
"eventsIDs": [],
"filterUID": {
"id": -1728986321682574312
},
"name": "cluster_events",
"topic": "CLUSTER",
"groupsToInclude": null
}
]
When I try to run the script I get an error:
Unexpected token (START_ARRAY), expected START_OBJECT: need JSON Object to contain As.PROPERTY type information (for class com.emc.fapi.version5_2.commons.SystemEventLogsFilter)
at [Source: org.apache.catalina.connector.CoyoteInputStream#75b592c2; line: 1, column: 1]
If I remove the square brackets it does the first value but not the second. Is this an issue with my code or an issue with theirs?
The script:
$rp4vmcl = import-csv -Path .\test_clusters.csv
$credential = Get-Credential
$username = $credential.GetNetworkCredential().UserName
$password = $credential.GetNetworkCredential().password
$credPair = "$($username):$($password)"
$encodedCredentials = [System.Convert]::ToBase64String([System.Text.Encoding]::ASCII.GetBytes($credPair))
$headers = #{
Authorization = "Basic $encodedCredentials";
"Accept" = "application/json";
"Content-Type" = "application/json"
}
$comp = "/system/event_logs_filters"
$json = Get-Content .\event_log_filter.json -Raw
foreach ($s in $rp4vmcl) {
$cluster = $s.cluster_name
$uid = $s.cluster_uid
$curl = $s.cluster_url
$url = "$curl$comp"
$cluster
$results = Invoke-RestMethod -Method POST -uri $url -SkipCertificateCheck -Headers $headers -Body $json
}
If the recipient expect one Call per Json Object it will not be able to handle arrays. It's totally dependant from the implementation of the webservice. Btw, better change the body:
$results = Invoke-RestMethod -Method POST -uri $url -SkipCertificateCheck -Headers $headers -Body ([System.Text.Encoding]::UTF8.GetBytes($json))
Try this first, and if this is doesnt help, loop through the elemnts and call the webservice individual:
$jsonObject = $json | ConvertFrom-Json
$results = #()
$jsonObject | foreach {
$json = $_ | ConvertTo-Json -Depth 99
$results += Invoke-RestMethod -Method POST -uri $url -SkipCertificateCheck -Headers $headers -Body ([System.Text.Encoding]::UTF8.GetBytes($json))
}
Btw, the invoke-restmethod is buggy in powershell < 6 Version, so if youre will with the standard V5 Windows Version, check the response headers via invoke-webservice, and if the response header is:
"application/json"
and not
"application/json; charset=utf-8"
powershell will misinterpret this as a windows encoding. So if youree experiencing encoding issues, you have four options:
1.) if you can modify the webservice, change the response header
2.) switch to a newer powershell version (v7 is recommended)
3.) build your own webservice call directly via the .net cmdlets
4.) use the invoke-webservice, write the answer directly into a file with the OutFile Paramater
see also:
Powershell Invoke-RestMethod incorrect character

Invoke-RestMethod convert hashtable to json array

I'm trying to send a request to an API that requires the body to be a json array. How can I convert the parameters hash table into a json array?
$parameters =#{
"sn" = "CND3210W9M"
"pn" = "D5H49AV"
}
$post = Invoke-RestMethod -Uri "https://blah.com/queries" -Method Post -Body ($parameters | ConvertTo-Json) -Headers $headers -ContentType 'application/json'
The API example shows the array below as a valid body
[
{
"sn": "CND3210W9M",
"pn": "D5H49AV"
}
]
If your request is expecting valid json, it might look something like this:
$body = #{
parameters =
#( # Make this an array
#{ # of hashtables
"sn" = "CND3210W9M"
"pn" = "D5H49AV"
} ) }
$body | ConvertTo-Json
Output:
{
"parameters": [
{
"pn": "D5H49AV",
"sn": "CND3210W9M"
}
]
}
#Eris, I tried using your code but it returned an extra {} which the API didn't like.
In the end I ended up just using a here string and moving on. It's not very elegant but couldn't get the API to respond properly otherwise.
$body = #"
[
{
"sn": "$sn",
"pn": "$pn"
}
]
"#

Error 400 bad request when creating a group calendar event in powershell with Microsoft Graph API

I'm trying to create an event in a calendar in an Office 365 group via powershell.
This is my first experience to do this type of programming so sorry if my question will be very basic :-)
First, I created a simple json file (calendar.json)
{
"start":
{
"dateTime":"2017-03-12T17:00:00.0000000",
"timeZone":"UTC"
},
"end":
{
"dateTime":"2017-03-12T17:30:00.0000000",
"timeZone":"UTC"
},
"responseStatus": {
"response": "None"
},
"iCalUId": "null",
"isReminderOn": false,
"subject": "Test Event created from API"
}
Then I create the event with these steps:
Use a tested powershell function that give me the token
Add header with this code:
$headers = #{}
$headers.Add('Authorization','Bearer ' + $token.AccessToken)
$headers.Add('Content-Type',"application/json")
Because I'm starting now, I convert the json file in an object and then the object in json (I know, it's quite stupid, but I've done so beacuse I have no knowledge of json and how convert without error in powershell code)
$json = ConvertFrom-Json -InputObject (Gc 'C:\Users\mmangiante\OneDrive - Interactive Media S.p.A\Office 365\calendar.json'-Raw)
$body = ConvertTo-Json $json
Call the Invoke-RestMethod
response = Invoke-RestMethod 'https://graph.microsoft.com/v1.0/groups/768afb0c-bafd-4272-b855-6b317a3a9953/calendar/events' -Method Post -Headers $headers -Body $json
What is returned is a 400 bad request.
It's the same error of Sending Microsoft Graph request events returns 400
Given the answer given to that question I modified my code to return the error:
try{$restp=Invoke-RestMethod 'https://graph.microsoft.com/v1.0/groups/768afb0c-bafd-4272-b855-6b317a3a9953/calendar/events' -Method Post -Headers $headers -Body $json
} catch {$err=$_}
$err
like suggested in How do I get the body of a web request that returned 400 Bad Request from Invoke-RestMethod but I found nothing of interest.
The only thing that I found is that, at the time of writing, the Invoke-RestMethod doesn't return the full response as in this https://github.com/PowerShell/PowerShell/issues/2193
I suppose my json is not "well formed", but I don't know why.
Does anyone have a suggestion?
This formatting has worked for me in the past. Let me know if this resolves your issues:
$headers = #{
"Authorization" = ("Bearer {0}" -f $token);
"Content-Type" = "application/json";
}
$body = #{
Name1 = 'Value1';
Name2 = 'Value2';
}
$bodyJSON = $body | ConvertTo-Json
Invoke-RestMethod -Method Post -Uri <API HERE> -Headers $headers -Body $bodyJSON -OutFile $output
Thanks Shawn,
I tried your suggestion but without luck; I have done other test with 2 other api and found discordant results.
The first test is to use the graph api related to contact, creating a contact as in https://graph.microsoft.io/en-us/docs/api-reference/v1.0/api/user_post_contacts
I created the powershell representation of the sample json:
$contactbody = #{
givenName = 'Ciccio';
surname = 'Patacca';
emailAddresses = #(
#{
address = 'cicciopatacca#cicciociccio.com'
name = 'Ciccio Patacca'
}
)
businessPhones = (
'+39 555 123 4567'
)
}
and then converted in json
$contactbody = $contactbody | ConvertTo-Json
I retrieved from Azure Portal the object ID related to my user in my company and so I call the rest method:
$response = Invoke-RestMethod 'https://graph.microsoft.com/v1.0/users/e37d2dbe-bdaf-4098-9bb0-03be8c653f7d/contact' -Method Post -Headers $headers -Body $contactbody
The final result is a 400 bad request error.
So, I tried another example and reused some code retrieved from a google search.
This time I copied the powershell json representation as in the sample and converted:
$body = #{"displayName"="ps-blog"; "mailEnabled"=$false; "groupTypes"=#("Unified"); "securityEnabled"=$false; "mailNickname"="ps1" } | ConvertTo-Json
and, as stated in https://graph.microsoft.io/en-us/docs/api-reference/v1.0/api/group_post_groups I called the rest method
$response = Invoke-RestMethod 'https://graph.microsoft.com/v1.0/groups' -Method Post -Headers $headers -Body $body
and this worked.
So I thought that the previously powershell representations of the sample with the error were not correctly formed (even if when I printed it they are equal to the samples on the graph api); for test, I rewritten the last powershell of the body as this:
$body = #{
displayName = 'TestGraphGroup';
mailEnabled = $true;
groupTypes = #('Unified')
securityEnabled = $false;
mailNickname = 'TestGraphGroup'
}
$body = $body | ConvertTo-Json
and invoked last method: it worked again.
So, where I'm doing wrong?
A new SDK was released that makes this easier.
Checkout instructions on how to use it here