Passing Header Auth Bearer token as variable in Powershell Invoke-RestMethod - powershell

I have the below code, where i am trying to capture the access token and passing it as a variable in the Headers section for Bearer token, but looks like the $Token.access_token is not getting replaced with in the header and i am getting below error.
ANy help would be highly appreciated
Invoke-RestMethod : {"error":"Unauthorized","message":"Failed to create session using the supplied Authorization header"}
At E:\restcurl.ps1:48 char:1
+ Invoke-RestMethod -Uri $Uri -Headers $Headers -Method Post -ContentTy ...
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : InvalidOperation: (System.Net.HttpWebRequest:HttpWebRequest) [Invoke-RestMethod], WebException
+ FullyQualifiedErrorId : WebCmdletWebResponseException,Microsoft.PowerShell.Commands.InvokeRestMethodCommand
PS E:\>
Do {
$RequestAccessTokenUri = "https://anypoint.mulesoft.com/accounts/api/v2/oauth2/token"
$ClientId = "44b1d81339c74"
$ClientSecret = "c3804f9fc18"
$auth_body = "grant_type=client_credentials&client_id=$ClientId&client_secret=$ClientSecret"
$Token = Invoke-RestMethod -Method Post -Uri $RequestAccessTokenUri -Body $auth_body -ContentType 'application/x-www-form-urlencoded'
echo $Token.expires_in
echo $Token.access_token
if ($Token.expires_in -gt 200) { break }
} Until ($Token.expires_in -gt 200)
$path = 'E:\actions-runner\cuments-v1-1.0.2.jar';
$jsonpath='E:\curljson.json'
$Headers = #{
'X-ANYPNT-ENV-ID' = '4af1b64'
'X-ANYPNT-ORG-ID' = 'c659234ad'
'Authorization' = "`"Bearer $Token.access_token`""
}

I can see that you've resolved your issue by assigning the token to a variable and then passing that to the header.
It's also possible to use the PowerShell Subexpression operator $() in this instance.
The Subexpression operator is described as:
Returns the result of one or more statements. For a single result, returns a scalar. For multiple results, returns an array. Use this when you want to use an expression within another expression. For example, to embed the results of command in a string expression.
This would essentially have transformed your Header code from:
$Headers = #{
'X-ANYPNT-ENV-ID' = '4af1b64'
'X-ANYPNT-ORG-ID' = 'c659234ad'
'Authorization' = "`"Bearer $Token.access_token`""
}
to:
$Headers = #{
'X-ANYPNT-ENV-ID' = '4af1b64'
'X-ANYPNT-ORG-ID' = 'c659234ad'
'Authorization' = "`"Bearer $($Token.access_token)`""
}
Wrapping $Token.access_token in the Subexpression operator $() causes PowerShell to evaluate this first and then return the resulting object/string to the caller.

Assigning the token to a variable and passing it to the header helped

Related

PowerShell Environment Variable does not equal its string equivalent

Problem
I am unable to use an Environment Variable as a token in an Invoke-RestMethod
I have the following code, that does work:
$props = #{
Uri = $my_url
Method = "POST"
ContentType = "application/json"
Headers = #{ Authorization = "Bearer Token123456789" }
}
$payload = Invoke-RestMethod #props
But I don't want the token hard-coded here.
However, if I replace Token123456789 with the environment variable $env:token which contains the identical token, it fails.
$props = #{
Uri = $my_url
Method = "POST"
ContentType = "application/json"
Headers = #{ Authorization = "Bearer $env:token" }
}
$payload = Invoke-RestMethod #props
The error message is
Invoke-RestMethod : Specified value has invalid Control characters.
Parameter name: value
At C:\Temp\test.ps1:29 char:12
$payload = Invoke-RestMethod #props
CategoryInfo : NotSpecified: (:) [Invoke-RestMethod], ArgumentException
FullyQualifiedErrorId :
System.ArgumentException,Microsoft.PowerShell.Commands.InvokeRestMethodCommand
What I have tried
I have tried comparing them directly, like this
$bearer1 = "$env:token"
$bearer2 = "Token123456789"
echo $bearer1
echo $bearer2
echo ($bearer1 -eq $bearer2)
The first two echo's output the same results.
However, the last one returns False
Conclusion
The Environment Variable for some reason does not equal its string equivalent.
How do I turn the environment variable into this identical string so that it will work in my Invoke-RestMethod?

Scanner API Call using PowerShell for multiple PowerBI workspaces

I'm trying to call a PowerBI GETinfo Scanner API using PowerShell. One of the requirements is to pass multiple workspaces to get the info. Here is the MS doc link :\
https://learn.microsoft.com/en-us/rest/api/power-bi/admin/workspace-info-post-workspace-info#example
However, I'm not able to pass below syntax for API body in PowerShell.
The below syntax to call multiple workspaces in API body is not working :
$auth_body =#{
"workspaces": [
"97d03602-4873-4760-b37e-1563ef5358e3",
"67b7e93a-3fb3-493c-9e41-2c5051008f24"
]
}
I'm only able to pass single workspace and below syntax works :
$auth_body =#{'workspaces' ="3b7e9b1c-bdac-4e46-a39d-1b3d24a0e122"}
Please help me to form the syntax for multiple workspaces. Seems I'm not able to form key value pair inside PowerShell for multiple workspaces
Updated Code after applying MathiasR.Jessen suggestion:
$authority = 'https://login.microsoftonline.com/oauth2/'+ $tenantID
$authResult = Get-AdalToken -Authority $authority -Resource $resourceAppIdURI -ClientID $UId -Clientsecret $password -TenantID $tenantID
$Token=$authResult.AccessToken
#Write-Output "Token: $Token"
$auth_header = #{
'Accept' = "application/json";
'Authorization' = 'Bearer ' +$Token
}
$auth_body = #{
"workspaces" =
#("50c4bd8e-fc75-433e-a0cd-755f9329515e","97d03602-4873-4760-b37e-1563ef5358e3")
}
$uri = "https://api.powerbi.com/v1.0/myorg/admin/workspaces/getInfo"
$all_workspace = (Invoke-RestMethod -Uri $uri –Headers $auth_header -Body $auth_body –Method Post)
And Error Message :
Invoke-RestMethod : The remote server returned an error: (400) Bad Request.
+ ... rkspace1 = (Invoke-RestMethod -Uri $uri –Headers $auth_header -Body $ ...
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : InvalidOperation: (System.Net.HttpWebRequest:HttpWebRequest) [Invoke-RestMethod], WebException
+ FullyQualifiedErrorId : WebCmdletWebResponseException,Microsoft.PowerShell.Commands.InvokeRestMethodCommand
However, It works perfectly if I provide single workspace.
You're mixing PowerShell and JSON syntax.
To define an array in PowerShell, use the #() array subexpression operator:
$auth_body = #{
"workspaces" = #(
"97d03602-4873-4760-b37e-1563ef5358e3",
"67b7e93a-3fb3-493c-9e41-2c5051008f24"
)
}

Invoking MS Graph API from PowerShell

We need to be able to programatically POST to the MS Graph API in order to bulk assign users to Access Packages, e.g.: https://learn.microsoft.com/en-us/graph/api/accesspackageassignmentrequest-post?view=graph-rest-beta&tabs=http#examples
I am trying things like this:
Invoke-RestMethod 'https://graph.microsoft.com/beta/identityGovernance/entitlementManagement/accessPackageAssignmentRequests' -Method POST -ContentType 'application/json' -Body #{
"requestType": "AdminAdd",
"accessPackageAssignment":{
"targetId":"xxx",
"assignmentPolicyId":"xxx",
"accessPackageId":"xxx"
}
}
Unfortunately though I get errors like this:
At line:2 char:29
+ "requestType": "AdminAdd",
+ ~
Missing '=' operator after key in hash literal.
At line:2 char:29
+ "requestType": "AdminAdd",
+ ~
The hash literal was incomplete.
+ CategoryInfo : ParserError: (:) [], ParentContainsErrorRecordException
+ FullyQualifiedErrorId : MissingEqualsInHashLiteral
Does anyone know how I should be doing it please?
Additionally, we have MFA enforced so the standard $Cred = Get-Credential will not work. What should I use instead?
Thanks
There are several errors on the object syntax of your example:
In Powershell properties are assigned with =
Property names must not be quoted
Property assignments are separated with semicolon
The correct command would look like:
Invoke-RestMethod 'https://graph.microsoft.com/beta/identityGovernance/entitlementManagement/accessPackageAssignmentRequests' -Method POST -ContentType 'application/json' -Body #{
requestType = "AdminAdd";
accessPackageAssignment = {
targetId = "xxx";
assignmentPolicyId = "xxx";
accessPackageId = "xxx"
}
}
Regarding MFA, you need to either use AppTokens or OAuth.
I wanted to call Graph API endpoints through PowerShell as well. This was the script I ended up with:
Install-Module -Name MSAL.PS -RequiredVersion 4.2.1.3
Import-Module MSAL.PS
$clientId = "YOURCLIENTID"
$clientSecret = "YOURCLIENTSECRET"
$tenantId = "YOURTENANTID"
$ConfidentialClientOptions = New-Object Microsoft.Identity.Client.ConfidentialClientApplicationOptions -Property #{ ClientId = $clientId; ClientSecret = $clientSecret; TenantId = $tenantId }
$ConfidentialClient = $ConfidentialClientOptions | New-MsalClientApplication
$tokenObj = Get-MsalToken -Scope 'https://graph.microsoft.com/.default' -ConfidentialClientApplication $ConfidentialClient
$apiUrl = "https://graph.microsoft.com/beta/users?filter=signInActivity/lastSignInDateTime le 2021-06-21T00:00:00Z&`$select=userPrincipalName,displayName,mail,signInActivity"
$res = Invoke-RestMethod -Headers #{Authorization = "Bearer $($tokenObj.AccessToken)"} -Uri $apiUrl -Method Get
$res.value | select userPrincipalName, displayName, mail, #{L="LastSignInDateTime";E={$_.signInActivity.lastSignInDateTime}} | Sort-Object -Property LastSignInDateTime
I wrote a blog post about it as well: https://engineerer.ch/2021/07/01/how-to-use-powershell-to-call-graph-api-endpoints/

