2017-02-14 7 views
0

Invoke-WebRequestが500,401,403などになると出力をキャプチャするにはどうすればよいですか?呼び出しが成功すると、結果は$Response変数に格納されますが、401がヒットした場合はエラーがスローされますが、レスポンスは格納されません。失敗時に応答をキャプチャする/ 401 Invoke-WebRequest

$Response = Invoke-WebRequest -Method HEAD -Uri 'https://site.contoso.com' 
Invoke-WebRequest : The remote server returned an error: (401) Unauthorized. 
At line:1 char:13 
+ $Response = Invoke-WebRequest -Method HEAD -Uri 'https://site.contoso.com' -Erro ... 
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 
    + CategoryInfo   : InvalidOperation: (System.Net.HttpWebRequest:HttpWebRequest) [Invoke-WebRequest], WebException 
    + FullyQualifiedErrorId : WebCmdletWebResponseException,Microsoft.PowerShell.Commands.InvokeWebRequestCommand 

$Response変数は、例外として処理されるので、それは単にのPowerShellによって捕捉されていない、しかし、エンドポイントは401の不正ヘッダを返して、ヌルのままです。フィドラーを通してこれを確認します。

[System.Net.WebRequest]を使用してリクエストを作成すると、$Response = $WebRequest.GetResponse()を実行した場合と同じ結果になります。

ここは私の$PSVersionTableです。

Name       Value                           
----       -----                           
PSVersion      4.0                            
WSManStackVersion    3.0                            
SerializationVersion   1.1.0.1                           
CLRVersion      4.0.30319.36373                         
BuildVersion     6.3.9600.16406                         
PSCompatibleVersions   {1.0, 2.0, 3.0, 4.0}                        
PSRemotingProtocolVersion  2.2 

答えて

2

これは実際にはopen issue on the PowerShell project on GitHubですが、多少解決する可能性があります。

今のところ、これを回避する傾向があります。

まず、この関数をメモリに読み込みます。

function Failure { 
$global:helpme = $body 
$global:helpmoref = $moref 
$global:result = $_.Exception.Response.GetResponseStream() 
$global:reader = New-Object System.IO.StreamReader($global:result) 
$global:responseBody = $global:reader.ReadToEnd(); 
Write-Host -BackgroundColor:Black -ForegroundColor:Red "Status: A system exception was caught." 
Write-Host -BackgroundColor:Black -ForegroundColor:Red $global:responsebody 
Write-Host -BackgroundColor:Black -ForegroundColor:Red "The request body has been saved to `$global:helpme" 
break 
} 

次に、このようにWebRequestsをラップします。

try 
{ 
    $Response = Invoke-WebRequest -Method HEAD -Uri 'https://site.contoso.com' 
} 
catch 
{ 
    Failure 
} 

このアプローチについての涼しい事は、それがグローバルスコープの変数を書き込み、彼らはあなたの関数が終了後も持続うということです。エラーが発生した場合は、完全なエラーのために$global:resultまたは$global:responsebodyを突き止めてください。

これはRPCエンドポイントまたはRESTエンドポイントに基づいてモジュールを作成する際に必須です。このtechnique goes to Steve Wahl.

+0

ため

クレジットありがとうございました - この方法ははるかに直感的で柔軟な私が思い付いたものよりもあります。 – Taylor

+0

あなたはそれが好きで、うれしい幸せ。ボーナスとして、$ bodyを使用するように関数を変更したり、ヘッダーを$ morefとして保存すると、それらのグローバル変数もトラブルシューティングのために取得されます。その機能は本当に役に立ちます。 – FoxDeploy

+0

ありがとうございました - このシナリオでは、私は* 401を期待するスクリプトを書いていましたが、ヘッダーを抽出する必要があります。 – Taylor

0

try/catchブロック内でレスポンスを取得できることがわかりました。

try 
{ 
    $Response = Invoke-WebRequest -Method HEAD -Uri 'https://site.contoso.com' 
} 
catch 
{ 
    $Failure = $_.Exception.Response 
} 

ただし、これはトラップして実行時にレスポンスを確認する場合にのみ有効です。 $ Error変数から応答データを取得することはできません。

関連する問題