トップ回答者
Invoke-WebRequestの挙動について

質問
-
いつもお世話になっております。
TeckNetの書き込みにはいつも助けられております。
ありがとうございます。
”invoke-webrequest”を利用して簡易的なURL監視を行っています。
※取得したstatusが200なら正常と判定します。
※取得したstatusが200以外ならエラーと判定し、ポップが挙がります。
コマンドの挙動について理解できない部分が有り困っています。
テストで実際に監視しているURLにノイズ(ex.11111などを末尾に入れたり、URLの中間に入れたり)を
入れて、挙動の確認をしているのですが、思った通りの動きをしてくれません。
200のステータスコードが返り、Descriptionでokが返ります。
また、全てのURLで一様の動きとならず、同じURLでもノイズを入れる場所によって
挙動が変わります。
コマンドの動きをみていると、コマンドではそのURLが正しく表示されるかどうかの判断はできないため、
URLを叩いてWEBページから何かしらの反応が返れば『正常』と判断する様に見受けられます。
※WEBブラウザでURLを叩いてブラウザ上では404が返っても、コマンドは200を返す時があります。。
コマンドの挙動について
・URLのコマンド判定
・URLの正否の判定にキャッシュ情報などが関与するか
また、コマンドの挙動を変えたい場合、書き換えなどでるかなど
何かお持ちの情報があればご教示頂けますと大変助かります。
宜しくお願い致します。
回答
-
もしかするとこのようなコードを書いていませんか?
$response = Invoke-WebRequest "https://social.technet.microsoft.com/" $statusCode = $response.StatusCode if($statusCode -eq 200) {"正常"} else {"異常"}
実はこのコード、サーバーがステータスコード200を返す時には正しく動作しますが、200以外の404等を返す時には正しく動作しません。
というのも、Invoke-WebRequestコマンドレットは200以外のステータスコードが返されると、エラーが発生するため、$response変数には何も値が格納されません。(実際この仕様は酷いと思いますが)
$response変数に、以前にステータスコード200で返却されたレスポンスが格納されている状態で新たにエラーが出ると、$response変数の中身が更新されないため、「実際には404なのに200が返された」ように見えてしまう現象が起きます。
この現象の公式な回避方法は不明ですが、私は以下のようにしています。try catchステートメントを使って、正常時(200)にはそのままレスポンスからステータスコードを取り、エラー時(404等)には例外オブジェクトから取るようにします。
$statusCode = 0 $response = $null try { $response = Invoke-WebRequest https://social.technet.microsoft.com/ $statusCode = $response.StatusCode } catch [System.Net.WebException] { $statusCode = $_.Exception.Response.StatusCode.value__ } if($statusCode -eq 200) {"正常"} else {"異常"}
これに加えて、キャッシュの問題もあります。Invoke-WebRequestは内部的に.NETのWebClientクラスを用いていて、このクラスはIEとキャッシュを共有しているようです。
キャッシュを読まないようにする方法はいくつかありますが、一番単純なものは、アクセス毎にURIの末尾にランダムなクエリを付けるというものがあります。
- 回答としてマーク みふさま 2018年11月21日 8:31
すべての返信
-
もしかするとこのようなコードを書いていませんか?
$response = Invoke-WebRequest "https://social.technet.microsoft.com/" $statusCode = $response.StatusCode if($statusCode -eq 200) {"正常"} else {"異常"}
実はこのコード、サーバーがステータスコード200を返す時には正しく動作しますが、200以外の404等を返す時には正しく動作しません。
というのも、Invoke-WebRequestコマンドレットは200以外のステータスコードが返されると、エラーが発生するため、$response変数には何も値が格納されません。(実際この仕様は酷いと思いますが)
$response変数に、以前にステータスコード200で返却されたレスポンスが格納されている状態で新たにエラーが出ると、$response変数の中身が更新されないため、「実際には404なのに200が返された」ように見えてしまう現象が起きます。
この現象の公式な回避方法は不明ですが、私は以下のようにしています。try catchステートメントを使って、正常時(200)にはそのままレスポンスからステータスコードを取り、エラー時(404等)には例外オブジェクトから取るようにします。
$statusCode = 0 $response = $null try { $response = Invoke-WebRequest https://social.technet.microsoft.com/ $statusCode = $response.StatusCode } catch [System.Net.WebException] { $statusCode = $_.Exception.Response.StatusCode.value__ } if($statusCode -eq 200) {"正常"} else {"異常"}
これに加えて、キャッシュの問題もあります。Invoke-WebRequestは内部的に.NETのWebClientクラスを用いていて、このクラスはIEとキャッシュを共有しているようです。
キャッシュを読まないようにする方法はいくつかありますが、一番単純なものは、アクセス毎にURIの末尾にランダムなクエリを付けるというものがあります。
- 回答としてマーク みふさま 2018年11月21日 8:31