如何使用 Invoke-RestMethod 从 Powershell POST
How do I POST from Powershell using Invoke-RestMethod
根据 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
长话短说:
该错误消息极具误导性,根本无济于事。在查看代码后,虽然 $body
看起来不是有效的 json。仔细观察,PowerShell documentation 提到它不会自动转换它,即使您指定了所需的 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.
所以你还是得自己转换:
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"
}
---------------------
根据 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
长话短说:
该错误消息极具误导性,根本无济于事。在查看代码后,虽然 $body
看起来不是有效的 json。仔细观察,PowerShell documentation 提到它不会自动转换它,即使您指定了所需的 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.
所以你还是得自己转换:
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"
}
---------------------