Powershell v5.1 Invoke-RestMethod Error Parsing Body

I'm a beginner with Powershell who's trying to send a PUT request to Microsoft Azure to create an Application Insights log query. I'm able to get this working in Postman, but not in a powershell script. This is the error that I'm getting when running the script:
Invoke-RestMethod : {"code":"Unexpected character encountered while parsing value: S. Path '', line 0, position 0.","message":"Unexpected character encountered while parsing value: S. Path '', line 0, position 0.","innererror":{"diagnosticcontext":"f2843c54-dad7-49b5-92ab-e1dadd40e145","time":"2020-07-24T19:59:45.7979293Z"}}
At C:\Users\thophan\source\Update-AiLogQueries.ps1:58 char:9
+ Invoke-RestMethod -Method Put -Uri $uri -Header $header -Body ...
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : InvalidOperation: (System.Net.HttpWebRequest:HttpWebRequest) [Invoke-RestMethod], WebException
+ FullyQualifiedErrorId : WebCmdletWebResponseException,Microsoft.PowerShell.Commands.InvokeRestMethodCommand
From looking at the Microsoft documentation, it looks like it's supposed to be able to take in a hashtable for the body, and I'm quite certain my syntax looks exactly the same as the one from the exameple, so I'm not sure what's going on. Below is an excerpt from my script:
$scope = "shared"
$header = #{
"Authorization" = "Bearer $token"
}
$uri = "https://management.azure.com/subscriptions/$subscriptionId/resourceGroups/$rgName/providers/microsoft.insights/components/$aiName/analyticsItems/item?api-version=2020-02-02-preview"
$difference = Compare-Object -ReferenceObject $localQueryList.value -DifferenceObject $response
if ($difference -ne $null)
{
$difference.ForEach(
{
$body = #{
Scope = $scope
Type = "query"
Name = $_.InputObject.Name
Content = $_.InputObject.Content
}
Invoke-RestMethod -Method Put -Uri $uri -Header $header -Body $body
})
}
UPDATE: Here is the documentation that I was looking at, as requested.
https://learn.microsoft.com/en-us/powershell/module/microsoft.powershell.utility/invoke-restmethod?view=powershell-5.1
The API requires that the body be a JSON string. You can do a simple conversion (using ConvertTo-Json) in your Invoke-RestMethod command and set the content type accordingly.
Invoke-RestMethod -Method Put -Uri $uri -Header $header -Body ($body | ConvertTo-Json) -ContentType 'application/json'

