Connect-MgGraph : Cannot Bind Parameter AccessToken MSAL PowerShell

Table of Contents

Cannot Bind Parameter AccessToken

$ClientSecret = 'v~58Q~sf0AcfemVucNGGC1yxETFejdzxgZd4taqg'
$params = @{
    ClientId = '87c980ca-a1dd-4748-98db-8007af2bdc70'
    TenantId = 'c032627b-6715-4e39-9990-bcf48ee5e0c5'
    ClientSecret = $ClientSecret | ConvertTo-SecureString -AsPlainText -Force
    AzureCloudInstance = '1'
}

$MsalToken = (Get-MsalToken @params).AccessToken
Connect-Graph -AccessToken $MsalToken

In some cases, when we trying to connect to Microsoft Graph PowerShell. We got the following error.

Connect-MgGraph : Cannot bind parameter ‘AccessToken’. Cannot convert the “…” value of type “System.String” to type “System.Security.SecureString”.
At line:1 char:28
+ Connect-Graph -AccessToken $MsalToken.AccessToken
+                            ~~~~~~~~~~~~~~~~~~~~~~
    + CategoryInfo          : InvalidArgument: (:) [Connect-MgGraph], ParameterBindingException
    + FullyQualifiedErrorId : CannotConvertArgumentNoMessage,Microsoft.Graph.PowerShell.Authentication.Cmdlets.Connect
   MgGraph

We’ve check the installed version of Microsoft Graph PowerShell module. It shows we have install the v2 of the Microsoft Graph PowerShell SDK.

PS C:\> Get-InstalledModule Microsoft.Graph | ft -AutoSize

Version Name            Repository Description
------- ----            ---------- -----------
2.3.0   Microsoft.Graph PSGallery  Microsoft Graph PowerShell module

We did a try on a computer has been installed the v1 of Graph PowerShell module. And as you can see, the script works without any error.

PS C:\> Get-InstalledModule Microsoft.Graph

Version Name            Repository Description
------- ----            ---------- -----------
1.28.0  Microsoft.Graph PSGallery  Microsoft Graph PowerShell module
Import-Module MSAL.PS -Force
$ClientSecret = 'v~58Q~sf0AcfemVucNGGC1yxETFejdzxgZd4taqg'
$params = @ {
    ClientId = '87c980ca-a1dd-4748-98db-8007af2bdc70'
    TenantId = 'c032627b-6715-4e39-9990-bcf48ee5e0c5'
    ClientSecret = $ClientSecret | ConvertTo-SecureString -AsPlainText -Force
    AzureCloudInstance = '1'
}
$MsalToken = Get-MsalToken @params
Connect-Graph -AccessToken $MsalToken.AccessToken
PS C:\> Connect-Graph -AccessToken $MsalToken.AccessToken
Welcome To Microsoft Graph!
PS C:\>

Solution

When we check the AccessToken of the Connect-MgGraph command. We found that, in the v2 of the SDK the AccessToken must be a SecureString instead of String on the v1.

PS C:\> Get-Help Connect-Graph -Parameter AccessToken   #This ran on v2

-AccessToken <securestring>   
    Required?                    true
    Position?                    1
    Accept pipeline input?       false
    Parameter set name           AccessTokenParameterSet

PS C:\> Get-Help Connect-Graph -Parameter AccessToken   #This ran on v1

-AccessToken <string>       
    Required?                    false
    Position?                    1
    Accept pipeline input?       false
    Parameter set name           AccessTokenParameterSet

This is a change in behavior between v1.0 and v2.0 of the Microsoft Graph PowerShell module. If you want your scripts works on the v2. You must convert the AccessToken to a SecureString as below:

$ClientSecret = 'v~58Q~sf0AcfemVucNGGC1yxETFejdzxgZd4taqg'
$params = @{
    ClientId = '87c980ca-a1dd-4748-98db-8007af2bdc70'
    TenantId = 'c032627b-6715-4e39-9990-bcf48ee5e0c5'
    ClientSecret = $ClientSecret | ConvertTo-SecureString -AsPlainText -Force
    AzureCloudInstance = '1'
}

$MsalToken = (Get-MsalToken @params).AccessToken
$token = ($MsalToken | ConvertTo-SecureString -AsPlainText -Force)

Connect-Graph -AccessToken $token

As you can see, this time, we’re able to connect to Microsoft PowerShell API. When we check the session context, we can see the AuthType is UserProvidedAccessToken.

PS C:\> Connect-Graph -AccessToken $token
Welcome To Microsoft Graph!

PS C:\> Get-MgContext

ClientId               : 87c980ca-a1dd-4748-98db-8007af2bdc70
TenantId               : c032627b-6715-4e39-9990-bcf48ee5e0c5
Scopes                 : {User.ReadWrite.All}
AuthType               : UserProvidedAccessToken
TokenCredentialType    : UserProvidedAccessToken

Maintain compatibility with v1.0

If you want your scripts to maintain compatibility with v1.0, you can convert the access token value conditionally:

  1. Check the AccessToken parameter property.
  2. If match SecureString then convert the AccessToken to SecureString.
  3. Else connect to Graph as v1.
$ClientSecret = 'v~58Q~sf0AcfemVucNGGC1yxETFejdzxgZd4taqg'
$params = @{
    ClientId = '87c980ca-a1dd-4748-98db-8007af2bdc70'
    TenantId = 'c032627b-6715-4e39-9990-bcf48ee5e0c5'
    ClientSecret = $ClientSecret | ConvertTo-SecureString -AsPlainText -Force
    AzureCloudInstance = '1'
}

$MsalToken = (Get-MsalToken @params).AccessToken

$targetParameter = (Get-Command Connect-MgGraph).Parameters['AccessToken']

if ($targetParameter.ParameterType -eq [securestring]){
  Connect-MgGraph -AccessToken ( $MsalToken | ConvertTo-SecureString -AsPlainText -Force )
} else {
    Connect-MgGraph -AccessToken $MsalToken
}

Leave a Comment

Required fields are marked *