Skip to content

Instantly share code, notes, and snippets.

Show Gist options
  • Save janegilring/f2147a1f48f0e461139808262fbb2a5d to your computer and use it in GitHub Desktop.
Save janegilring/f2147a1f48f0e461139808262fbb2a5d to your computer and use it in GitHub Desktop.
Example on how to use a Windows VM Managed Service Identity (MSI) access token to authenticate to Azure AD PowerShell
# Step 1 - Enable MSI on the resource - in this case a virtual machine
# Step 2 - Assign permissions to the MSI - in this example full permissions to Azure AD
$Principal = Get-AzureADServicePrincipal -searchstring MGMT-AZ-01
$Role = Get-AzureADDirectoryRole | Where-Object DisplayName -Like 'Company Administrator'
Add-AzureADDirectoryRoleMember -ObjectId $Role.ObjectId -RefObjectId $Principal.ObjectId
# Step 3 - Get an access token. Note that the resource we are requesting a token for is https://graph.windows.net
$response = Invoke-WebRequest -UseBasicParsing -Uri 'http://169.254.169.254/metadata/identity/oauth2/token?api-version=2018-02-01&resource=https://graph.windows.net/' -Method GET -Headers @{Metadata="true"}
$content = $response.Content | ConvertFrom-Json
$AadGraphToken = $content.access_token
# Step 4 - Authenticate to Azure AD PowerShell using the token
Connect-AzureAD -AadAccessToken $AadGraphToken -AccountId 413b4ad1-87e4-4312-9d4a-1f00ca2fd3cb -TenantId b5fb2192-06f1-43f4-a44f-1d42a9106deb
# Run an Azure AD command against the API - for example Get-AzureADUser
Get-AzureADUser
@LockTar
Copy link

LockTar commented Jan 12, 2019

If you make your MSI Company Administrator it will have a lot of permissions... Why not giving the permissions in the Azure AD that it only needs? Like this:

Connect-AzureAD
$msiObjectId = "YOUR MSI OBJECT ID HERE"

$adgraph = Get-AzureADServicePrincipal -Filter "AppId eq '00000002-0000-0000-c000-000000000000'"
Write-Host "-ResourceId $($adgraph.ObjectId)"

# Manage apps that this app creates or owns (Role: Application.ReadWrite.OwnedBy)
$rdscope = "824c81eb-e3f8-4ee6-8f6d-de7f50d565b7"

# Read directory data (Role: Directory.Read.All)
$rdscope2 = "5778995a-e1bf-45b8-affa-663a9f3f4d04"

try
{
    New-AzureADServiceAppRoleAssignment -Id $rdscope -PrincipalId $msiObjectId -ObjectId $msiObjectId -ResourceId $adgraph.ObjectId
    New-AzureADServiceAppRoleAssignment -Id $rdscope2 -PrincipalId $msiObjectId -ObjectId $msiObjectId -ResourceId $adgraph.ObjectId
}
#the New-AzureADServiceAppRoleAssignment is throwing the following exception
#the message is Unauthorized, but the assignment is applied!
catch [Microsoft.Open.AzureAD16.Client.ApiException]
{
    #This error appears when the assignment already has been done
    if ($Error[0].Exception.Message.Contains("BadRequest"))
    {
        Write-Output "The Role assignment was already applied. Check if all roles are applied!"
    }
}

Write-Output "The Role assignment:"
Get-AzureADServiceAppRoleAssignedTo -ObjectId $msiObjectId

@janegilring
Copy link
Author

Good point - principle of least privileges should be followed

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment