iwr - powershell invoke http
Cómo hacer que Powershell Invoke-Restmethod devuelva el cuerpo de la respuesta del código http 500 (4)
Aunque es un hilo antiguo, aquí hay una respuesta al problema con los cmdlets Invoke-WebRequest y Invoke-RestMethod.
Este me ha molestado desde hace bastante tiempo. Como todas las respuestas 4xx y 5xx están generando una excepción, debe capturar esa y luego puede extraer la Respuesta desde allí. Úsalo así:
$resp = try { Invoke-WebRequest ... } catch { $_.Exception.Response }
Ahora $ resp siempre contiene todo lo que te gusta.
La llamada Invoke-RestMethod devuelve solo una excepción muy poco útil a continuación y no (por lo que puedo decir) le permite recopilar el contenido del cuerpo (objeto JSON que se muestra en los resultados del rastreo del Fiddler). Esto parece una implementación bastante mala si es así porque la definición de http 500 es bastante específica de que el cliente debería devolver el cuerpo de la respuesta para ayudar a solucionar problemas ... ¿Me estoy perdiendo algo?
invoke-restmethod -method Post -uri "https://api-stage.enviance.com/ver2/EqlService.svc/eql" -Body (ConvertTo-Json $eqlhash) -Headers @{"Authorization"="Enviance $session"}
invoke-restmethod: el servidor remoto devolvió un error: (500) Error interno del servidor. En línea: 1 char: 9 ...
Trazo del violinista a continuación
HTTP / 1.1 500 Conexión de error interna del servidor: cerrar Fecha: jueves, 12 de septiembre de 2013 17:35:00 GMT Servidor: Microsoft-IIS / 6.0 X-Powered By: ASP.NET X-AspNet-Version: 2.0.50727 EnvApi- Versión: 2.0,2.0 EnvApi-Remaining-Calls: 994,994 EnvApi-Remaining-Interval: 2684,2684 Cache-Control: no-cache Pragma: no-cache Expires: -1 Content-Type: text / csv; conjunto de caracteres = utf-8
{"errorNumber": 0, "mensaje": "El usuario actual no tiene derechos para recuperar datos de la tabla ''CustomFieldTemplate''"}
Buscando una respuesta para mi problema encontré este hilo.
Esta solución funcionó para mí, pero tuve que agregar dos nuevas líneas:
$reader.BaseStream.Position = 0
$reader.DiscardBufferedData()
¡Gracias!
Esta solución ya no funciona con PowerShell 6, no es compatible con GetResponseStream()
. En lugar de usar
try {
$result = Invoke-WebRequest ...
}
catch {
$_.ErrorDetails.Message
}
Escribí una breve función auxiliar para admitir PowerShell 6 y anteriores:
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($_)
}
La otra respuesta le proporciona la respuesta, pero necesita un paso adicional para obtener el cuerpo real de la respuesta, no solo los encabezados. Aquí hay un fragmento de código:
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();
}