Missing API key when making API RestMethod Call After HTTP Basic authentication in Mailchimp

In PowerShell, I was able to log in using HTTP Basic authentication For Mail Chimp.
$acctname = 'thisismyusername'
$password = 'thisismyapikey'
$params = #{
Uri = 'https://us14.api.mailchimp.com/3.0/';
Method = 'Get'; #(or POST, or whatever)
Headers = #{Authorization = 'Basic ' + [Convert]::ToBase64String([Text.Encoding]::ASCII.GetBytes("$($acctname):$($password)"));} #end headers hash table
} #end $params hash table
$var = Invoke-RestMethod #params
$var
When I try to get basic info on list thats id is "d3a7a4432d".
$URL = "https://us14.api.mailchimp.com/3.0/"
$Endpoint = "/lists/d3a7a4432d"
$URLMailChimp = "$URL$Endpoint"
$gist = Invoke-RestMethod -Method Get -Uri $URLMailChimp
I get this error message:
Invoke-RestMethod : {
"type":"http://developer.mailchimp.com/documentation/mailchimp/guides/error-glossary/",
"title":"API Key Missing",
"status":401,
"detail":"Your request did not include an API key.",
"instance":""
}
At line:7 char:9
+ $gist = Invoke-RestMethod -Method Get -Uri $URLMailChimp
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : InvalidOperation: (System.Net.HttpWebRequest:HttpWebRequest) [Invoke-RestMethod], WebException
+ FullyQualifiedErrorId : WebCmdletWebResponseException,Microsoft.PowerShell.Commands.InvokeRestMethodCommand
I don't understand how to pass it my API key again. I thought by logging it it solved the issue.
I don't use MailChimp, but unless the first invocation provides you with an access token (and the documentation as well as your error message don't look like it would) you need to provide the authentication header with every request.
$acctname = 'thisismyusername'
$password = 'thisismyapikey'
$URL = 'https://us14.api.mailchimp.com/3.0/'
$listID = 'd3a7a4432d'
$auth = #{Authorization = 'Basic ' + [Convert]::ToBase64String([Text.Encoding]::ASCII.GetBytes("${acctname}:${password}"))}
$gist = Invoke-RestMethod -Method Get -Uri "$URL/lists/$listID" -Headers $auth