Back to Blog
Azure
4 min read

Migrating from Legacy MFA to Modern Authentication Methods

Microsoft 365MFASecurityConditional AccessAzure AD

Microsoft is pushing organisations away from legacy per-user MFA towards Conditional Access. If you're still using the old MFA portal, here's how to migrate.

Legacy vs Modern MFA

Legacy (being deprecated):

  • Per-user MFA enabled in users.microsoft.com
  • Limited policy options
  • No device state awareness
  • Basic "enabled/enforced/disabled" states

Modern (recommended):

  • Conditional Access policies
  • Authentication Methods policies
  • Device compliance integration
  • Risk-based authentication
  • Passwordless options

Step 1: Audit Current State

Check Legacy MFA Status

# Connect to MSOnline
Connect-MsolService

# Get users with legacy MFA
Get-MsolUser -All | Where-Object {
  $_.StrongAuthenticationRequirements.State -ne $null
} | Select-Object DisplayName, UserPrincipalName,
  @{N='MFAState';E={$_.StrongAuthenticationRequirements.State}}

Check Conditional Access

# Connect to Graph
Connect-MgGraph -Scopes "Policy.Read.All"

# List CA policies requiring MFA
Get-MgIdentityConditionalAccessPolicy | Where-Object {
  $_.GrantControls.BuiltInControls -contains "mfa"
} | Select-Object DisplayName, State

Step 2: Create Conditional Access Policies

Baseline Policy: Require MFA for All Users

$params = @{
  DisplayName = "Require MFA for all users"
  State = "enabledForReportingButNotEnforced"  # Start in report-only
  Conditions = @{
    Users = @{
      IncludeUsers = @("All")
      ExcludeUsers = @("BREAK_GLASS_ACCOUNT_ID")
    }
    Applications = @{
      IncludeApplications = @("All")
    }
    ClientAppTypes = @("all")
  }
  GrantControls = @{
    Operator = "OR"
    BuiltInControls = @("mfa")
  }
}

New-MgIdentityConditionalAccessPolicy -BodyParameter $params

Admin Policy: Always Require MFA

$adminRoles = @(
  "62e90394-69f5-4237-9190-012177145e10",  # Global Admin
  "194ae4cb-b126-40b2-bd5b-6091b380977d",  # Security Admin
  "f28a1f50-f6e7-4571-818b-6a12f2af6b6c",  # SharePoint Admin
  "29232cdf-9323-42fd-ade2-1d097af3e4de"   # Exchange Admin
)

$params = @{
  DisplayName = "Require MFA for admins - Always"
  State = "enabled"
  Conditions = @{
    Users = @{
      IncludeRoles = $adminRoles
    }
    Applications = @{
      IncludeApplications = @("All")
    }
  }
  GrantControls = @{
    Operator = "OR"
    BuiltInControls = @("mfa")
  }
  SessionControls = @{
    SignInFrequency = @{
      Value = 4
      Type = "hours"
      IsEnabled = $true
    }
  }
}

New-MgIdentityConditionalAccessPolicy -BodyParameter $params

Step 3: Configure Authentication Methods

Enable Modern Methods

# Enable Microsoft Authenticator
$authenticatorConfig = @{
  "@odata.type" = "#microsoft.graph.microsoftAuthenticatorAuthenticationMethodConfiguration"
  State = "enabled"
  IncludeTargets = @(
    @{
      TargetType = "group"
      Id = "all_users"
      IsRegistrationRequired = $false
      AuthenticationMode = "any"
    }
  )
}

Update-MgPolicyAuthenticationMethodPolicyAuthenticationMethodConfiguration `
  -AuthenticationMethodConfigurationId "MicrosoftAuthenticator" `
  -BodyParameter $authenticatorConfig

Enable FIDO2 Keys

$fido2Config = @{
  "@odata.type" = "#microsoft.graph.fido2AuthenticationMethodConfiguration"
  State = "enabled"
  IsAttestationEnforced = $false
  IsSelfServiceRegistrationAllowed = $true
  KeyRestrictions = @{
    IsEnforced = $false
    EnforcementType = "allow"
    AaGuids = @()
  }
}

Update-MgPolicyAuthenticationMethodPolicyAuthenticationMethodConfiguration `
  -AuthenticationMethodConfigurationId "Fido2" `
  -BodyParameter $fido2Config

Step 4: Temporary Access Pass for Migration

Enable TAP for users who need to re-register:

$tapConfig = @{
  "@odata.type" = "#microsoft.graph.temporaryAccessPassAuthenticationMethodConfiguration"
  State = "enabled"
  DefaultLifetimeInMinutes = 60
  DefaultLength = 8
  IsUsableOnce = $true
  IncludeTargets = @(
    @{
      TargetType = "group"
      Id = "HELPDESK_GROUP_ID"
    }
  )
}

Update-MgPolicyAuthenticationMethodPolicyAuthenticationMethodConfiguration `
  -AuthenticationMethodConfigurationId "TemporaryAccessPass" `
  -BodyParameter $tapConfig

Step 5: Migration Process

For Each User

  1. Create TAP (if needed for re-registration):
$tap = New-MgUserAuthenticationTemporaryAccessPassMethod `
  -UserId "[email protected]" `
  -LifetimeInMinutes 60 `
  -IsUsableOnce $true

$tap.TemporaryAccessPass  # Give this to user
  1. User registers new method at https://aka.ms/mfasetup

  2. Disable legacy MFA:

$mfa = @{
  StrongAuthenticationRequirements = @()
}
Set-MsolUser -UserPrincipalName "[email protected]" -StrongAuthenticationRequirements $mfa

Step 6: Block Legacy Authentication

After migration, block protocols that don't support MFA:

$params = @{
  DisplayName = "Block legacy authentication"
  State = "enabled"
  Conditions = @{
    Users = @{
      IncludeUsers = @("All")
      ExcludeUsers = @("BREAK_GLASS_ACCOUNT_ID")
    }
    Applications = @{
      IncludeApplications = @("All")
    }
    ClientAppTypes = @("exchangeActiveSync", "other")
  }
  GrantControls = @{
    Operator = "OR"
    BuiltInControls = @("block")
  }
}

New-MgIdentityConditionalAccessPolicy -BodyParameter $params

Monitoring the Migration

// Sign-in logs showing legacy auth attempts
SigninLogs
| where TimeGenerated > ago(7d)
| where ClientAppUsed in ("Exchange ActiveSync", "IMAP4", "MAPI Over HTTP", "Offline Address Book", "Other clients", "POP3", "SMTP")
| summarize count() by UserPrincipalName, ClientAppUsed
| order by count_ desc

Need help modernising your authentication infrastructure? Get in touch - we help organisations implement secure identity solutions.

Need help with your Azure environment?

Get in touch for a free consultation.

Get in Touch