46

Invoke-RestMethod 调用在下面仅返回非常无用的异常,并且(据我所知)不允许您收集正文内容(提琴手跟踪结果中显示的 JSON 对象)。如果是这样的话,这似乎是一个非常糟糕的实现,因为 http 500 定义非常具体,客户端应该返回响应的主体以帮助排除故障......我错过了什么吗?

invoke-restmethod -method Post -uri "https://api-stage.enviance.com/ver2/EqlService.svc/eql" -Body (ConvertTo-Json $eqlhash)  -Headers @{"Authorization"="Enviance $session"}

invoke-restmethod :远程服务器返回错误:(500)内部服务器错误。在 line:1 char:9...

下面的提琴手跟踪

HTTP/1.1 500 内部服务器错误连接:关闭日期:2013 年 9 月 12 日星期四 17:35:00 GMT 服务器:Microsoft-IIS/6.0 X-Powered-By:ASP.NET X-AspNet-Version:2.0.50727 EnvApi-版本:2.0,2.0 EnvApi-Remaining-Calls:994,994 EnvApi-Remaining-Interval:2684,2684 Cache-Control:no-cache Pragma:no-cache Expires:-1 Content-Type:text/csv;字符集=utf-8

{"errorNumber":0,"message":"当前用户无权从表 'CustomFieldTemplate' 中检索数据"}

4

6 回答 6

103

另一个答案确实为您提供了响应,但您需要一个额外的步骤来获取响应的实际正文,而不仅仅是标题。这是一个片段:

try {
        $result = Invoke-WebRequest ...
}
catch {
        $result = $_.Exception.Response.GetResponseStream()
        $reader = New-Object System.IO.StreamReader($result)
        $reader.BaseStream.Position = 0
        $reader.DiscardBufferedData()
        $responseBody = $reader.ReadToEnd();
}
于 2014-05-22T19:25:41.510 回答
35

虽然是一个旧线程,但这里是 cmdlet Invoke-WebRequest 和 Invoke-RestMethod 问题的答案。

这个问题困扰了我一段时间。由于所有 4xx 和 5xx 响应都在生成异常,因此您必须捕获该异常,然后才能从那里提取响应。像这样使用它:

$resp = try { Invoke-WebRequest ... } catch { $_.Exception.Response }

现在 $resp 总是包含你喜欢的一切。

于 2013-11-30T23:02:24.777 回答
29

此解决方案不再适用于 PowerShell 6 - 它不支持GetResponseStream(). 而是使用

try {
    $result = Invoke-WebRequest ...
}
catch {
    $_.ErrorDetails.Message
}

我编写了一个简短的辅助函数来支持 PowerShell 6 及更早版本:

function ParseErrorForResponseBody($Error) {
    if ($PSVersionTable.PSVersion.Major -lt 6) {
        if ($Error.Exception.Response) {  
            $Reader = New-Object System.IO.StreamReader($Error.Exception.Response.GetResponseStream())
            $Reader.BaseStream.Position = 0
            $Reader.DiscardBufferedData()
            $ResponseBody = $Reader.ReadToEnd()
            if ($ResponseBody.StartsWith('{')) {
                $ResponseBody = $ResponseBody | ConvertFrom-Json
            }
            return $ResponseBody
        }
    }
    else {
        return $Error.ErrorDetails.Message
    }
}

try {
    $result = Invoke-WebRequest ...
}
catch {
    ParseErrorForResponseBody($_)
}
于 2018-01-08T16:52:18.020 回答
12

搜索我的问题的答案,我找到了这个线程。

这些解决方案对我有用,但我必须添加两个新行:

 $reader.BaseStream.Position = 0
 $reader.DiscardBufferedData()

谢谢!

于 2014-10-28T13:05:30.197 回答
3

请注意,作为 Florial Feldhaus 对答案提供者的扩展,$_.ErrorDetails.Message它不是原始响应正文。HTML 标记删除正则表达式用于使响应更易于阅读github 链接。由于流位于第 1535 行,因此目前无法检索原始响应正文。

解决方法是使用 dotnetHttpClient获取原始响应,而不是使用Invoke-WebRequestcmdlet

$url = "http://localhost"
$client = [System.Net.Http.HttpClient]::new()
$request = [System.Net.Http.HttpRequestMessage]::new([System.Net.Http.HttpMethod]::Post, $url)
$request.Content = [System.Net.Http.StringContent]::new("Hello World", [System.Text.Encoding]::UTF8, "plain/text")

$result = $client.SendAsync($request).GetAwaiter().GetResult()
$content = $result.Content.ReadAsStringAsync().GetAwaiter().GetResult()

Write-Verbose $content -Verbose

powershell core github问题在这里

于 2019-03-02T16:59:02.100 回答
3

我一直在专门使用 Invoke-RestMethod - 由于它可能是 Invoke-WebRequest 的包装器,因此以下信息可能有用。

您需要捕获异常,然后像这样从 Response 获取响应流。

    try
    {
        $response = Invoke-RestMethod Method Get uri "$($uri)" -Headers $headers
        return $response
    }
    catch
    {
        Write-Host "Exception details: "
        $e = $_.Exception
        Write-Host ("`tMessage: " + $e.Message)
        Write-Host ("`tStatus code: " + $e.Response.StatusCode)
        Write-Host ("`tStatus description: " + $e.Response.StatusDescription)

        Write-Host "`tResponse: " -NoNewline
        $memStream = $e.Response.GetResponseStream()
        $readStream = New-Object System.IO.StreamReader($memStream)
        while ($readStream.Peek() -ne -1) {
            Write-Host $readStream.ReadLine()
        }
        $readStream.Dispose();
    }

参考:https ://social.technet.microsoft.com/Forums/windowsserver/en-US/7d838d53-bfd5-4706-b0df-c4bee2d00412/using-memorystream-and-textreader

于 2020-09-21T23:05:10.907 回答