1

As per https://learn.microsoft.com/en-us/powershell/module/microsoft.powershell.utility/invoke-restmethod?view=powershell-7#example-2--run-a-post-request I am trying to invoke a simple POST method but getting some errors.

My instruction is:

$uri = "https://localhost:44355/api/job/machine-status";
#$machineName = HOSTNAME.EXE;
$machineName = "simPass2";
$body = @{
    Name = $machineName
    Status = "Complete"
}
Invoke-RestMethod -Method 'Post' -Uri $uri  -ContentType 'application/json' -Body $body;

and my error is

Invoke-WebRequest : Unable to connect to the remote server
At line:8 char:1
+ Invoke-WebRequest -Uri $uri -Method Post -ContentType 'application/js ...
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo          : NotSpecified: (:) [Invoke-WebRequest], WebException
+ FullyQualifiedErrorId : System.Net.WebException,Microsoft.PowerShell.Comman
ds.InvokeWebRequestCommand
5
  • Is the port open? Can you curl it? Is the SSL certificate self signed? Maybe you have to skip certificate verification? Commented Jul 27, 2020 at 23:51
  • 3
    I think your $body is not a valid json. you might need to do -Body ($body | ConvertTo-Json) there Commented Jul 28, 2020 at 1:21
  • @timur thanks that was the answer to my issue! Commented Jul 28, 2020 at 16:46
  • 1
    @timur I think you should post this as answer eventhough the OP has done this himself already. You may still be awarded the bounty then.. Commented Jul 29, 2020 at 19:07
  • 1
    @timur I agree, you should be awarded the bounty! Commented Jul 29, 2020 at 21:28

1 Answer 1

8
+50

TL;DR:

The error message is extremely misleading, and does not help at all. After looking at the code though $body looked like not a valid json. Looking even closer, PowerShell documentation mentions it does not automagically convert it even though you specified desired ContentType:

For other request types (such as POST), the body is set as the value of the request body in the standard name=value format.

So you'd still have to convert it yourself:

Invoke-RestMethod -Method 'Post' -Uri $uri  -ContentType 'application/json' -Body ($body | ConvertTo-Json);

Testing it out

I built a quick test stand to verify my assumption:

void Main()
{
    var listener = new HttpListener(); // this requires Windows admin rights to run
    listener.Prefixes.Add("http://*:8181/"); // this is how you define port and host the Listener will sit at: https://learn.microsoft.com/en-us/dotnet/api/system.net.httplistener?view=netcore-3.1
    listener.Start();
    var context = listener.GetContext();
    var request = context.Request;
    var response = context.Response;
    
    var reader = new System.IO.StreamReader(request.InputStream, Encoding.UTF8);
    Console.WriteLine($"Client data content type {request.ContentType}");   
    Console.WriteLine("Start of client data:"); 
    Console.WriteLine(reader.ReadToEnd());// Convert the data to a string and dump it to console.
    Console.WriteLine("---------------------");
    
    // just fill the response so we can see it on the Powershell side:
    response.StatusCode = 200;
    var buffer = Encoding.UTF8.GetBytes("Nothing to see here");
    response.OutputStream.Write(buffer, 0, buffer.Length);
    response.Close(); // need this to send the response back
    listener.Stop();
}

Your original code sample, came back with something like this:

Client data content type application/json
Start of client data:
Name=simPass2&Status=Complete
---------------------

but if you employ ConvertTo-Json, the result looks way better:

Client data content type application/json
Start of client data:
{
    "Name":  "simPass2",
    "Status":  "Complete"
}
---------------------
Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.