Веб-запит Powershell без винятку винятків на 4xx / 5xx


82

Я пишу сценарій PowerShell, який повинен зробити веб-запит та перевірити код стану відповіді.

Я спробував написати це:

$client = new-object system.net.webclient

$response = $client.DownloadData($url)

а також це:

$response = Invoke-WebRequest $url

але коли веб-сторінка має код стану, який не є кодом стану успіху, PowerShell продовжує і видає виняток замість того, щоб подавати мені фактичний об'єкт відповіді.

Як я можу отримати код стану сторінки, навіть якщо вона не завантажується?


Це спрацювало для мене docs.microsoft.com/en-us/powershell/module/... Приклад 7: Перехоплення повідомлень про невдалі результати від Invoke-WebRequest
user3520245

Відповіді:


121

Спробуйте це:

try { $response = Invoke-WebRequest http://localhost/foo } catch {
      $_.Exception.Response.StatusCode.Value__}

Це якось невдало, що це створює виняток, але це так.

Оновлення за коментарями

Щоб переконатися, що такі помилки все ще повертають дійсну відповідь, ви можете зафіксувати ці винятки типу WebExceptionта отримати відповідні Response.

Оскільки відповідь на виняток має тип System.Net.HttpWebResponse, тоді як відповідь від успішного Invoke-WebRequestвиклику є типом Microsoft.PowerShell.Commands.HtmlWebResponseObject, для повернення сумісного типу з обох сценаріїв нам потрібно взяти успішну відповідь BaseResponse, яка також має тип System.Net.HttpWebResponse.

Код статусу цього нового типу відповіді - це перелік типів [system.net.httpstatuscode], а не просте ціле число, тому вам потрібно просто перетворити його на int або отримати доступ до його Value__властивості, як описано вище, щоб отримати числовий код.

#ensure we get a response even if an error's returned
$response = try { 
    (Invoke-WebRequest -Uri 'localhost/foo' -ErrorAction Stop).BaseResponse
} catch [System.Net.WebException] { 
    Write-Verbose "An exception was caught: $($_.Exception.Message)"
    $_.Exception.Response 
} 

#then convert the status code enum to int by doing this
$statusCodeInt = [int]$response.BaseResponse.StatusCode
#or this
$statusCodeInt = $response.BaseResponse.StatusCode.Value__

5
Дякую, це спрацювало. Я не розумів, що ви можете просто отримати доступ до об’єкта Response з об’єкта Exception.
jcarpenter2

1
Так, дістатися до фактичного номера коду було трохи складно. :-)
Кіт Хілл

Я використовую цей код від Кріса Уола
FoxDeploy

11
Трохи кращий спосіб: $ response = спробуйте {Invoke-WebRequest localhost / foo } catch {$ _. Exception.Response} Таким чином ви отримаєте щось із змінною $ response в обох випадках. Але майте на увазі, що помилка повертає HtmlWebResponse, але успіх - HtmlWebResponseObject. Зокрема, StatusCode на ці різні типи (зітхання ..)
Роб Кеннон

4
Кілька незначних налаштувань з великою пропозицією Роба, щоб уникнути проблеми з різними типами: $response = try { (Invoke-WebRequest -Uri 'localhost/foo' -ErrorAction Stop).BaseRequest } catch [System.Net.WebException] { $_.Exception.Response }. Тобто завантаження BaseRequestгарантує, що в сценаріях успіху та помилок ми отримуємо файл HttpWebReqponse. Додавання [System.Net.WebException]гарантує, що ми лише таким чином фіксуємо відповідні винятки / не випадково підмітаємо інші типи проблем.
JohnLBevan

6

Оскільки Powershell версії 7.0 Invoke-WebRequestмає -SkipHttpErrorCheckпараметр комутатора.

-SkipHttpErrorCheck

Цей параметр змушує командлет ігнорувати статуси помилок HTTP і продовжувати обробляти відповіді. Відповіді на помилки записуються в конвеєр так само, як якщо б вони були успішними.

Цей параметр було введено в PowerShell 7.

документи витягнути запит - -


0

-SkipHttpErrorCheck є найкращим рішенням для PowerShell 7+, але якщо ви поки не можете цим скористатися, то ось проста альтернатива, яка корисна для інтерактивних сеансів командного рядка Poweshell.

Коли ви бачите опис помилки для відповіді 404, тобто

Віддалений сервер повернув помилку: (404) Не знайдено.

Тоді ви можете побачити "останню помилку" з командного рядка, ввівши це:

$Error[0].Exception.Response.StatusCode

Або

$Error[0].Exception.Response.StatusDescription

Або будь-що інше, що ви хотіли б знати з об'єкта `Response '.

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.