64

I want to make a POST request in PowerShell. Following is the body details in Postman.

{
  "@type":"login",
  "username":"xxx@gmail.com",
  "password":"yyy"
}

How do I pass this in PowerShell?

Dan Atkinson
  • 11,391
  • 14
  • 81
  • 114
live2learn
  • 861
  • 2
  • 9
  • 16

3 Answers3

98

You should be able to do the following:

$params = @{"@type"="login";
 "username"="xxx@gmail.com";
 "password"="yyy";
}

Invoke-WebRequest -Uri http://foobar.com/endpoint -Method POST -Body $params

This will send the post as the body. However - if you want to post this as a Json you might want to be explicit. To post this as a JSON you can specify the ContentType and convert the body to Json by using

Invoke-WebRequest -Uri http://foobar.com/endpoint -Method POST -Body ($params|ConvertTo-Json) -ContentType "application/json"

Extra: You can also use the Invoke-RestMethod for dealing with JSON and REST apis (which will save you some extra lines for de-serializing)

Harald F.
  • 4,505
  • 24
  • 29
  • 1
    While you can use a hashtable (`@{...}`) for GET requests, where the hashtable entries are converted to a `=&...` _query string_, I don't think that works for POSTing JSON. Compare the output from `Invoke-WebRequest https://httpbin.org/post -Body @{ "foo"="bar"; "baz"="bam" } -Method POST -ContentType 'application/json'` to `Invoke-WebRequest https://httpbin.org/post -Body '{ "foo":"bar", "baz":"bam" }' -Method POST -ContentType 'application/json'`. I think you need an explicit call to `ConvertTo-Json` and pass the resulting string instead. – mklement0 Apr 13 '18 at 19:20
  • If the body is a string already in JSON format, why make a hashtable and convert it back to JSON? The OP shows their body already in JSON format. – Jesse Chisholm Jan 23 '21 at 00:15
  • I needed argument "-EscapeHandling EscapeNonAscii" on my ConvertTo-Json for it to work. Could be just for my case, but maybe it's also helpful for others. – Martini Bianco Feb 06 '22 at 13:42
72

Use Invoke-RestMethod to consume REST-APIs. Save the JSON to a string and use that as the body, ex:

$JSON = @'
{"@type":"login",
 "username":"xxx@gmail.com",
 "password":"yyy"
}
'@

$response = Invoke-RestMethod -Uri "http://somesite.com/oneendpoint" -Method Post -Body $JSON -ContentType "application/json"

If you use Powershell 3, I know there have been some issues with Invoke-RestMethod, but you should be able to use Invoke-WebRequest as a replacement:

$response = Invoke-WebRequest -Uri "http://somesite.com/oneendpoint" -Method Post -Body $JSON -ContentType "application/json"

If you don't want to write your own JSON every time, you can use a hashtable and use PowerShell to convert it to JSON before posting it. Ex.

$JSON = @{
    "@type" = "login"
    "username" = "xxx@gmail.com"
    "password" = "yyy"
} | ConvertTo-Json
Frode F.
  • 52,376
  • 9
  • 98
  • 114
6

@Frode F. gave the right answer.

By the Way Invoke-WebRequest also prints you the 200 OK and a lot of bla, bla, bla... which might be useful but I still prefer the Invoke-RestMethod which is lighter.

Also, keep in mind that you need to use | ConvertTo-Json for the body only, not the header:

$body = @{
 "UserSessionId"="12345678"
 "OptionalEmail"="MyEmail@gmail.com"
} | ConvertTo-Json

$header = @{
 "Accept"="application/json"
 "connectapitoken"="97fe6ab5b1a640909551e36a071ce9ed"
 "Content-Type"="application/json"
} 

Invoke-RestMethod -Uri "http://MyServer/WSVistaWebClient/RESTService.svc/member/search" -Method 'Post' -Body $body -Headers $header | ConvertTo-HTML

and you can then append a | ConvertTo-HTML at the end of the request for better readability

Francesco Mantovani
  • 10,216
  • 13
  • 73
  • 113