Unable to get response when Head method is used with Invoke-RestMethod - rest

I am running the following within PowerShell with the Head method but I am not getting any response. The expected output is in encoded format.
Invoke-RestMethod -Uri 'http://localhost:2375/containers/45e97476b2f5/archive?path=/home/test/' -Method Head
When I run the same REST API request with CURL or SOAP UI, I get expected output as below.
HTTP/1.1 200 OK
Content-Type: application/x-tar
Server: Docker/1.12.3 (linux)
X-Docker-Container-Path-Stat: eyJuYW1lIjoidGVzdCIsInNpemUiOjYsIm1vZGUiOjIxNDc0ODQxNDEsIm10aW1lIjoiMjAxNy0wMy0wN1QyMzoyMToyNC40MD
Any help?

Invoke-RestMethod is for interacting with a Restful web service and as such it does not return the headers of your request even when you specify the Head method.
You should instead use Invoke-WebRequest which does bring back the headers, and other properties (with headers then being in the .headers property).
For example:
$Web = Invoke-WebRequest -URI 'http://localhost:2375/containers/45e97476b2f5/archive?path=/home/test/' -Method Head
$Web.Headers

I am able to get response using Invoke-WebRequest.

Related

Cant' Access API with Powershell but can access using Postman, Python, or cURL

I'm trying to get data back from an API online using Powershell with the command Invoke-WebRequest -UseBasicParsing $request_string -Method Get -Headers $headers) but am getting back Invoke-WebRequest : The remote server returned an error: (403) Forbidden.
I am supplying a $headers dictionary. Strangely, I can access the API using Postman, Python, and cURL. It's only when using Powershell commands that I get the 403 error. In fact, I used Postman's Code Snippet feature to generate my Powershell code, and it still doensn't work! Postman's Powershell Code Snippet was:
$headers = New-Object "System.Collections.Generic.Dictionary[[String],[String]]"
$headers.Add("Authorization", "Bearer {removed for security}")
$response = Invoke-RestMethod '{removed for security}' -Method 'GET' -Headers $headers
$response | ConvertTo-Json
To recap, both Invoke-WebRequest and Invoke-RestMethod don't work.
Any help here is much appreciated.
Thanks!
Figured it out on my own.
The API vendor enforced https requirement instead of just http. Apparently, Postman, Python, and cURL can figure that out on their own and change the request accordingly, but Powershell cannot.

Invoke-RestMethod returning 401 - Unauthorized in Powershell 7

I'm running into an issue trying to use the Invoke-RestMethod command in PowerShell 7. I can get it to run fine in PowerShell 5.1, but 7 gives me a 401 - Unauthorized message.
Here's the command for PowerShell 5.1:
Invoke-RestMethod "http://internalServer/api/job?name=testJob" -Method GET -UseDefaultCredentials -ContentType "application/JSON"
Here's the command for PowerShell 7:
Invoke-RestMethod "http://internalServer/api/job?name=testJob" -Method GET -UseDefaultCredentials -ContentType "application/JSON" -AllowUnencryptedAuthentication
The api is hosted on an internal server that uses Windows Authentication. When I track the requests through Fiddler, both commands seem to get the 401 response, but PowerShell 5.1 uses the response to generate an Authorization: Negotiate YII{token} header whereas PowerShell 7 stops and returns an error. Has anyone else encountered this before?
As indicated in the comments, there is a redirect going on here. By default, authentication won't survive a redirect, but you can control that with the -PreserveAuthorizationOnRedirect parameter to Invoke-RestMethod:
$irmParams = #{
Uri = "http://internalServer/api/job?name=testJob"
Method = 'GET'
UseDefaultCredentials = $true
ContentType = 'application/json'
PreserveAuthorizationOnRedirect = $true # <== Should be your solution
AllowUnencryptedAuthentication = $true # <=== You should not be using this :)
}
Invoke-RestMethod #irmParams
Thanks to some additional legwork by OP, -PreserveAuthorizationOnRedirect:
Will only keep the authentication headers for requests made to a Uri that includes the original Uri up to the last /. What the documentation doesn't include is that the subsequent Uri's must also match the case of the original Uri.
In OP's case, the redirection was changing the case of the original Uri, thus breaking the authentication on redirect even when they specified -PreserveAuthorizationOnRedirect.

