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?
Related
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
Goal: I want to send a POST API request to JIRA with irm (Invoke-RestMethod).
Environment:
OS: Windows 10 64 bit
Powershell 5 (I think it's 5, it's the default that comes with Windows)
Script:
$Body = #{
'fields' = #{
'project' = #{'key' = 'ABC'}
'summary' = "summary"
'description' = "desc"
'issuetype' = #{'name' = 'Test'}
'assignee' = 'user'
}
}
$JsonBody = ($Body | ConvertTo-Json)
$params = #{
Uri = "https://jira.myjira.co.uk/rest/api/latest/issue"
Headers = #{ "Authorization" = "Basic myToken" }
Method = "POST"
Body = $JsonBody
ContentType = "application/json"
}
$response = irm $params
$response | Out-File test.txt
When I execute it, I get the message below. Powershell is complaining but I don't know what is wrong with my parameters.
Invoke-RestMethod : Cannot bind parameter 'Uri'. Cannot convert the "System.Collections.Hashtable" value of type
"System.Collections.Hashtable" to type "System.Uri".
At C:\Users\User\Downloads\MyScript.ps1:64 char:17
+ $response = irm $params
+ ~~~~~~~
+ CategoryInfo : InvalidArgument: (:) [Invoke-RestMethod], ParameterBindingException
+ FullyQualifiedErrorId : CannotConvertArgumentNoMessage,Microsoft.PowerShell.Commands.InvokeRestMethodCommand
What I've tried:
Executed it in ISE and it does the same thing
I used the #params format for another script and it was fine. I wonder if the issue is with the Uri part...
Googling and looking at stackoverflow, there was similar matches but doesn't fit my scenario
Any help is appreciated, I've been banging my head against a wall for an hour.
Simply change the $params to #params, this is called splatting.
"Splatting is a method of passing a collection of parameter values to a command as a unit."
https://learn.microsoft.com/en-us/powershell/module/microsoft.powershell.core/about/about_splatting?view=powershell-7.1
$response = irm #params
I'm not able to understand why my code is failing.
$Param = #{
Uri = ("https://api.crowdstrike.com/policy/combined/reveal-uninstall-token/v1")
Method = 'post'
Headers = #{
'Content-type' = 'application/json'
authorization = "$($Token.token_type) $($Token.access_token)"
}
}
$data = #{
audit_message="test api"
device_id='111111111111111111111111111'
}
$json = $data | ConvertTo-Json
$uninstall = Invoke-RestMethod #Param -Body #json
Error:
Invoke-RestMethod : A positional parameter cannot be found that accepts argument ''.
At line:48 char:14
+ $uninstall = Invoke-RestMethod #Param -Body #json
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : InvalidArgument: (:) [Invoke-RestMethod], ParameterBindingException
+ FullyQualifiedErrorId : PositionalParameterNotFound,Microsoft.PowerShell.Commands.InvokeRestMethodCommand
I'm passing the data as JSON (as required per the below screen shot):
[![enter image description here][1]][1]
Any hints please ?
Thank you !
[1]: https://i.stack.imgur.com/eeRaj.png
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/
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