I need to produce some output when Invoke-WebRequest exceeds the time limit set by the -TimeoutSec parameter. How can I build an If condition that runs when this is the case?
In other words; what goes in place of ????? in the example below?:
Try {
Invoke-RestMethod -Uri $Uri -contentType "application/json"
-Method Post -Headers $Headers -Body $Body -TimeoutSec 8
}
Catch {
If (?????) {
Write-Host "the request timed out..."
}
}
In Windows PowerShell, the exception thrown will be a [System.Net.WebException] with the Status field set to Timeout:
try{
Invoke-WebRequest 'http://hostname.fqdn/really/slow/endpoint/' -TimeoutSec 3 -UseBasicParsing
}
catch [System.Net.WebException] {
if($_.Exception.Status -eq 'Timeout'){
# the request timed out
}
# something else went wrong during the web request
}
Related
$uri="http:\\www.SomeUrl.com"
Measure-Command { $request = Invoke-WebRequest -Uri $uri -UseBasicParsing}
In above powershell script, how can I exit from Invoke-WebRequest if it takes time more than 10 secs, and return a error code if possible.
You can use the Timeout parameter to the Invoke-WebRequest command,
$uri="http://www.SomeUrl.com"
Measure-Command { $request = Invoke-WebRequest -Uri $uri -UseBasicParsing -Timeout 10}
You can cover it with try / catch block to get the error message.
try {
$uri="http://www.SomeUrl.com"
Measure-Command { $request = Invoke-WebRequest -Uri $uri -UseBasicParsing -Timeout 10 -ErrorAction Stop}
}
catch {
Write-Output "Timeout occured. Exception: $_"
}
You can also use -Headers #{"Cache-Control"="no-cache"} with Invoke-WebRequest which will not cache the pages you are visiting.
Upload a document into sharepoint using invoke-webrequest works but comes back with an unhelpful error when overwrite=false is used
I have used postman to send the same request and get back a sharepoint exception error
<m:error xmlns:m="http://schemas.microsoft.com/ado/2007/08/dataservices/metadata">
<m:code>-2130575257, Microsoft.SharePoint.SPException</m:code>
<m:message xml:lang="en-US">A file with the name docs/a.txt already exists. It was last modified by [redacted] on 08 Aug 2019 15:23:02 +0100.</m:message>
</m:error>
try
{
Invoke-webrequest -method post -uri $uri -infile $fullpath -headers $Headers -credential $credential
}
catch
{
$errors = $_.exception
}
instead of getting the error that is in postman I get "The remote server returned an error: (400) Bad Request."
I got around this by following the parserror function suggested here
How to get Powershell Invoke-Restmethod to return body of http 500 code response
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
{
Invoke-restmethod -method post -uri $uri -infile $fullpath -headers $Headers -credential $credential
}
catch
{
ParseErrorForResponseBody($_)
}
When I run this (parameters and body that worked from Postman):
$Url = "http://${IPADDR}:8080/api/v1/topology/query"
$headers = New-Object "System.Collections.Generic.Dictionary[[String],[String]]"
$headers.Add('Access-Token', 'token')
$headers.Add('Content-Type', 'application/json')
$headers.Add('Accept', 'application/json')
$json =
'{
"includes":[{"ids":["264690t5te74hy4y"],"observationName":"page_life_expectancy"}],
"startTime":1528718400000,
"endTime":1528768800000,
"granularity":3600000,
"numberOfValue":1,
"retrievalType":"RAW"
}'
$response = Invoke-RestMethod -Method 'Post' -Uri $url -Headers $headers -Body $json
$ple = $response | select -ExpandProperty data | select max
in Powershell ISE, I get this:
An error occurred while calling REST method at: http://${IPADDR}:8080/api/v1/topology/query. Error: The remote server returned an
error: (500) Internal Server Error.. Response body: Apache Tomcat/7.0.82 - Error report
Any expert in Powershell, JSON, and REST API that can help me with this issue?
The content of the Body parameter of Invoke-RestMethod should be an object serialized in JSon. In your example, you have 3 levels of serialization.
You should remove 2 levels of serialization:
$jsonBody = '{
"includes":[{"ids":
["264690t5te74hy4y"],"observationName":"page_life_expectancy"}],
"startTime":1528718400000,
"endTime":1528768800000,
"granularity":3600000,
"numberOfValue":1,
"retrievalType":"RAW"
}'
$response = Invoke-RestMethod -Method 'Post' -Uri $url -Headers $headers -Body $jsonBody
But it's not guaranteed that the error 500 disappear.
You may have more details about the error with the Exception content. You can try that:
try {
$response = Invoke-RestMethod -Method 'Post' -Uri $url -Headers $headers -Body $jsonBody
}
catch {
$errorMessage = $_.Exception.Message
if (Get-Member -InputObject $_.Exception -Name 'Response') {
try {
$result = $_.Exception.Response.GetResponseStream()
$reader = New-Object System.IO.StreamReader($result)
$reader.BaseStream.Position = 0
$reader.DiscardBufferedData()
$responseBody = $reader.ReadToEnd();
} catch {
Throw "An error occurred while calling REST method at: $url. Error: $errorMessage. Cannot get more information."
}
}
Throw "An error occurred while calling REST method at: $url. Error: $errorMessage. Response body: $responseBody"
}
Error handling from post: How to get Powershell Invoke-Restmethod to return body of http 500 code response
From PowerShell since you serialize the content to JSON, specify -ContentType "application/json". Also, if you think the content might contain unicode strings, include the -ContentType "application/json; charset=utf-8".
I'm trying to make a PATCH request using the following lines in PowerShell but it is returning a 403:
Try{
$Body = #{
'api_key' = 'myapikey'
'item[status]' = 'unavailable'
} | ConvertTo-Json
$response = Invoke-WebRequest -Method PATCH -Uri "https://api.example.com/store/apikey.json" -Body $Body -ContentType "application/json"
$response.StatusCode
}
Catch [System.Net.WebException]{
$code = [int]$_.Exception.Response.StatusCode
}
Fiddler is returning a 403 with the following message: "{"error":"Parameter item is required"}". Also, the query string in Fiddler is empty. However, a successful request is made when everything is hard-coded into the Uri:
$statusUpdate = Invoke-WebRequest -Method PATCH -Uri "https://api.example.com/store/apikey.json?api_key=myapikey&item[status]=unavailable" -ContentType "application/json"
If that's the code you're actually using to hit the API, your problem appears to simply be due to piping your json body to out-host, thus sending an empty $Body to the API, so you should edit it to do this:
try
{
$Body = #{
'api_key' = 'myapikey'
'item[status]' = 'unavailable'
} | ConvertTo-Json
$response = Invoke-WebRequest -Method PATCH -Uri "https://api.example.com/store/apikey.json" -Body $Body -ContentType "application/json"
$response.StatusCode
}
catch [System.Net.WebException]
{
$code = [int]$_.Exception.Response.StatusCode
}
I have a powershell script using the Skytap API (REST). I would like to catch the error, if there is one, and try to display it.
For example, we are changing the IP:
Invoke-RestMethod -Uri https://cloud.skytap.com/configurations/XXXXXX/vms/YYYYYY/interfaces/ZZZZZZ?ip=10.0.0.1 -Method PUT -Headers $headers
If the IP is used somewhere else, I will get the 409 Conflict Error (Request is well-formed but conflicts with another resource or permission).
I would like to check if the error is 409 and then tell it to do something else about it.
This is somewhat awkward but the only way to do it as far as I know without doing something more complicated like using .NET's WebRequest and ConvertFrom-Json (or whatever data format you are expecting).
try {
Invoke-RestMethod ... your parameters here ...
} catch {
# Dig into the exception to get the Response details.
# Note that value__ is not a typo.
Write-Host "StatusCode:" $_.Exception.Response.StatusCode.value__
Write-Host "StatusDescription:" $_.Exception.Response.StatusDescription
}
I know you asked for Powershellv4, but since v6/v7 :
Try {
$WebRequestResult = Invoke-RestMethod -Uri $URL -Headers $Headers -Body $BodyJSON -Method $Method -ContentType $ContentType -SkipCertificateCheck
} Catch {
if($_.ErrorDetails.Message) {
Write-Host $_.ErrorDetails.Message
} else {
Write-Host $_
}
}
The Special Variable $? will solve this. It stands for $LASTEXITCODE = 0 (everything ok). It will ask for the Result Code from the previous Command.
Invoke-RestMethod -Uri https://cloud.skytap.com/configurations/XXXXXX/vms/YYYYYY/interfaces/ZZZZZZ?ip=10.0.0.1 -Method PUT -Headers $headers
if (!$?) {
throw $_.ErrorDetails.Message
}
Powershell 7 introduces the -SkipHttpErrorCheck parameter. This instructs the cmdlet to behave in a similar way to web requests in programming frameworks (i.e. where 404, 409, etc. are valid responses - the web request is successful but the server returned an error code).
This can be combined with the -StatusCodeVariable parameter. This instructs the cmdlet to insert the response code into a variable. However, the variable name is passed as a string (not as a reference). For example:
$scv = $null
Invoke-RestMethod ... -SkipHttpErrorCheck -StatusCodeVariable "scv"