Convert multi header and json input curl command in to powershell - json

I have the below curl command which i am trying to convert to powershell, but i am not sure on how to handle the multi header inputs and the JSON input
Any help is highly appreciated
curl --location --request POST 'https://anypoint.studio.com/cloudhub/api/v2/applications' \
--header 'X-ANYPNT-ENV-ID: 4a96abfd4f5237cf1b64' \
--header 'X-ANYPNT-ORG-ID: bc0d-3b9fd79234ad' \
--header 'Authorization: Bearer 3esede-a44b-29ab8841b508' \
--form 'file=#"/C:/Users/pgi/Downloads/eafdc-flow-proxy-v1.2.jar"' \
--form 'appInfoJson="{
\"domain\": \"testproxy-test\",
\"Version\": {
\"version\": \"4.4.0\"
},
\"properties\": {
\"platform.client_id\": \"8f95qw3sa4b679aaa699cf0f5c6b6\",
\"secure.key\": \"sYf%NJ7F^y&3lNRH*D$#\",
\"env\": \"dev\",
\"platform.client_secret\": \"acF0JHFUEFH8829a481D9c37EF364be7a\"
},
\"propertiesOptions\": {
\"secure.key\": {
\"secure\": true
},
\"anypoint.platform.client_secret\": {
\"secure\": true
}
},
\"region\": \"us-west-1\",
\"monitoringEnabled\": true,
\"monitoringAutoRestart\": true,
\"workers\": {
\"amount\": 1,
\"type\": {
\"name\": \"Micro\",
\"weight\": 0.1,
\"cpu\": \"0.1 vCores\",
\"memory\": \"500 MB memory\"
}
},
\"loggingNgEnabled\": true,
\"persistentQueues\": true
}"' \
--form 'autoStart="true"'

You can replace curl with Invoke-WebRequest and parse the JSON with ConvertFrom-Json.
$r = Invoke-WebRequest -Uri $uri -Method Post -Body $body
$j = ConvertFrom-Json $r.Content
I've left out setting the value of $uri and $body. I hope this is enough for you to get started with.
Update
First response was written too quickly. You probably need to pass header and body.
Like curl, Invoke-Webrequest is powerful and complex. You can find online documentation here:
https://learn.microsoft.com/en-us/powershell/module/microsoft.powershell.utility/invoke-webrequest?view=powershell-7.2&WT.mc_id=ps-gethelp
You'll need to use the Headers and Body Parameters:
-Headers <System.Collections.IDictionary>
Specifies the headers of the web request. Enter a hash table or dictionary.
To set UserAgent headers, use the UserAgent parameter. You can't use this parameter to specify User-Agent or cookie headers.
Content related headers, such as Content-Type is overridden when a MultipartFormDataContent object is supplied for Body .
-Body <System.Object>
Specifies the body of the request. The body is the content of the request that follows the headers. You can also pipe a body value to Invoke-WebRequest.
The Body parameter can be used to specify a list of query parameters or specify the content of the response.
When the input is a GET request and the body is an IDictionary (typically, a hash table), the body is added to the URI as query
parameters. For other request types (such as
POST), the body is set as the value of the request body in the standard name=value format.
The Body parameter may also accept a System.Net.Http.MultipartFormDataContent object. This facilitates multipart/form-data requests. When a MultipartFormDataContent object is supplied for Body , any Content related headers supplied to the ContentType , Headers , or WebSession parameters is overridden by the Content headers of the MultipartFormDataContent object. This feature was added in PowerShell 6.0.0.
Looks like you'll have to create a MultipartFormDataContent object. Note this was added in PowerShell Version 6, so you can't use the Windows built-in default version 5. If you haven't already, you'll probably need to install the latest version of Version 7. (I use version 7 and it's great.)
So for headers you'd create something like:
$headers = [ordered]#{
'X-ANYPNT-ENV-ID' = '4a96abfd4f5237cf1b64'
'X-ANYPNT-ORG-ID' = 'bc0d-3b9fd79234ad'
'Authorization' = 'Bearer 3esede-a44b-29ab8841b508'
}
Then make a call like:
$r = Invoke-WebRequest -Uri $uri -Method Post `
-Headers $headers -Body $myMultipartFormDataContent
I haven't used MultipartFormDataContent so I'll leave that up to you. I hope this provides you with a good starting point.

Related

Convert Curl to Invoke-RestMethod

Problem
I am having a hard time converting a curl call into a Powershell Invoke-RestMethod call as Powershell doesn't really thow the most informative error messages (if any).
Curl call (Ubuntu)
token = "djsakldsakldjaslda"
host = "https://lalala.azuredatabricks.net/"
curl -X POST -H "Authorization: Bearer $(token)" $(host)/api/2.0/clusters/create -d $(cat my_file.json)
Invoke-RestMethod call (Powershell)
$token= "djsakldsakldjaslda"
$host = "https://lalala.azuredatabricks.net/"
Invoke-RestMethod -Method Post -Uri $host/api/2.0/clusters/create -Headers #{"Authorization" = "Bearer " + $token} -Body $(get-content my_file.json -raw | ConvertFrom-Json)
I have various formats for the body, but no matter what I send, I just get some HTML back for a login page. On Ubuntu with Curl everything works perfectly.
NOTE:
The problem seemed to be that PowerShell cannot handle double-"/" as in "https://lalala.azuredatabricks.net//api/2.0/clusters/create".
The strange part is that Invoke-RestMethod gets to the login page, but fails from there.
Use -InFile to upload a file. Don't forget to set the content type.
Wrapped for legibility (escaping the EOL works as line continuation in PowerShell, it looks funny because StackOverflow syntax highlighting cannot handle it):
Invoke-RestMethod `
-Method Post `
-Uri "$host/api/2.0/clusters/create"
-Headers #{
Authorization = "Bearer $token"
} `
-Infile my_file.json
-ContentType "application/json"
The body is expected to be JSON format, when you take the file and add the | ConvertFrom-Json the content becomes a PowerShell object.
So, you can remove the | ConvertFrom-Json and it should work :)

