Friday, February 14, 2020

Connect to Azure AD PowerShell with MFA

Sometimes you might want to connect to Azure AD PowerShell with MFA but there is no way for the PowerShell to prompt you for MFA unless you have MFA enforced on the account.

The scenario which I had was calling a cmdlet for Privileged Identity Management where I was activating a role which requires MFA https://docs.microsoft.com/en-us/powershell/module/azuread/?view=azureadps-2.0-preview#privileged_role_management

The solution is to get an access token with MFA and pass the token while connecting to PowerShell.

The pre-requisite is that you have already installed Azure AD Preview PowerShell by following these steps https://docs.microsoft.com/en-us/powershell/azure/active-directory/install-adv2?view=azureadps-2.0

# Install msal.ps
if(!(Get-Module | Where-Object {$_.Name -eq 'PowerShellGet' -and $_.Version -ge '2.2.4.1'})) { Install-Module PowerShellGet -Force }
if(!(Get-Package msal.ps)) { Install-Package msal.ps }

# Get token for MS Graph by prompting for MFA
$MsResponse = Get-MSALToken -Scopes @("https://graph.microsoft.com/.default") -ClientId "1b730954-1685-4b74-9bfd-dac224a7b894" -RedirectUri "urn:ietf:wg:oauth:2.0:oob" -Authority "https://login.microsoftonline.com/common" -Interactive -ExtraQueryParameters @{claims='{"access_token" : {"amr": { "values": ["mfa"] }}}'}

# Get token for AAD Graph
$AadResponse = Get-MSALToken -Scopes @("https://graph.windows.net/.default") -ClientId "1b730954-1685-4b74-9bfd-dac224a7b894" -RedirectUri "urn:ietf:wg:oauth:2.0:oob" -Authority "https://login.microsoftonline.com/common"

Connect-AzureAD -AadAccessToken $AadResponse.AccessToken -MsAccessToken $MsResponse.AccessToken -AccountId: "upn" -tenantId: "tenantId"

# Call cmdlet which requires MFA
$resource = Get-AzureADMSPrivilegedResource -ProviderId AadRoles

$roleDefinition = Get-AzureADMSPrivilegedRoleDefinition  -ProviderId AadRoles -ResourceId $resource.Id -Filter "DisplayName eq 'Global Administrator'"

$subject = Get-AzureADUser -Filter "userPrincipalName eq 'upn'"

$schedule = New-Object Microsoft.Open.MSGraph.Model.AzureADMSPrivilegedSchedule
$schedule.Type = "Once"
$schedule.Duration="PT1H"
$schedule.StartDateTime = (Get-Date).ToUniversalTime().ToString("yyyy-MM-ddTHH:mm:ss.fffZ")

Open-AzureADMSPrivilegedRoleAssignmentRequest -ProviderId AadRoles -Schedule $schedule -ResourceId $resource.Id -RoleDefinitionId $roleDefinition.Id -SubjectId $subject.ObjectId -AssignmentState "Active" -Type "UserAdd" -Reason "Test"



11 comments:

  1. In your get-msaltoken you mention a client ID, is this for an app registration?

    ReplyDelete
  2. Great script - even referenced from Microsoft docs.
    I can't find anything about the schedule Duration attribute. What does that mean PT1H?
    If I provide a schedule like this I get a funny enddate:
    EndDateTime: 1-1-0001 08:00:00
    while I assumed it would yield something like startdatetime+1 hour

    ReplyDelete
    Replies
    1. PT1H stands for one hour. More details here https://en.wikipedia.org/wiki/ISO_8601#Durations
      You can ignore the end time in the response if you see a duration. If you query the assignment, you will see an end time which will be startdatetime+1 hour

      Delete
  3. You, my friend, are a genius, a gentleman and a scholar.

    ReplyDelete
  4. Hi Anuj,
    Can I use a service principal to authenticate and connect to azure ad or does it have to be user details? I
    Using the SPN I get Forbidden error when I try to run Open-AzureADMSPrivilegedRoleAssignmentRequest command

    ReplyDelete
  5. Hi Anuj,

    Would you be able to answer the below question ?
    Open-AzureADMSPrivilegedRoleAssignmentRequest Fails when executed with SPN

    Error: Open-AzureADMSPrivilegedRoleAssignmentRequest : Error occurred while executing OpenAzureADMSPrivilegedRoleAssignmentRequest
    Code: UnauthorizedAccessException
    Message: Attempted to perform an unauthorized operation.

    The same works fine when I use my user credentials, is there any limitation?
    I ran below command first.
    Connect-AzureAD -TenantId $TenantId -ApplicationId $ApplicationId -CertificateThumbprint $Thumbprint

    ReplyDelete
  6. Anuj,
    Absolutely happy and stunned to find this code that seems to be the only one that works in MFA scenario! Even Microsoft endorsed your code!
    BTW, what is ClienId and why is it hard coded to 53d3b514-c543-46eb-be4c-1c4d6ccb50a8.Can I see this anywhere visually in my tenant?
    Thanks,
    Soumya

    ReplyDelete
  7. Thanks for this great post Anuj. This is the only thing that works for MFA scenario. Can you tell me what is Client Id and why is it hard coded?

    ReplyDelete
  8. You are a star!!!, Thank you so much for getting me off this pestering problem. Gracias

    ReplyDelete
  9. This is a really useful blog post, thank you. I had to change the redirectUri in the two Get-MSALToken cmdlets from 'urn:ietf:wg:oauth:2.0:oob' to 'https://login.microsoftonline.com/common/oauth2/nativeclient' because I was getting the error "Sorry, but we’re having trouble signing you in. AADSTS500119: Redirect URIs with urn: schemes are prohibited" when trying to get a token.

    ReplyDelete