Move from per-user MFA to Conditional Access MFA in Azure AD

More often than not, I see both per-user MFA and Conditional Access MFA enabled in Azure AD tenants. There seems to be a misconception amongst IT admins that by disabling per-user MFA, users will need to re-register their MFA authentication methods. So, admins end up leaving per-user MFA enabled and also creating a Conditional Access MFA policy. This often results in some users still using per-user MFA and newer users using conditional access (especially if there is not a good onboarding process), resulting in an inconsistent user experience. Assuming you have an Azure AD P1/P2 license, Conditional Access is the recommended method for MFA. Conditional access is much more versatile than per-user MFA and allows you much more control over how MFA is enforced. By disabling per-user MFA, users will not lose their MFA authentication methods. Authentication methods are tied to the user identity and remain intact after disabling per-user MFA. This quick post will describe how you can easily move from per-user MFA to conditional access MFA. 

First, I suggest you visit this link and read through it – https://learn.microsoft.com/en-us/azure/active-directory/authentication/howto-mfa-userstates

First, let’s look at an example sign-in log with per-user MFA enabled. We can see MFA was used as the authentication requirement and it was required by the Per-User MFA policy:

We can also see conditional access was not applied for this sign-in: 

If we look at our per-user MFA settings, I have it enforced for three users in my lab tenant. If this was a production environment, you may have hundreds or thousands of users using per-user MFA. You can only bulk update a subset of them at a time from the GUI. Luckily, Microsoft provides a script (from the above link) that disables per-user MFA on all accounts.

If we run the script, per-user MFA is disabled for all users in a matter of seconds. Save the script as a .ps1 file, open PowerShell, install the MSOnline module if you don’t already have it installed, connect to Azure AD with connect-msolservice, and run the script file.

# Sets the MFA requirement state
function Set-MfaState {
    [CmdletBinding()]
    param(
        [Parameter(ValueFromPipelineByPropertyName=$True)]
        $ObjectId,
        [Parameter(ValueFromPipelineByPropertyName=$True)]
        $UserPrincipalName,
        [ValidateSet("Disabled","Enabled","Enforced")]
        $State
    )
    Process {
        Write-Verbose ("Setting MFA state for user '{0}' to '{1}'." -f $ObjectId, $State)
        $Requirements = @()
        if ($State -ne "Disabled") {
            $Requirement =
                [Microsoft.Online.Administration.StrongAuthenticationRequirement]::new()
            $Requirement.RelyingParty = "*"
            $Requirement.State = $State
            $Requirements += $Requirement
        }
        Set-MsolUser -ObjectId $ObjectId -UserPrincipalName $UserPrincipalName `
                     -StrongAuthenticationRequirements $Requirements
    }
}
# Disable MFA for all users
Get-MsolUser -All | Set-MfaState -State Disabled

If we refresh the per-user MFA window, all users have their MFA state disabled: 

If we look at the authentication methods for an account we just disabled for per-user MFA, we can see the phone number and authenticator are still tied to their account:

Configure your Conditional Access MFA policy. We will keep it simple in this example and require MFA for all users and all apps. However, consider using the new authentication strength controls, requiring sign-in risk so users don’t get MFA fatigue, and having a break-glass account excluded from MFA.  

After enabling conditional access MFA, signed in users will receive this message if they are using the browser: 

If we sign in, we are still prompted with the same authentication method as before (authenticator in this example), and we can see the conditional access MFA policy was successfully applied: