Azure Pipelines and Azure Functions (and Automation Accounts) can have managed identities, in other words, a service principal. This service principal can be assigned to Azure AD roles (e.g. to modify users / devices) or graph / Azure RM resources. A service principal could even be a global admin, and Service Principals don’t have to do MFA…. đŸ™‚
In both Pipelines and Functions the new Az module is enabled and logged into your tenant by default as the service principal, how cool would it be to use that identity to do those (hopefully few) things that are still only supported by e.g. the AzureAD module?
Here’s an example on getting tokens for Azure AD and for Graph, obviously you could also get tokens for other audiences the same way:
$context = [Microsoft.Azure.Commands.Common.Authentication.Abstractions.AzureRmProfileProvider]::Instance.Profile.DefaultContext
$graphToken = [Microsoft.Azure.Commands.Common.Authentication.AzureSession]::Instance.AuthenticationFactory.Authenticate($context.Account, $context.Environment, $context.Tenant.Id.ToString(), $null, [Microsoft.Azure.Commands.Common.Authentication.ShowDialog]::Never, $null, "https://graph.microsoft.com").AccessToken
$aadToken = [Microsoft.Azure.Commands.Common.Authentication.AzureSession]::Instance.AuthenticationFactory.Authenticate($context.Account, $context.Environment, $context.Tenant.Id.ToString(), $null, [Microsoft.Azure.Commands.Common.Authentication.ShowDialog]::Never, $null, "https://graph.windows.net").AccessToken
Write-Output "Hi I'm $($context.Account.Id)"
Connect-AzureAD -AadAccessToken $aadToken -AccountId $context.Account.Id -TenantId $context.tenant.id
get-azureaduser -Top 5
If you want to do this from an old fashioned Azure Runbook (please move to functions!) then you’ll have to log in to Az first:
try
{
$servicePrincipalConnection = Get-AutomationConnection -Name "AzureRunAsConnection"
Connect-AzAccount -Tenant $servicePrincipalConnection.TenantID `
-ApplicationId $servicePrincipalConnection.ApplicationID `
-CertificateThumbprint $servicePrincipalConnection.CertificateThumbprint `
-ServicePrincipal
}catch {
Write-Error -Message $_.Exception
throw $_.Exception
}
Hi Jos,
It seems you have forgot the parameter:
in your
to fully authenticate in AzureAD
some command does not work without this
Thank you for providing this info. Works pretty well. What I’m trying to achieve is, connecting to ExchangeOnline with a Bearer-Token. The thing is, there’s a token generated by my second commandline. But then, with the command New-PSSession I get the message, I’m not authorized. If I catch with Fiddler the token generated by the command Connect-ExchangeOnline and insert it into $exoToken, I can connect with the following code. Any idea how I make this code work? $context = Get-AzContext # Build the auth information $exoToken = [Microsoft.Azure.Commands.Common.Authentication.AzureSession]::Instance.AuthenticationFactory.Authenticate($context.Account, $context.Environment, $context.Tenant.Id.ToString(), $null, [Microsoft.Azure.Commands.Common.Authentication.ShowDialog]::Never, $null, "https://outlook.office365.com").AccessToken $Authorization = "Bearer {0}" -f $exoToken… Read more »
Hi Jos,
Thanks for this post.
I’ve been trying to use this to login to graph and do some Intune automation but when I see the tokens that are generated I don’t get anything from DeviceManagementManagedDevices permissions
Is there a way to point to an ApplicationID on this process or anything that can help me authenticate with Delegated permissions without creating App Secrets?
Hi. Thanks for your approach with example script.
I am trying to apply the same concept in order to apply it on Connect-MsolService, so it should be something like the script below,
$context = [Microsoft.Azure.Commands.Common.Authentication.Abstractions.AzureRmProfileProvider]::Instance.Profile.DefaultContext
$graphToken = [Microsoft.Azure.Commands.Common.Authentication.AzureSession]::Instance.AuthenticationFactory.Authenticate($context.Account, $context.Environment, $context.Tenant.Id.ToString(), $null, [Microsoft.Azure.Commands.Common.Authentication.ShowDialog]::Never, $null, “https://graph.microsoft.com”).AccessToken
$aadToken = [Microsoft.Azure.Commands.Common.Authentication.AzureSession]::Instance.AuthenticationFactory.Authenticate($context.Account, $context.Environment, $context.Tenant.Id.ToString(), $null, [Microsoft.Azure.Commands.Common.Authentication.ShowDialog]::Never, $null, “https://graph.windows.net”).AccessToken
Write-Output “Hi I’m $($context.Account.Id)“
Connect-MsolService -AdGraphAccessToken $aadToken -MsGraphAccessToken $graphToken
However, I got the error: Connect-MsolService: IDX10703: Unable to decode the ‘header’: ‘eyJ0e….<the jwt token>’.
Have everyone tried to Connect-MsolService in this way?
Anny idea how to make this work?
Thanks a million, any help appreciated.
Hi Jos,
Thank you for this!
This appears to work for almost all the AzureAD cmdlets but today I stumbled across one that didn’t work.
New-AzureADMSInvitation
Would you have any idea on why this command would not work using the above authentication approach?
Any thoughts on this would be appreciated.
The error I’m getting is Object reference not set to an instance of an object.
Hi Jos, I am following the same process did the following : created the SPN Added the Graph Permissions for create Group and Group readwrite Acquired the token also during the process. When it tried to connect it throws out the error. ]Error occurred while executing GetUsers Code: Authorization_RequestDenied Message: Insufficient privileges to complete the operation. Permissions on Graph: Group.Create Group.Read.All User.Read Application.ReadWrite.Owned Directory.Read.All all are admin consent for the tenant Any advice would be great as i can run the same script from the local it works.From the pipeline it throws the Error as i did created the SPN access on subscription to “Contributor” also. The SPN is set manually… Read more »