11

In Windows PowerShell 3.0 was introduced Invoke-RestMethod cmdlet.

Invoke-RestMethod cmdlet accepts -Body<Object> parameter for setting the body of the request.

Due to a certain limitations Invoke-RestMethod cmdlet could not be used in our case. From the other hand, an alternative solution described in article InvokeRestMethod for the Rest of Us suits our needs:

$request = [System.Net.WebRequest]::Create($url)
$request.Method="Get"
$response = $request.GetResponse()
$requestStream = $response.GetResponseStream()
$readStream = New-Object System.IO.StreamReader $requestStream
$data=$readStream.ReadToEnd()
if($response.ContentType -match "application/xml") {
    $results = [xml]$data
} elseif($response.ContentType -match "application/json") {
    $results = $data | ConvertFrom-Json
} else {
    try {
        $results = [xml]$data
    } catch {
        $results = $data | ConvertFrom-Json
    }
}
$results 

But it is intended for a GET method only. Could you please suggest how to extend this code sample with the ability to send the body of the request using POST method (similar to Body parameter in Invoke-RestMethod)?

Vadim Gremyachev
  • 57,952
  • 20
  • 129
  • 193

2 Answers2

20

First, change the line that updates the HTTP method.

$request.Method= 'POST';

Next, you need to add the message body to the HttpWebRequest object. To do that, you need to grab a reference to the request stream, and then add data to it.

$Body = [byte[]][char[]]'asdf';
$Request = [System.Net.HttpWebRequest]::CreateHttp('http://www.mywebservicethatiwanttoquery.com/');
$Request.Method = 'POST';
$Stream = $Request.GetRequestStream();
$Stream.Write($Body, 0, $Body.Length);
$Request.GetResponse();

NOTE: PowerShell Core edition is now open source on GitHub, and cross-platform on Linux, Mac, and Windows. Any issues with the Invoke-RestMethod cmdlet should be reported on the GitHub issue tracker for this project, so they can be tracked and fixed.

  • 1
    thank you, Trevor! This is the way how i thought it should be implemented but was not sure that this is the best way – Vadim Gremyachev Apr 07 '14 at 20:44
  • @TrevorSullivan How the body would look like if i have a json on it? – Campinho Oct 19 '15 at 00:54
  • @campinho: Simply replace the "asdf" with your JSON. :) –  Oct 19 '15 at 18:22
  • 1
    @TrevorSullivan can I send a file this way? Like `$Body = [reports[]]$filecontent;` I got a question [here](http://stackoverflow.com/questions/39144921/how-to-pass-an-array-via-web-request) and now I come over this answer. How do you think, this solution will work in my case? – gofr1 Oct 17 '16 at 19:09
  • @gofr1 did you figure out how to send a file? – irl_irl Feb 14 '18 at 20:49
  • 1
    @irl_irl Yeah, I got the answer to this question [here](http://stackoverflow.com/questions/39144921/how-to-pass-an-array-via-web-request) – gofr1 Feb 15 '18 at 06:26
  • One irk with `Invoke-RestMethod` (at least in PS5) was that it throws an exception on 4** error codes making access to the response body a pain. – Marc May 14 '20 at 14:58
5
$myID = 666;
#the xml body should begin on column 1 no indentation.
$reqBody = @"
<?xml version="1.0" encoding="UTF-8"?>
<ns1:MyRequest
    xmlns:ns1="urn:com:foo:bar:v1"
    xmlns:ns2="urn:com:foo:xyz:v1"
    <ns2:MyID>$myID</ns2:MyID>
</ns13:MyRequest>
"@

Write-Host $reqBody;

try
{
    $endPoint = "http://myhost:80/myUri"
    Write-Host ("Querying "+$endPoint)
    $wr = [System.Net.HttpWebRequest]::Create($endPoint)
    $wr.Method= 'POST';
    $wr.ContentType="application/xml";
    $Body = [byte[]][char[]]$reqBody;
    $wr.Timeout = 10000;

    $Stream = $wr.GetRequestStream();

    $Stream.Write($Body, 0, $Body.Length);

    $Stream.Flush();
    $Stream.Close();

    $resp = $wr.GetResponse().GetResponseStream()

    $sr = New-Object System.IO.StreamReader($resp) 

    $respTxt = $sr.ReadToEnd()

    [System.Xml.XmlDocument] $result = $respTxt
    [String] $rs = $result.DocumentElement.OuterXml
    Write-Host "$($rs)";
}
catch
{
    $errorStatus = "Exception Message: " + $_.Exception.Message;
    Write-Host $errorStatus;
}
Gopi Palamalai
  • 391
  • 6
  • 6