LWP response JSON values are empty

I'm trying to run GET method using LWP and CURL (unix command) to get the content in JSON format, I'm seeing the complete content only in CURL command but the LWP response is showing valid JSON but with empty values.
REQUEST
LWP
my $ua= LWP::UserAgent->new();
my $host='https://sample.com/iersiefhsiof';
$ua->default_header('Content-Type' => 'application/json');
$ua->default_header('Authorization' => 'XXXXXXXXXXXXXXxx');
$ua->default_header('Accept' => 'application/json');
my $response=$ua->get($host);
$res=$response->content();
print ($res);
CURL
curl -H "Accept: application/json" -H "Content-Type: application/json" -H 'Authorization:XXXXXXXXXXXXXXX' -ikL 'https://sample.com/iersiefhsiof'
RESPONSE
LWP
{
"id":"",
"state":"",
"category":"",
"severity":"",}'`
CURL
`{"id":"iersiefhsiof","state":"open","category":"App","severity":"minor",}'`
Please help me to understand what I'm missing in LWP request to get the complete response content.
It is fixed now !
As per Header.pm , I should use ":" for custom header field name , if I'm not using that then it is converting the first characters as Uppercase and hence the header is missed.
unless ($field =~ /^:/) {
$field =~ tr/_/-/ if $TRANSLATE_UNDERSCORE;
my $old = $field;
$field = lc $field;
unless($standard_case{$field} || $self->{'::std_case'}{$field}) {
# generate a %std_case entry for this field
**$old =~ s/\b(\w)/\u$1/g;**
$self->{'::std_case'}{$field} = $old;
}
}
Refer: https://github.com/libwww-perl/HTTP-Message/blob/master/lib/HTTP/Headers.pm
':x-inf-route-key'=>'GetID'
Thanks :)

convert simple curl data request to powershell invoke-webrequest

Converting a very simple Plaid API curl data request to a powershell invoke-webrequest
what works:
curl -X POST https://tartan.plaid.com/balance \
-d client_id=client-id-value \
-d secret=secret-value \
-d access_token=access-token-value
What I'm trying unsuccessfully in Powershell
#test powershell api call
$hash = #{ client_id = "client-id-value";
secret = "secret-value"
access_token = "access-token-value"
}
$JSON = $hash | convertto-json
#Invoke-WebRequest -uri "https://tartan.plaid.com/balance" -Method POST -Body $JSON
This returns a plaid error 1100 (client id missing), so I know some API functionality is working, but it's not parsing input data correctly.
My biggest misunderstanding is how to translate a "curl -data" value into the proper Powershell parameter.
Is this a header value, body value? etc.
Unless the target url expects the POST body to be in JSON format, skip the ConvertTo-JSON step completely.
When the chosen HTTP method is POST, Invoke-WebRequest will automatically take all the keys in the hashtable supplied to the -Body parameter and construct a body payload similar to that of curl -d:
$POSTParams = #{
client_id = "client-id-value"
secret = "secret-value"
access_token = "access-token-value"
}
Invoke-WebRequest -Uri "https://tartan.plaid.com/balance" -Method POST -Body $POSTParams

Jira API POST and Invoke-RestMethod

