Powershell and Rest API Postmark - powershell

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"

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.

need to add authentication header to azure devops api request

I'm trying to get information on my latest builds by sending a GET request to the Azure DevOps REST Api. I'm using Azure DevOps Server 2020 with the Patch 1 update. I need to add an authorization header to the request. The header I added is not working.
I'm doing the request in Powershell. Here's my code:
$PAT = 'personal access token'
$ENCODED = [Convert]::ToBase64String([Text.Encoding]::Unicode.GetBytes($PAT))
$headers = #{
Authorization="Basic $ENCODED"
}
Invoke-RestMethod -Uri [azure devops server url]/[project name]/_apis/build/latest/Build?api-version=5.0 -Method Get -Headers $headers
When I run the code I get the error: Invoke Method: The format of value [PAT] is invalid
UPDATE:
I updated the header syntax. Now the reponse I get:
Invoke-RestMethod:
TF400813: Resource not available for anonymous access. Client authentication required. - Azure DevOps Server
I also tried passing my Azure DevOps username and password in the header like this:
$headers = #{
Authorization="Basic [domain\username]:[password]"
}
and I got this in response:
Invoke-RestMethod: Response status code does not indicate success: 401 (Unauthorized).
Do I have to enable some setting in Azure DevOps?
I usually reference to this demo to run REST API in PowerShell, it can work fine:
$uri = "request URI"
$pat = "personal access token"
$base64AuthInfo = [Convert]::ToBase64String([Text.Encoding]::ASCII.GetBytes(("{0}:{1}" -f "", $pat)))
$headers = New-Object "System.Collections.Generic.Dictionary[[String],[String]]"
$headers.Add("Authorization", ("Basic {0}" -f $base64AuthInfo))
$headers.Add("Content-Type", "application/json")
. . .
$body = "{
. . .
}"
Invoke-RestMethod -Uri $uri -Headers $headers -Body $body -Method POST
In your case, the issue seems is caused by the encoding. Try using ASCII or UTF8, instead of Unicode.
To view more details, you can see "Use personal access tokens".

Create folder in user mailbox with Graph API

want to use the Graph API to create a folder in a user's mailbox that exists in Exchange Online.
As a result of the investigation, if I use "https://graph.microsoft.com/v1.0/users/testuser01#domain.com/mailFolders", I feel that it is possible, but an error is displayed and I cannot create it.
Currently, "Exchange> Mail.ReadWrite, MailboxSettings.ReadWrite" is assigned to the execution user (admin).
However, it says "Access is denied. Check credentials and try again." Is the permission wrong?
Or is the specified URL incorrect?
Sorry to trouble you, but thank you for your response.
【Append】
$body = #{
grant_type="client_credentials"
resource=$resource
client_id=$ClientID
client_secret=$ClientSecret
}
`#Get Token
$oauth = Invoke-RestMethod -Method Post -Uri $loginURL/$TenantName/oauth2/token -Body $body
API Permissions
You are using the client credential flow to get the token to call Microsoft Graph - Create MailFolder, so you need to add the Application permission Mail.ReadWrite of Micrsoft Graph to your AD App.
1.Add the Application permission Mail.ReadWrite like below.
2.Click the Grant admin consent for xxx button, and make sure the $resource in your request is https://graph.microsoft.com.
Update:
Here is a powershell sample to call Create MailFolder API to create MailFolder.
$uri = "https://graph.microsoft.com/v1.0/users/joyw#xxxxx.onmicrosoft.com/mailFolders"
$headers = #{
'Content-Type' = 'application/json'
'Authorization' = 'Bearer <access-token-here>'
}
$body = ConvertTo-Json #{
"displayName" = "testfolder1"
}
Invoke-RestMethod -Method Post -Uri $uri -Headers $headers -Body $body
Check the result in the Graph Explorer with List mailFolders:

Key Vault returns 401 with access token (MSI PowerShell Function App)

I am trying to connect to Keyvault with my Azure Function using PowerShell.
The Managed Service Identity (MSI) has been turned on, and in Keyvault I granted the MSI 'get' and 'list' access policies.
Using the script below I successfully get an access token, but when I make the request to Keyvault I always receive a 401 response.
$vaultName = $Env:KeyVaultName
$vaultSecretName = $Env:VaultSecretName
$tokenAuthURI = $Env:MSI_ENDPOINT + "?resource=https://vault.azure.net/&api-version=2017-09-01"
$tokenResponse = Invoke-RestMethod -Method Get -Headers #{"Secret"="$env:MSI_SECRET"} -Uri $tokenAuthURI
$accessToken = $tokenResponse.access_token
$headers = #{ 'Authorization' = "Bearer $accessToken" }
$queryUrl = "https://$vaultName.vault.azure.net/keys/" +$vaultSecretName + "?api-version=2016-10-01"
$keyResponse = Invoke-RestMethod -Method GET -Uri $queryUrl -Headers $headers
Any idea why the token is not sufficient?
Try changing the resource URI to https://vault.azure.net (with no trailing slash). The token validation on the server expects the exact same string as it returns in the 401 response's WWW-Authenticate header. In general, Key Vault returns 401 for cases where the token is missing or fails validation (three common cases are the token is expired, has an incorrect resource URI, or was issued by a different tenant than the vault is associated with).