How do I POST from Powershell using Invoke-RestMethod

生来就可爱ヽ(ⅴ<●) 提交于 2021-02-10 16:56:13

问题


As per https://docs.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

回答1:


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://docs.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"
}
---------------------


来源:https://stackoverflow.com/questions/63045678/how-do-i-post-from-powershell-using-invoke-restmethod

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!