102 votes

Demande web Powershell sans déclencher d'exception sur les codes 4xx/5xx

Je suis en train d'écrire un script powershell qui doit faire une requête web et inspecter le code d'état de la réponse.

J'ai essayé d'écrire ceci :

$client = new-object system.net.webclient

$response = $client.DownloadData($url)

ainsi que ceci :

$response = Invoke-WebRequest $url

mais chaque fois que la page web a un code d'état qui n'est pas un code d'état de succès, PowerShell lance une exception au lieu de me donner l'objet réponse réel.

Comment puis-je obtenir le code d'état de la page même lorsque le chargement échoue?

150voto

Keith Hill Points 73162

Essayez ceci :

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

C'est un peu frustrant que cela déclenche une exception, mais c'est comme ça que ça se passe.

Mise à jour selon les commentaires

Pour vous assurer que de telles erreurs renvoient tout de même une réponse valide, vous pouvez capturer ces exceptions de type WebException et récupérer la Response associée.

Puisque la réponse de l'exception est de type System.Net.HttpWebResponse, tandis que la réponse d'un appel Invoke-WebRequest réussi est de type Microsoft.PowerShell.Commands.HtmlWebResponseObject, pour retourner un type compatible dans les deux scénarios, nous devons prendre la BaseResponse de la réponse réussie, qui est également de type System.Net.HttpWebResponse.

Le code d'état de ce nouveau type de réponse est une énumération de type [system.net.httpstatuscode], plutôt qu'un simple entier, donc vous devez le convertir explicitement en int, ou accéder à sa propriété Value__ comme décrit ci-dessus pour obtenir le code numérique.

#assurez-vous d'obtenir une réponse même si une erreur est renvoyée
$response = try { 
    (Invoke-WebRequest -Uri 'localhost/foo' -ErrorAction Stop).BaseResponse
} catch [System.Net.WebException] { 
    Write-Verbose "Une exception a été interceptée : $($_.Exception.Message)"
    $_.Exception.Response 
} 

#ensuite convertir l'énumération du code d'état en int en faisant ceci
$statusCodeInt = [int]$response.BaseResponse.StatusCode
#ou ceci
$statusCodeInt = $response.BaseResponse.StatusCode.Value__

37voto

Mariusz Pawelski Points 857

Depuis la version 7.0 de Powershell Invoke-WebRequest a le paramètre de commutation -SkipHttpErrorCheck.

-SkipHttpErrorCheck

Ce paramètre permet à la cmdlet d'ignorer les statuts d'erreur HTTP et de continuer à traiter les réponses. Les réponses d'erreur sont écrites dans le pipeline comme si elles étaient réussies.

Ce paramètre a été introduit dans PowerShell 7.

docs demande de tirage

7voto

DaveC Points 21

-SkipHttpErrorCheck est la meilleure solution pour PowerShell 7+, mais si vous ne pouvez pas encore l'utiliser, voici une alternative simple qui est utile pour les sessions interactives en ligne de commande Poweshell.

Lorsque vous voyez la description d'une erreur pour une réponse 404, par exemple,

Le serveur distant a renvoyé une erreur : (404) Non trouvé.

Alors vous pouvez voir la 'dernière erreur' à partir de la ligne de commande en entrant ceci :

$Error[0].Exception.Response.StatusCode

Ou

$Error[0].Exception.Response.StatusDescription

Ou tout autre élément que vous aimeriez savoir à partir de l'objet `Response’.

0voto

Riyyi Points 98

Si vous ne voulez pas mettre à jour vers Powershell 7 pour le drapeau -SkipHttpErrorCheck, il existe une solution de contournement, $true est essentiellement une instruction sans effet qui renverra vrai :

try {
    Invoke-WebRequest -Uri $url;
} catch { $true > $null }

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X