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)Internal Server Error。 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プラグマ:no-cache Expires:-1 Content-Type:text/csv; charset = utf-8
{"errorNumber":0、 "message": "現在のユーザーには、テーブル 'CustomFieldTemplate'からデータを取得する権限がありません"}
古いスレッドですが、ここではコマンドレットInvoke-WebRequestおよびInvoke-RestMethodの問題に対する答えを示します。
これは長い間私を悩ませてきました。 4xxおよび5xxの応答はすべて例外を生成しているため、その応答をキャッチする必要があります。その後、そこから応答を抽出できます。次のように使用します。
$resp = try { Invoke-WebRequest ... } catch { $_.Exception.Response }
現在、$ respには常に好きなものがすべて含まれています。
もう1つの答えは応答を取得しますが、ヘッダーだけでなく、応答の実際の本文を取得するために追加の手順が必要です。以下がスニペットです。
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();
}
このソリューションは、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($_)
}
問題の答えを探して、このスレッドを見つけました。
これらのソリューションは私にとってはうまくいきましたが、2つの新しい行を追加する必要がありました。
$reader.BaseStream.Position = 0
$reader.DiscardBufferedData()
ありがとう!
Florial Feldhausによる回答プロバイダーの拡張として、$_.ErrorDetails.Message
は元の応答本文ではないことに注意してください。 HTMLタグ削除正規表現は、応答を読みやすくするために使用されます github link 。ストリームは1535行目に配置されているため、現在、元の応答本文を取得する方法はありません。
回避策は、Invoke-WebRequest
コマンドレットを使用する代わりに、ドットネットHttpClient
を使用して元の応答を取得することです。
$url = "http://localhost"
$client = [System.Net.Http.HttpClient]::new()
$request = [System.Net.Http.HttpRequestMessage]::new()
$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コアgithubの問題は here