In this section

IAM4.2 MFA Registration and Enforcement

14 hours · Module 4
What you already know

Section 4.1 revealed your tenant's authentication tier distribution, how many users are password-only, how many have MFA, and how many have phishing-resistant methods. This section closes the registration gap. You configure authentication method policies that control which methods are available, design registration campaigns that drive adoption, and build monitoring that tracks progress toward 100% MFA coverage.

The registration gap

MFA only works when users have registered an MFA method. A Conditional Access policy that requires MFA forces unregistered users into one of two outcomes: the user registers during their next sign-in (which means they choose whatever method requires the least effort, usually SMS), or the user gets blocked entirely (which means a helpdesk ticket and an angry email to the IT director). Neither outcome produces good authentication governance.

The registration gap is the difference between "MFA is required" and "users have registered appropriate MFA methods." Most organizations enforce MFA through Conditional Access and call it done. The registration that precedes enforcement is unmanaged. Users register whichever method the registration wizard presents first. Nobody audits which methods were registered. Nobody campaigns for stronger methods. Nobody tracks the 38 users who haven't registered anything at all.

Registration governance means controlling three things: which methods are available (authentication method policies), which users register which methods (targeted registration campaigns), and whether the registration coverage meets your threshold (monitoring and alerting). This section covers all three.

MFA Registration Lifecycle Method Policy Which methods exist Registration Campaign Who registers what CA Enforcement Require MFA (Module 5) Monitoring Track coverage The registration gap: users without methods → blocked by CA or registered for the weakest available option

Estimated time: 55 minutes.

Authentication method policies

Authentication method policies control which methods are available in your tenant and which users can register each method. These are the upstream controls, they determine the menu of options users see when they register.

Entra Admin Center

ProtectionAuthentication methodsPolicies
Each authentication method has its own policy row: Microsoft Authenticator, FIDO2 security keys, SMS, Voice call, Temporary Access Pass, Certificate-based authentication, and third-party software OATH tokens. Click any method to configure it. Each method policy has three settings: Enable/Disable (is the method available at all?), Target (which users or groups can register this method: all users or a specific group), and method-specific configuration (e.g., number matching for Authenticator, attestation for FIDO2).

Query the current method policy state:

$policies = Invoke-MgGraphRequest -Method GET `
  -Uri "https://graph.microsoft.com/v1.0/policies/authenticationMethodsPolicy" `
  -OutputType PSObject

foreach ($config in $policies.authenticationMethodConfigurations) {
    $state = $config.state
    $targets = if ($config.includeTargets) {
        ($config.includeTargets | ForEach-Object { $_.targetType + ": " + $_.id }) -join ", "
    } else { "none" }
    Write-Host "$($config.id): $state, targets: $targets"
}
microsoftAuthenticator: enabled, targets: group: all_users
sms: enabled, targets: group: all_users
fido2: disabled, targets: none
temporaryAccessPass: disabled, targets: none
x509Certificate: disabled, targets: none
voice: enabled, targets: group: all_users
softwareOath: enabled, targets: group: all_users

This output reveals a common posture: Authenticator and SMS enabled for everyone, FIDO2 and TAP disabled, certificate-based authentication disabled. The tenant's method menu is limited to phishable options because the phishing-resistant methods haven't been turned on. Enabling FIDO2 and TAP is a prerequisite for the passwordless roadmap, you can't register what isn't enabled.

Enable FIDO2 for the administrators group (start with privileged users before expanding to all users):

Entra Admin Center

ProtectionAuthentication methodsPoliciesFIDO2 security key
Toggle Enable to Yes. Under Target, select Select groups and add the administrators group (e.g., SG-Auth-FIDO2-Eligible). Under Configure, set Allow self-service set up to Yes. Under Key Restriction Policy, decide whether to restrict to specific FIDO2 key models (by AAGUID). For initial deployment, leave unrestricted unless your organization has standardized on a specific key vendor.

The equivalent in PowerShell:

# Enable FIDO2 for the administrators group
$fido2Policy = @{
    "@odata.type" = "#microsoft.graph.fido2AuthenticationMethodConfiguration"
    state = "enabled"
    includeTargets = @(
        @{
            targetType = "group"
            id = $adminGroup.Id
        }
    )
    isSelfServiceRegistrationAllowed = $true
    isAttestationEnforced = $false
    keyRestrictions = @{
        isEnforced = $false
        enforcementType = "allow"
        aaGuids = @()
    }
}