Using Jira API 2 and PowerShell 5 Invoke-RestMethod I can successfully execute GET, but I keep getting a (400) Bad Request when attempting POST method to create an issue in my project.
$user = [System.Text.Encoding]::UTF8.GetBytes("me:mypassword")
$headers = #{Authorization = "Basic " + [System.Convert]::ToBase64String($user)}
$data = Get-Content D:\scripts\powershell\issue.txt
Invoke-RestMethod -Uri "https://agile.mycompany.com/rest/api/2/issue/" -Method POST -Headers $headers -ContentType "application/json" -Body $data
$data variable is well-formed JSON for Jira:
{
"fields":
{
"project":{"Key": "ITS"},
"summary":"Rest Test 1",
"issuetype":{"name": "Task"},
"assignee":{"key": "myusername"},
"priority":{"id": "3"},
"description":
"||Host Name||IP Address||Comments||
|some-pc|192.168.1.1| |",
"duedate": "2016-09-11"
}
}
I am the project owner, so this isn't a permissions issue.
Get-content is tricky, because it will actually result in a array of strings, where each line in your text file is an object in that array. The best way to get around that is probably using .Net's file read methods instead:
$data = [System.IO.File]::ReadAllText("D:\scripts\powershell\issue.txt")
btw, you can use a regular ps credential object instead of manually building your request header.
On a side note, it's always a good idea to test your api out using a tool such as postman. That will let you verify that you're posting valid json while not having to worry about your code doing strange things.
Problem solved. The issue was that I was CAPITALIZING the first letter of the field names. Apparently, Jira is very sensitive to CASE. Trondh - thank you for the recommendation to use postman. The errors that were getting generated by postman from the failed API calls were very concise.

Powershell & Curl - Using variables inside single-quoted JSON body

I am currently trying to automate new user creation in our Zendesk ticketing system using Powershell and Curl. The problem I am running into is that the curl json body is enclosed by single quotes and I need to reference a variable inside that body. Here is what I have:
$Firstname = "Test"
$Lastname = "User"
$email= 'user#test.org'
curl.exe https://mydomain.zendesk.com/api/v2/users.json -H "Content-Type: application/json" -X POST -d '{\"user\": {\"name\": \"$Firstname $Lastname\", \"email\": \"$email\"}}' -v -u myuser:mypass
This works fine if I type in regular text values inside the json, but how can I get it to recognize the variables $Firstname, $Lastname and $email?
Try the following:
$Firstname = "Test"
$Lastname = "User"
$email= 'user#test.org'
$json=#"
{\"user\": {\"name\": \"$Firstname $Lastname\", \"email\": \"$email\"}}
"#
curl.exe https://mydomain.zendesk.com/api/v2/users.json -d $json -H 'Content-Type: application/json' -X POST -v -u myuser:mypass
Using a double-quoted here-string #"<newline>...<newline>"# makes specifying embedded " instances easy (no escaping for the sake of PowerShell's own syntax required), while still expanding variable references - see the docs online or Get-Help about_Quoting_Rules.
You're clearly aware of the - unfortunate - additional need to \-escape the " instances, but just to explain why that is needed:
When passing arguments to an external program, PowerShell, after its own parsing and interpolation, conditionally wraps the resulting arguments in double quotes when concatenating them to form the argument list (a single string) to pass to the external utility. Unfortunately, this can result in embedded " instances getting discarded, and the only way to preserve them reliably is to \-escape them - see this answer for more information.
If you wanted to do it inline with a regular double-quoted string, you'd have to escape the " instances for PowerShell too (as `"), resulting in the awkward combination \`":
"{\`"user\`": {\`"name\`": \`"$Firstname $Lastname\`", \`"email\`": \`"$email\`"}}"
Afterthought:
Ryan himself points out in a comment that using a hashtable to construct the data and then converting it to JSON with ConvertTo-Json and feeding it to curl via stdin is an alternative that avoids the quoting headaches:
# Create data as PS hashtable literal.
$data = #{ user = #{ name = "$Firstname $Lastname"; email = "$adUsername#mydomain.org" } }
# Convert to JSON with ConvertTo-Json and pipe to `curl` via *stdin* (-d '#-')
$data | ConvertTo-Json -Compress | curl.exe mydomain.zendesk.com/api/v2/users.json -d '#-' -H "Content-Type: application/json" -X POST -v -u myuser:mypass
I think we can use here-string as json body for Invoke-RestMethod as below
$bufferTime = 5
$requestBody = #"
{
"size": 0,
"aggs": {
"last_x_min": {
"filter": {
"range": {
"#timestamp": {
"gte": "now-$($bufferTime)m",
"lte": "now"
}
}
},
"aggs": {
"value_agg": {
"avg": {
"field": "time-taken"
}
}
}
}
}
}
"#
$esResponse = Invoke-RestMethod -URI http://locahost:9200 -TimeoutSec 15 -Method Post -ContentType 'application/json' -Body $requestBody
This is the script I use to query Elasticsearch. No need to escape double quotes.