I was able to pass the dynamic json object if the object creation code is in single line.
Invoke-RestMethod -ContentType "application/json" -Method Post -Body '{ "name" : "azurefunctionapp2email", "appname": "Applicationnamehere", "requestedBy" : "requestedby", "reqdate" : "requestdate", "status" : "Successfully Deployed", "AppsCount" : "2" }' `
-Uri “https://implementurihere"
Since the dynamic JSON object in real world need be longer, I seperated created with new line and referenced in the above as below. But new line shift causes the json to break. I tried to pipe to ConvertTo-Json function and then found the output to hold '`\r\n' getting introduced:
$body = '{ "name" : "azurefunctionapp2email", `
"appname": "Applicationnamehere", `
"requestedBy" : "requestedby", `
"reqdate" : "requestdate",
"status" : "Successfully Deployed",
"AppsCount" : "2" }' `
Invoke-RestMethod -ContentType "application/json" -Method Post -Body $body `
-Uri “https://implementurihere"
Note: The above works if the $body is single line.
How to approach in such scenarios where we create a dynamic json , long file and feed?
Your example doesn't work because the last line containing a backtick which you have to omit.
You could use a here string to define your JSON so you don't need to seperate each line by a backtick:
$body =
#'
{ "name" : "azurefunctionapp2email",
"appname": "Applicationnamehere",
"requestedBy" : "requestedby",
"reqdate" : "requestdate",
"status" : "Successfully Deployed",
"AppsCount" : "2" }
'#
You could also consider to use a PowerShell hashtable to define your object which will allows you to use variables without the need of a format string:
$bodyObject = #{
name = 'azurefunctionapp2email'
appname = 'Applicationnamehere'
requestedBy = 'requestedby'
reqdate = 'requestdate'
status = 'Successfully Deployed'
AppsCount = '2'
}
$bodyObject | ConvertTo-Json
Related
I am using the Azure Management Rest API in Powershell , to create an NSG with some rule properties at the creation time. (yes I am aware that there is a PS module that can do that as well)
I have constructed the body of my PUT request as per the Microsoft documentation.
$url = "https://management.azure.com/subscriptions/$subid/resourceGroups/$rg/providers/Microsoft.Network/networkSecurityGroups/$nsg2" +"?api-version=2022-05-01"
$body = #{
"name" = "NSG-Test";
"location" = "useast";
"properties"= #{
"securityRules" = #(
#{
"name" = "rule1"
"properties"= #{
"protocol" = "*"
"sourcePortRange"= "*"
"destinationPortRange" = "80"
"sourceAddressPrefix"= "*"
"destinationAddressPrefix"= "*"
"access" = "Allow"
"priority" = 130
"direction"="Inbound"
}
}
)
}
} | ConvertTo-Json
try{
$Result = (Invoke-RestMethod -Uri $url -Headers $Headers -Method PUT -Body $body -Verbose -ContentType "application/json")
Write-Host $Result
}
Unfortunately I am greeted with the following error when executing this code :
{
"error": {
"code": "InvalidRequestFormat",
"message": "Cannot parse the request.",
"details": [
{
"code": "InvalidJson",
"message": "Error converting value \"System.Collections.Hashtable\" to type 'Microsoft.WindowsAzure.Networking.Nrp.Frontend.Contract.Csm.Public.Se
curityRule'. Path 'properties.securityRules[0]', line 4, position 75."
}
]
}
}
So the reason behind this is the nested dictionary #{"name"="rule1"..} inside the securityRules attribute value.
When removing this hashtable, the request executes and the NSG gets created, however without any properties of course.
Is there any way to circumvent this issue and have the REST API accept my JSON body with it's properties?
I tried to reproduce the same in my environment I got the same error as below:
To resolve this issue, Make sure to add -Depth 4 in the ConvertTo-Json .
When I added ConvertTo-Json -Depth 4 the error was resolved.
Code:
$AppId="<clientID>"
$AppSecret="75X8Q~2RXXXXXX"
$TokenURI="https://login.microsoftonline.com/2f2ebbbc-e970-XXXXXXXX/oauth2/token"
$Resource="https://management.core.windows.net"
#OAUTH
$BodyRequest="grant_type=client_credentials&client_id=$AppId&client_secret=$AppSecret&resource=$Resource"
$AccessToken=Invoke-RestMethod -Method Post -Uri $TokenURI `
-Body $BodyRequest -ContentType 'application/x-www-form-urlencoded'
$subid ="<SubscriptionID>"
$rg="imran"
$nsg2="nsg2"
#$Headers=#{}
#$Headers.Add("Authorization ","Bearer " + $AccessToken.access_token)
$RequestURI = "https://management.azure.com/subscriptions/$subid/resourceGroups/$rg/providers/Microsoft.Network/networkSecurityGroups/$nsg2" + "?api-version=2022-07-01"
$body=#{
"name" = "nsg2";
"location" = "East us";
"properties"= #{
"securityRules" = #(
#{
"name" = "rule1"
"properties"= #{
"protocol" = "*"
"sourcePortRange"= "*"
"destinationPortRange" = "80"
"sourceAddressPrefix"= "*"
"destinationAddressPrefix"= "*"
"access" = "Allow"
"priority" = 130
"direction"="Inbound"
}
}
)
}
} | ConvertTo-Json -Depth 4
$Headers=#{}
$Headers.Add("Authorization","Bearer " + $AccessToken.access_token)
$Result = (Invoke-RestMethod -Uri $RequestURI -Headers $Headers -Method PUT -Body $body -Verbose -ContentType 'application/json' )
Write-Host $Result
Result:
To confirm in portal rule1 is added successfully like below:
Using Powershell, I'm trying to PUT data into an API, but I'm having trouble using a variable within the JSON:
This code below does not generate an error from the API, but it PUTS the singer as, literally, "$var_currentsinger" and doesn't use the intended variable
$currentsinger = "Michael Jackson"
$headers.Add("Content-Type", "application/json")
$response = Invoke-WebRequest -Uri https://stackoverflow.com -Method PUT -Headers $headers -Body '{
"album": {
"name": "Moonlight Sonata",
"custom_fields": [{
"singer": "$currentsinger",
"songwriter": "Etta James"
}]
}
}'
This version below does not work, I assume because there are no quotes around the singer name. The API returns a value that the data is invalid
$currentsinger = "Michael Jackson"
$headers.Add("Content-Type", "application/json")
$response = Invoke-WebRequest -Uri https://stackoverflow.com -Method PUT -Headers $headers -Body '{
"album": {
"name": "Moonlight Sonata",
"custom_fields": [{
"singer": $currentsinger,
"songwriter": "Etta James"
}]
}
}'
The only thing I have tried is double quotes and triple quotes around the variable, but I either get the $currentsinger variable within the JSON and have it submit the variable value and not the variable name.
JSON requires double-quotes, so one example way to handle is by escaping the quotes or with a double-quoted here-string:
# here-string
$json = #"
"singer": $currentsinger,
"songwriter": "Etta James"
"#
# escaped
$json = "
`"singer`": $currentsinger,
`"songwriter`": `"Etta James`"
"
I have to use PowerShell to manage a Websense server via API. I am using Invoke-RestMethod and I am using a json format to make the changes. The comand to the server is as follows:
Invoke-RestMethod -Uri $uriCreate -Method Post -Headers $headers -Body ($jsonCat | ConvertTo-Json) -ContentType "application/json"
My variables are as follows:
$uriCreate = https://<ipaddress>:<port>/api/web/v1/categories
$headers = #{ Authorization = <credentials> }
$jsonCat = [ordered]#{
"Transaction ID" = $transID
Categories = #(
[ordered]#{
"Category Name" = $catName
"Category Description" = $catDesc
"Parent" = $catID
}
)
}
When I attempt to create the category via Powershell I get the following error returned:
Invoke-RestMethod : {
"Error" : [ "Could not parse JSON: Value is not convertible to Int." ]
}
Any idea what I am doing wrong?
I need to perform an Invoke-Webrequest with a specifically formatted body to add devices to a product. Here is what it looks like in json (example straight from the vendor's documentation):
$body_json = '{"datasource": [{
"parentId": "123456789000",
"name": "(name)",
"id": "(value)",
"typeId": 0,
"childEnabled": false,
"childCount": 0,
"childType": 0,
"ipAddress": "(ipAddress)",
"zoneId": 0,
"url": "(url)",
"enabled": false,
"idmId": 123456789000,
"parameters": [{
"key": "(key)",
"value": "(value)"
}]
}]}'
When I try to submit this in its json representation though, I get the following error:
Invoke-WebRequest : Can not deserialize instance of
com.vendor.etc.DataSourceDetail out of START_ARRAY token at [Source:
java.io.StringReader#22c614; line: 1, column: 1] At
C:\powershell_script_location\ps.ps1:114 char 9
+ $request = Invoke-WebRequest $url -Method Post -Headers $headers -Body $body_json - ...
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : InvalidOperation:
(System.Net.HttpWebRequest:HttpWebRequest) [Invoke-WebRequest],
WebException + FullyQualifiedErrorId :
WebCmdletWebResponseException,Microsoft.PowerShell.Commands.InvokeWebRequestCommand
The issue is with the format of the "parameters", parameter because the request submits fine when omitting the "parameters", but then the
devices that I'm adding are missing important parameter details.
Is there something wrong with Invoke-WebRequest, JavaScriptSerializer,
the vendor's code, or is this a user error? Let me know if any clarification is needed.
Unfortunately I don't know what a com.vendor.etc.DataSourceDetail instance looks like, as I am using an API and I don't have access to it directly.
Use Invoke-RestMethod instead of Invoke-WebRequest.
If you have the body as a string use:
Invoke-RestMethod -Uri http://your-url.com -Method POST -Body $body_json -ContentType "application/json"
If the body must be constructed from data/parameters, it might be easier to build a hashtable and convert it to json via ConvertTo-Json:
$body_json = #{
datasource = #(
#{
parentId = 123456789000
name = "name"
id = "value"
typeId = 0
childEnabled = $false
childCount = 0
childType = 0
ipAddress = "ipAddress"
zoneId = 0
url = "url"
enabled = $false
idmId = 123456789000
parameters = #( #{
key = "key"
value = "value"
})
})} | ConvertTo-Json -Depth 4
Invoke-RestMethod -Method 'Post' -Uri http://your-url.com -Body $body_json -ContentType "application/json"
Body Undefined
I couldn't understand why the req.body on the server was undefined (NodeJS Azure Function). It turns out I had a header that was an empty string.
It's not clear whether is was invoke-restmethod or azure-functions-core-tools that has a bug.
FWIW.
I'm trying to make a POST request to my server. Everything was fine until I decided to convert my object to JSON. Here's my code:
$postParams = #{
Login = "JonSnow66";
Password = "LetItSnow";
Email = "Jon.Snow#wall.com";
Name = "Jon Snow";
Desc = "I know nothing";
BirthDate = "1572 2 16";
Img = Get-Content -Path ./PH_img.txt | Out-String;
Type = "Admin";
}
Invoke-WebRequest -Uri http://localhost:3000/api/add/user -Method POST -Body (ConvertTo-Json $postParams -Compress)
Instead of returning regular JSON object like:
{
"Login": "JonSnow66"
...
}
It returns:
{{
"Login": "JonSnow66",
"BirthDate": "1572 2 16",
"Desc": "I know nothing",
"Name": "Jon Snow",
"Type": "Admin",
"Password": "LetItSnow",
"Img": "/9j/4<BASE64>/Z\r\n",
"Email": "Jon.Snow#wall.com"
}: ""}
I'm just a powershell beginner.
I think you need to specify ContentType on Invoke-WebRequest to be 'application/json'. If you don't specify a content type and are performing a Post then I think the cmdlet assumes you are submitting a form by default, and that might explain the extra { } characters you are seeing in the result.
Here's the modified code:
Invoke-WebRequest -Uri 'http://localhost:3000/api/add/user' -Method POST -ContentType 'application/json' -Body (ConvertTo-Json $postParams -Compress)