Invoke-MgGraphRequest -Method PATCH `
  -Uri "https://graph.microsoft.com/v1.0/policies/authenticationMethodsPolicy/authenticationMethodConfigurations/fido2" `
  -Body ($fido2Policy | ConvertTo-Json -Depth 5)

Write-Host "FIDO2 enabled for group: $($adminGroup.DisplayName)"

Verify the policy took effect:

$updated = Invoke-MgGraphRequest -Method GET `
  -Uri "https://graph.microsoft.com/v1.0/policies/authenticationMethodsPolicy/authenticationMethodConfigurations/fido2" `
  -OutputType PSObject

Write-Host "FIDO2 state: $($updated.state)"
Write-Host "Self-service registration: $($updated.isSelfServiceRegistrationAllowed)"
Write-Host "Targets: $(($updated.includeTargets | ForEach-Object { $_.id }) -join ', ')"

Include and exclude targets

Every method policy supports both include and exclude targets. Include targets define which groups can register the method. Exclude targets override the include: a user who belongs to both an included group and an excluded group cannot register the method.

The exclude mechanism is how you handle exceptions without restructuring your groups. If FIDO2 is enabled for all users but you need to block a specific group (service accounts that shouldn't have FIDO2 registered, for example), add that group as an exclude target rather than changing the include from "all users" to a complex list of included groups.

# Check include and exclude targets for all methods
$policy = Invoke-MgGraphRequest -Method GET `
  -Uri "https://graph.microsoft.com/v1.0/policies/authenticationMethodsPolicy" `
  -OutputType PSObject

foreach ($config in $policy.authenticationMethodConfigurations) {
    if ($config.state -eq "enabled") {
        $includes = ($config.includeTargets | ForEach-Object { $_.id }) -join ", "
        $excludes = if ($config.excludeTargets) {
            ($config.excludeTargets | ForEach-Object { $_.id }) -join ", "
        } else { "none" }
        Write-Host "$($config.id):"
        Write-Host "  Include: $includes"
        Write-Host "  Exclude: $excludes"
    }
}

A clean method policy state has explicit includes and no excludes. When excludes accumulate, they create invisible restrictions that are hard to audit: a user contacts the helpdesk because FIDO2 doesn't appear in their security info options, and the cause is a nested group membership that places them in an exclude target nobody remembers creating. Document every exclude target with the reason for the exclusion and a review date.

Disabling voice call authentication

Voice call is the weakest MFA method in the Entra ID catalog. The user receives a phone call, answers it, and presses the pound key to approve the authentication. There's no number matching, no context about what's being approved, and the call can be forwarded or intercepted. Most organizations enabled voice call as a fallback years ago and never revisited the decision.

Entra Admin Center

ProtectionAuthentication methodsPoliciesVoice call
Toggle Enable to No. Before disabling, verify no users rely on voice as their only MFA method. Unlike SMS restriction (where you narrow the target group), voice call should be disabled entirely, there is no legitimate use case where voice call provides better security than SMS, and its usability is worse (users must answer a phone call and wait for the prompt).

Disable voice call and verify:

$voicePolicy = @{
    "@odata.type" = "#microsoft.graph.voiceAuthenticationMethodConfiguration"
    state = "disabled"
}

Invoke-MgGraphRequest -Method PATCH `
  -Uri "https://graph.microsoft.com/v1.0/policies/authenticationMethodsPolicy/authenticationMethodConfigurations/voice" `
  -Body ($voicePolicy | ConvertTo-Json -Depth 3)

# Verify
$voiceCheck = Invoke-MgGraphRequest -Method GET `
  -Uri "https://graph.microsoft.com/v1.0/policies/authenticationMethodsPolicy/authenticationMethodConfigurations/voice" `
  -OutputType PSObject
Write-Host "Voice call: $($voiceCheck.state)"

Registration campaigns

Enabling a method makes it available. Registration campaigns make users actually register it. A registration campaign is a feature in Entra ID that prompts targeted users to register a specific authentication method during their next sign-in. The prompt appears as an interruption: the user must register before they can continue to their destination application.

Entra Admin Center

ProtectionAuthentication methodsRegistration campaign
Set State to Enabled. Set Days allowed to snooze (how many days the user can postpone registration — 1, 3, 7, or 14). Under Users and groups, add the target group and select the method to promote (e.g., Microsoft Authenticator). The campaign prompts users in the target group to register the specified method during their next interactive sign-in. Users can snooze the prompt for the specified number of days, after which it reappears.

Configure a registration campaign via Graph API:

$campaignConfig = @{
    registrationEnforcement = @{
        authenticationMethodsRegistrationCampaign = @{
            state = "enabled"
            snoozeDurationInDays = 3
            includeTargets = @(
                @{
                    id = $allUsersGroup.Id
                    targetType = "group"
                    targetedAuthenticationMethod = "microsoftAuthenticator"
                }
            )
            excludeTargets = @()
        }
    }
}

Invoke-MgGraphRequest -Method PATCH `
  -Uri "https://graph.microsoft.com/v1.0/policies/authenticationMethodsPolicy" `
  -Body ($campaignConfig | ConvertTo-Json -Depth 6)

Write-Host "Registration campaign enabled. Authenticator, snooze 3 days"

The campaign targets Microsoft Authenticator because it's the broadest-reach MFA method: every user with a smartphone can register it. Once Authenticator adoption reaches your target threshold (typically 90%+), you can launch a second campaign for FIDO2 keys targeting the administrators group, and a third for Windows Hello targeting managed device users.

The sequence matters: Authenticator first (broadest reach, lowest friction), FIDO2 second (hardware-dependent, targeted population), WHfB third (device-dependent, automatic enrollment via Intune). Each campaign builds on the previous one. Don't run multiple campaigns simultaneously, users who receive prompts for two different methods get confused and abandon both.

Monitor campaign progress weekly to track the adoption curve:

$report = Get-MgReportAuthenticationMethodUserRegistrationDetail -All

$authenticatorRegistered = ($report | Where-Object {
    $_.MethodsRegistered -contains "microsoftAuthenticatorPush" -or
    $_.MethodsRegistered -contains "microsoftAuthenticatorPasswordless"
}).Count

$total = $report.Count
$pct = [math]::Round($authenticatorRegistered / $total * 100, 1)

Write-Host "Authenticator registration: $authenticatorRegistered / $total ($pct%)"
if ($pct -lt 90) {
    Write-Host "  ⚠ Below 90% target, campaign should continue"
    $unregistered = $report | Where-Object {
        $_.MethodsRegistered -notcontains "microsoftAuthenticatorPush" -and
        $_.MethodsRegistered -notcontains "microsoftAuthenticatorPasswordless"
    }
    Write-Host "  Users without Authenticator: $($unregistered.Count)"
}

Track the adoption rate over multiple weeks. Healthy campaigns follow a predictable curve: rapid adoption in week 1 (the early adopters and compliant users), steady growth in weeks 2–3 (the "I'll do it when I'm reminded" population), and a plateau in week 4 (the holdouts who need escalation). If your curve plateaus below 80%, reduce the snooze duration. If it plateaus between 80% and 90%, identify the holdout users individually, they often share common characteristics (a specific office location, a department with older devices, or a population that doesn't sign in interactively).

The enforcement sequencing principle

Registration governance follows a five-step sequence. Skipping steps causes lockouts.

Step 1: Enable the method. Make the target method available in the method policy. Users can register but aren't required to.

Step 2: Run the registration campaign. Prompt users to register the target method during their next sign-in. Track adoption weekly.

Step 3: Verify coverage. Confirm that every user in the target population has the method registered. Identify and resolve gaps (SMS-only users, users without smartphones, users who haven't signed in during the campaign period).

Step 4: Restrict the old method. Narrow the targeting for the method being replaced (e.g., restrict SMS to the exceptions group). Don't disable entirely until coverage is verified.

Step 5: Enforce the new method via authentication strength. Create or update the Conditional Access policy to require the authentication strength that maps to the new method. This is the enforcement step, it happens last, not first.

Most organizations attempt step 5 first (enforce the requirement) without completing steps 2–4 (register the method and verify coverage). The result is predictable: lockouts, helpdesk queue, executive escalation, policy rollback, and a six-month delay before anyone tries again.

Anti-Pattern

An organization enables MFA enforcement through Conditional Access without running a registration campaign first. On Monday morning, 200 users hit the MFA registration prompt during sign-in. 180 choose SMS because it's the fastest registration option. 15 choose voice call. 5 install the Authenticator app. The helpdesk gets 40 calls from users who don't understand what's happening. The security team wanted Authenticator adoption. They got SMS adoption, by accident, because they didn't govern the registration sequence. The fix: run a registration campaign for Authenticator (with snooze set to 3 days) for 2-4 weeks before enabling the CA enforcement policy. When users hit the MFA requirement, they already have Authenticator registered.

Disabling weak methods

After Authenticator adoption reaches 90%+, the next governance step is disabling weaker methods for populations that no longer need them. This is the hardest organizational conversation because users resist losing a method they've used, even when they have a stronger alternative registered.

Entra Admin Center

ProtectionAuthentication methodsPoliciesSMS
Before disabling SMS for a group, verify every user in that group has an alternative method registered. Under Target, change from All users to Select groups and include only the groups that still need SMS (e.g., users without smartphones). This narrows SMS availability rather than removing it entirely: a graduated approach that reduces risk without a cliff edge.

Before disabling any method, verify coverage, confirm every affected user has an alternative:

# Find users who have ONLY SMS registered (no alternative)
$smsOnlyUsers = $report | Where-Object {
    $_.MethodsRegistered -contains "mobilePhone" -and
    $_.MethodsRegistered -notcontains "microsoftAuthenticatorPush" -and
    $_.MethodsRegistered -notcontains "microsoftAuthenticatorPasswordless" -and
    $_.MethodsRegistered -notcontains "fido2" -and
    $_.MethodsRegistered -notcontains "windowsHelloForBusiness"
}

Write-Host "Users with SMS as only MFA method: $($smsOnlyUsers.Count)"
if ($smsOnlyUsers.Count -gt 0) {
    Write-Host "  ⚠ Cannot disable SMS until these users register an alternative"
    $smsOnlyUsers | Select-Object UserDisplayName, UserPrincipalName | Format-Table
}

If the count is zero, you can safely narrow SMS targeting. If users remain SMS-only, those are your registration campaign targets, they need Authenticator (or another method) before SMS can be restricted.

Break down the SMS-only population by department to identify where the registration campaign needs to focus:

# SMS-only users by department, identifies which teams need targeted campaign effort
foreach ($user in $smsOnlyUsers) {
    $u = Get-MgUser -UserId $user.UserPrincipalName -Property Department
    $user | Add-Member -NotePropertyName Department -NotePropertyValue $u.Department -Force
}

$smsOnlyUsers | Group-Object Department | Sort-Object Count -Descending |
  ForEach-Object {
    Write-Host "  $($_.Name): $($_.Count) SMS-only users"
}

If one department dominates the SMS-only count, the registration campaign should target that department specifically: a department-focused registration push with their manager informed is more effective than a tenant-wide campaign that's already been running for weeks. The manager conversation is essential: "12 of your 30 team members haven't registered Authenticator. Here's what we need from them by [date]." Manager involvement converts a security initiative into an operational expectation.

The communication sequence for method restriction follows the same cadence as any change management: announcement (2 weeks before restriction), reminder (1 week before), final notice (2 days before), and restriction date. Each communication explains what's changing, why, what the user needs to do, and who to contact for help. Users who receive the restriction without prior communication will escalate, and the escalation target will be whoever approved the restriction without communicating it.

At Northgate Engineering: NE's registration strategy follows a three-phase approach. Phase 1 (weeks 1-4): Authenticator registration campaign for all 810 users with 3-day snooze. Target: 90% Authenticator adoption. Phase 2 (weeks 5-8): FIDO2 registration for the 22 administrators, bootstrapped with TAP (section 4.6). Target: 100% phishing-resistant for privileged accounts. Phase 3 (weeks 9-12): restrict SMS to the exceptions group (users without smartphones, estimated 15-20 users), disable voice call entirely. ADR-IAM4-002 documents the phased approach, the 90% threshold before method restriction, and the exceptions process for users who cannot use Authenticator.

Method resilience: the two-method minimum

Registration governance isn't just about moving users to stronger methods, it's about ensuring every user has at least two registered methods. A user with only one method is one lost phone, one dead battery, or one broken key away from being locked out.

# Find users with only one MFA method registered
$singleMethod = $report | Where-Object {
    $_.IsMfaRegistered -and $_.MethodsRegistered.Count -eq 1
}
Write-Host "Users with only one MFA method: $($singleMethod.Count)"
Write-Host "  These users have no fallback if their primary method is unavailable"

# Break down by method type
$singleMethod | Group-Object { $_.MethodsRegistered[0] } | Sort-Object Count -Descending |
  ForEach-Object { Write-Host "  $($_.Name): $($_.Count)" }

The single-method population is your resilience gap. Encourage these users to register a second method during the campaign: the registration prompt can include guidance: "You have Authenticator registered. For backup access, add a phone number or register a security key." The two-method minimum should be a governance target, tracked alongside the MFA coverage percentage. A tenant where 100% of users have MFA but 40% have only one method has a resilience problem that will surface as lockouts during the inevitable "I left my phone at home" morning.

Decision-point simulation

Scenario 1. Your Authenticator registration campaign has been running for 3 weeks. Adoption is at 78%. The remaining 22% haven't snoozed, they dismissed the prompt and haven't returned. Your security team wants to set snooze to 0 days (no dismissal) to force registration. What's the trade-off?

Zero-snooze forces registration at next sign-in: the user cannot proceed until they complete setup. This eliminates the "I'll do it later" population but creates helpdesk load from users who don't have their phone accessible at sign-in time (conference rooms, shared workstations, new devices). The trade-off is speed vs friction. A middle path: reduce snooze from 3 days to 1 day, which increases urgency without creating a hard block, then move to 0 days for the final 10% after reaching 90%.

Scenario 2. A compliance officer asks: "Can we prove to auditors that 100% of our users have MFA enabled?" You check and find that 100% of users have a CA policy requiring MFA. But 6% of users have only SMS registered. Is the compliance officer's question answered?

Technically yes: all users are required to use MFA, and all users have a method registered. But the auditor's question should trigger a deeper conversation about method strength. "100% MFA enabled" is different from "100% phishing-resistant MFA." If the audit framework specifies phishing resistance (NIST AAL2+, for example), SMS-only users don't meet the requirement even though they have MFA. Document the distinction: 100% MFA-enabled, 94% Authenticator or stronger, 6% SMS-only with a remediation timeline.

Scenario 3. During the Authenticator registration campaign, a user reports they can't register because they have an older phone that doesn't support the latest Authenticator version. What's your process?

First, verify the claim, check the Authenticator app's minimum OS requirements (iOS 16.0+, Android 10+). If the user's phone genuinely can't run Authenticator, they need an alternative: hardware OATH token (TOTP-based, works on any device), FIDO2 security key (no phone required), or software OATH token (third-party authenticator apps may have lower OS requirements). Add the user to the SMS exceptions group temporarily, document the exception with an expiry date (e.g., "SMS permitted until phone upgrade, review quarterly"), and track the exception in the risk register. The exception should have a named owner and a closure condition.

Reusable script. MFA registration audit

# IAM4.2. MFA Registration Audit
# Tracks registration coverage by method and identifies gaps

Connect-MgGraph -Scopes "UserAuthenticationMethod.Read.All"

$report = Get-MgReportAuthenticationMethodUserRegistrationDetail -All

# Method distribution
Write-Host "`n=== Method Registration Distribution ==="
$methodCounts = @{}
foreach ($u in $report) {
    foreach ($m in $u.MethodsRegistered) {
        if (-not $methodCounts[$m]) { $methodCounts[$m] = 0 }
        $methodCounts[$m]++
    }
}
$methodCounts.GetEnumerator() | Sort-Object Value -Descending |
  ForEach-Object { Write-Host "  $($_.Key): $($_.Value) ($([math]::Round($_.Value/$report.Count*100,1))%)" }

# Users without any MFA
$noMfa = $report | Where-Object { -not $_.IsMfaRegistered }
Write-Host "`n=== Users Without MFA ==="
Write-Host "  Count: $($noMfa.Count)"
$noMfa | Select-Object UserDisplayName, UserPrincipalName | Format-Table

# SMS-only users (upgrade targets)
$smsOnly = $report | Where-Object {
    $_.MethodsRegistered -contains "mobilePhone" -and
    $_.MethodsRegistered -notcontains "microsoftAuthenticatorPush" -and
    $_.MethodsRegistered -notcontains "fido2" -and
    $_.MethodsRegistered -notcontains "windowsHelloForBusiness"
}
Write-Host "`n=== SMS-Only Users (Upgrade Targets) ==="
Write-Host "  Count: $($smsOnly.Count)"