UPDATE (2018-02-12): The method described below does not work, unfortunately. Connect-AzureAD runs without error but the AD context you get is not authorized to perform AD operations. I get errors that look like this:

Get-AzureADApplication : Error occurred while executing GetApplications 
Code: Authentication_MissingOrMalformed
Message: Access Token missing or malformed.
RequestId: 1f15adc8-1cf5-443b-b78d-88db66701506
DateTimeStamp: Mon, 12 Feb 2018 16:43:42 GMT
HttpStatusCode: Unauthorized
HttpStatusDescription: Unauthorized
HttpResponseStatus: Completed

The access token is missing or malformed. I’m trying to figure out what goes wrong since an access token is actually provided (so it can not be missing). But ‘malformed’ is also strange because this is the token I get back from Add-AzureRmAccount.

Checking the actual access token in jwt.io proves that is isn’t malformed. However, the token audience is https://management.core.windows.net/. This is probably not the audience that is expected when authenticating against Azure AD (unfortunately we can not inspect this token). So that is probably why the token is ‘malformed’.

This means I’m stuck with a double login when using both Add-AzureRmAccount and Connect-AzureAD in one Powershell script… If someone knows a solution, please leave a comment :)

UPDATE (2018-02-13): I also found out that it doesn’t really matter what you pass as access token to Connect-AzureAD. The following runs without error: Connect-AzureAD -TenantId $tenantId -AadAccessToken "this is no token" -AccountId $accountId. Errors happen only later when you try to run operations against Azure AD.

I had to write a Powershell script that connected to Azure Resource Manager via Add-AzureRmAccount and to Azure AD via Connect-AzureAD. If you write your script like this:

Add-AzureRmAccount -SubscriptionId $subscriptionId
Connect-AzureAD -TenantId $tenantId

you are presented twice with this login dialog:

This is of course annoying for users of my script so I set out to improve this. The end result looks like this:

$rmAccount = Add-AzureRmAccount -SubscriptionId $subscriptionId
$tenantId = (Get-AzureRmSubscription -SubscriptionId $subscriptionId).TenantId
$tokenCache = $rmAccount.Context.TokenCache
$cachedTokens = $tokenCache.ReadItems() `
        | where { $_.TenantId -eq $tenantId } `
        | Sort-Object -Property ExpiresOn -Descending
Connect-AzureAD -TenantId $tenantId `
                -AadAccessToken $cachedTokens[0].AccessToken `
                -AccountId $rmAccount.Context.Account.Id

Let’s dissect this:

  • Login to Azure Resource Manager and store the result.
  • Get the tenant id from the subscription.
  • Get the token cache property from the ARM account. This is an object of type Microsoft.IdentityModel.Clients.ActiveDirectory.TokenCache from the ADAL library.
  • We can retrieve the access token we want through the ReadItems() method, filtering on tenant id and getting the most recent one.
  • And finally we can use the access token to connect to Azure AD.

And that’s how we prevent a double login in Powershell scripts that use both Add-AzureRmAccount and Connect-AzureAD.