【问题标题】:How do I POST from Powershell using Invoke-RestMethod如何使用 Invoke-RestMethod 从 Powershell 发布
【发布时间】:2020-07-23 01:53:57
【问题描述】:

根据https://docs.microsoft.com/en-us/powershell/module/microsoft.powershell.utility/invoke-restmethod?view=powershell-7#example-2--run-a-post-request,我正在尝试调用一个简单的 POST 方法,但出现一些错误。

我的指示是:

$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;

我的错误是

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

【问题讨论】:

  • 端口是否开放?你能curl吗? SSL 证书是自签名的吗?也许您必须跳过证书验证?
  • 我认为您的 $body 不是有效的 json。你可能需要在那里做-Body ($body | ConvertTo-Json)
  • @timur 谢谢这是我问题的答案!
  • @timur 我认为您应该将其发布为答案,尽管 OP 自己已经这样做了。那时你可能仍会获得赏金..
  • @timur 我同意,你应该获得赏金!

标签: powershell powershell-3.0 invoke-restmethod


【解决方案1】:

TL;DR:

错误消息极具误导性,根本没有帮助。在查看代码后,虽然$body 看起来不是一个有效的 json。仔细观察,PowerShell documentation 提到即使您指定了所需的ContentType,它也不会自动转换它:

对于其他请求类型(如 POST),body 设置为标准 name=value 格式的请求正文的值。

所以你仍然需要自己转换它:

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

测试一下

我建立了一个快速测试台来验证我的假设:

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();
}

您的原始代码示例返回如下:

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

但如果你使用ConvertTo-Json,结果看起来会更好:

Client data content type application/json
Start of client data:
{
    "Name":  "simPass2",
    "Status":  "Complete"
}
---------------------

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2015-02-04
    • 1970-01-01
    • 2019-01-09
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多