11

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.

U r s u s
  • 6,680
  • 12
  • 50
  • 88
  • Might be a duplicate of http://stackoverflow.com/questions/8919414/powershell-http-post-rest-api-basic-authentication – David Brabant Jul 23 '14 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. – U r s u s Jul 23 '14 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}'` – Frode F. Jul 23 '14 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. – U r s u s Jul 24 '14 at 08:25
  • if anyone needs answer for this please refer : http://stackoverflow.com/a/23556669/4192663 – chathura rupasinghe Apr 01 '17 at 20:11

2 Answers2

14

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.

Therefore, even though:

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

should work, it doesn't, due to a long-standing bug; instead, you must use:

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

See this answer for more information.

mklement0
  • 382,024
  • 64
  • 607
  • 775
4

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
Raf
  • 9,681
  • 1
  • 29
  • 41
  • 2
    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"}*` – U r s u s Jul 24 '14 at 09:29
  • Edited the answer to add required header. – Raf Jul 24 '14 at 09:45
  • Your edited answer returns the error I mentioned in the 'What I've tried' section above. Any idea why? – U r s u s Jul 24 '14 at 09:51
  • 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. – Raf Jul 24 '14 at 10:01
  • Done that, but no joy. – U r s u s Jul 24 '14 at 10:16
  • Try using pure powershell, this could help: http://social.technet.microsoft.com/Forums/windowsserver/en-US/0085e084-cff3-422d-98c2-00d2cfeae815/cannot-post-data-to-http-page?forum=winserverpowershell – Raf Jul 24 '14 at 10:35
  • This answer doesn't work, because the JSON string must have its embedded `"` chars. escaped as `\"`, due to being passed to an _external program_ (`curl.exe`) - hard to believe, but true; see [this answer](https://stackoverflow.com/a/55604316/45375) for more information. – mklement0 Dec 04 '19 at 18:38