14

Scenario

Among other things, Powershell 2.0 doesn't have the useful cmdlet Invoke-RestMethod.

I can't upgrade to version 3 and most examples I've found use version 3.

I have found this article, which seems, however, too complicated for my simple scenario.

I need to write a Powershell script that POSTs data in Json format, e.g.

{"Id":5,"Email":"test@com","DataFields":null,"Status":0} 

What I've tried

I am able to GET data. This is one of the scripts I have tried.

curl -v --user username:password https://api.dotmailer.com/v2/account-info 

But, when I try to POST, I can't figure out where to put the body of the message in the script. This is what I've got so far:

curl -v -X POST -H "Accept: application/json" -H "Content-Type: application/json" -u username:password -d '{"Id":5,"Email":"test@com","OptInType":0,"EmailType":0, "DataFields":null,"Status":0}' https://api.dotmailer.com/v2/contacts

which returns the following error:

{"message":"Could not parse the body of the request based on the content type \"application/json\" ERROR_BODY_DOES_NOT_MATCH_CONTENT_TYPE"}*

Question

Can anyone advise on how to POST Json data from Powershell using cURL?

Any pointers to why I get the error I mentioned in the Waht I've tried section would be much appreciated.

Thanks.

5
  • Might be a duplicate of stackoverflow.com/questions/8919414/… Commented Jul 23, 2014 at 15:17
  • @DavidBrabant I have seen that question and I don't think mine is a duplicate because I am not asking about basic authentication. Commented Jul 23, 2014 at 15:23
  • Ehmm. Actually, you are. "I need to write a Powershell script that POSTs data in Json format and uses basic authentication". AFAIK, to post JSON you should just convert it to bytes with UTF8 encoding and set application/json as content type. So cut and paste the relevant parts from the linked question, where $Post = '{"Id":5,"Email":"test@com","DataFields":null,"Status":0}' Commented Jul 23, 2014 at 16:15
  • @FrodeF. Fair enough, I've edited the question to avoid that (I do know how to write the basic auth bit). Also I've edited the title as it was unclear: I want to use cURL commands and run them in powershell. Commented Jul 24, 2014 at 8:25
  • if anyone needs answer for this please refer : stackoverflow.com/a/23556669/4192663 Commented Apr 1, 2017 at 20:11

3 Answers 3

20

Note that the question is about the curl.exe external program, not about PowerShell's Invoke-WebRequest cmdlet (which, unfortunately, is aliased to curl in later PowerShell versions, preempting calls to the external program unless the .exe extension is explicitly specified (curl.exe ...).

Unfortunately and unexpectedly, you have to \-escape embedded " instances in a string you pass as an argument to an external program in Windows PowerShell and PowerShell (Core) up to v7.2.x.

That is, the following works only in v7.3+:

# Only works in PowerShell 7.3+ '{"Id":5,"Email":"test@com","DataFields":null,"Status":0}' 

Windows PowerShell and PowerShell (Core) 7.2.x- require:

# Manual \-escaping of " required in # *Windows PowerShell* and *PowerShell (Core) 7.2.x-* '{\"Id\":5,\"Email\":\"test@com\",\"DataFields\":null,\"Status\":0}' 

See this answer for more information.

Sign up to request clarification or add additional context in comments.

Comments

6

From curl's man page it appears you need to use -d switch:

curl -v --user username:password -H "Content-Type: application/json" -d '{"Id":5,"Email":"test@com","DataFields":null,"Status":0}' https://api.dotmailer.com/v2/contacts 

7 Comments

Thanks, however the command you provided returns the following error: {"message":"Content type \"application/x-www-form-urlencoded\" is not supported. Please use one of: application/json,application/xml ERROR_CONTENT_TYPE_IS_NOT_SUPPORTED"}*
Edited the answer to add required header.
Your edited answer returns the error I mentioned in the 'What I've tried' section above. Any idea why?
Hmm, it is a valid json.. try adding square brackets around the body: -d '[{"Id":5,"Email":"test@com","DataFields":null,"Status":0}]' or double quotes around values -d '{"Id":"5","Email":"test@com","DataFields":"null","Status":"0"}' or both.
Done that, but no joy.
|
0

I wanted to use a variable for auth token, so shell history won't be flooded with few hundred character long token strings. I have found the below solution for that.

For variable expansion in the JSON data you can't use single quotes.
You need to stick to double quotes and then both \ and " needs to be escaped with `:

-d "{`\`"Id`\`":$id,`\`"Email`\`":`\`"$email`\`",`\`"DataFields`\`":null,`\`"Status`\`":$status}" 

So the actual string passed to curl will be:

{\"Id\":5,\"Email\":\"test@com\",\"DataFields\":null,\"Status\":0} 

Using curl with --trace-ascii option, you can see the actual data sent in the log file:

=> Send data, 56 bytes (0x38) 0000: {"Id":5,"Email":"test@com","DataFields":null,"Status":0} 

Tested with PowerShell version 5.1.19041 (the default on my Windows 10 install).

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.