Powershell and Rest API Postmark

when I send a request through powershell to rest api Postmarkapp I have these errors
When use metod get
Invoke-RestMethod : Cannot send a content-body with this verb-type.
When use metod post
Server Error in '/' Application. The resource cannot be found.
Description: HTTP 404. The resource you are looking for (or one of its dependencies) could have been removed, had its name changed, or is temporarily unavailable. Please review the following URL and make sure that it is spelled correctly.
Requested URL: /deliverystats
Script
$Uri = 'https://api.postmarkapp.com/deliverystats'
Invoke-RestMethod $Uri -Method Post -Headers #{'X-Postmark-Server-Token' =" Token" } -ContentType "application/json" |
The script you provided wasn't complete - it ends with a |.
A valid token is required before executing a request or you'll get this error:
Invoke-RestMethod : {"ErrorCode":10,"Message":"No Account or Server API tokens were supplied in the HTTP headers. Please add a header for either
X-Postmark-Server-Token or X-Postmark-Account-Token."}
Your code had ' Token', which is a constant and is probably not a valid value for the X-Postmark-Server-Token or X-Postmark-Account-Token header. You didn't show how $Token was set, but it probably should have been something like this:
$Token = 'xxxxxxxxxxxxx' #your account specific token
$uri = 'https://api.postmarkapp.com/deliverystats'
Then add the headers like this (with a $ before Token):
Invoke-RestMethod $Uri -Method Get -Headers #{'X-Postmark-Server-Token' ="$Token" } -ContentType "application/json"

Why the response-content returned from Invoke-WebRequest is too short?

I am trying to make a REST request to fetch some data from a server using PowerShell. The commandlet I am using is Invoke-WebRequest:
> Invoke-WebRequest -Uri "http://server" -Method GET -ContentType "application/json" -Credential $cred
This request will run successfully with this result:
StatusCode : 200
StatusDescription: OK
Content : 25/08/2018 11:49:51 INFO Start-Time ...
RawContent : HTTP/1.1 200 OK
......
Actually I am fetching a log file and the file content should be returned in the HTTP body as content. However, the content returns only 2-3 line and the rest is omitted. How can I obtain the full content of the log file in the content section of the response body?
I use something like this to get JSON content from web services. You can probably use something similar
$resp = Invoke-WebRequest ....
Write-Information -Message $resp.StatusCode
Write-Information -Message $resp.Content
$json = $resp.Content | ConvertFrom-Json
If you just want the content and can ignore all errors you can use:
(Invoke-WebRequest ...).Content
As noted elsewhere Invoke-RestMethod does some of this automagically ... if you're calling a REST API.

API response is not showing in Powershell

I'm using Powershell v4.
I am calling a POST API and want to see the response when I run Invoke-RestMethod but it just shows a new line.
How can I output the response from the API to the console? I have tried running it in a script with Write-Host and Write-Output, but nothing appears on the console screen.
PowerShell script:
$Response = Invoke-RestMethod -Uri https://localhost:8081/myAPI -Body '{"username":"xyz","password":"xyz"}' -ContentType application/json -Method POST
Write-Host $Response
I can see the response when I curl the API but cannot see it in my PowerShell script which I need to use.
CURL
curl -H "Content-Type: application/json" -X POST -d '{"username":"xyz","password":"xyz"}' https://localhost:8081/myAPI
It looks like its not even hitting the API as nothing appears in the API logs when triggering from Powershell. Not sure how to resolve that if that is the problem.
Your command has a syntax error. Your contenttype is not in proper format.
You have:
-ContentType application/json
Change it to:
-ContentType "application/json"