Lab Metadata
Core technologies
Scenario and Description
Your Lab 01 baseline gave Northgate's programme board an uncomfortable number: a meaningful share of staff complete MFA over SMS text messages, and some administrators have no strong method registered at all. SMS is the weakest widely deployed second factor. It is exposed to SIM-swap fraud, SS7 interception and simple social engineering of mobile carriers. Regulators and the National Cyber Security Centre have moved firmly toward app-based and phishing-resistant factors.
Since 30 September 2025, Microsoft retired the ability to manage authentication methods in the legacy per-user MFA and legacy SSPR blades. There is now one place that governs which factors exist and who can use them: the Authentication Methods policy. This is a good thing. It is a single, targetable, Graph-manageable control plane, and it is where the whole of this lab lives.
You will enable Microsoft Authenticator for the estate, switch on the Authenticator registration campaign so that SMS users are prompted to adopt the app at sign-in, scope the SMS method down to a controlled exception group rather than the whole tenant, then disable SMS once the exception group is empty. This is the exact "migration away from SMS-based authentication to Microsoft Authenticator" work named in the specialist brief, done safely and reversibly.
Prerequisites
Prior labs
Lab 01 is required. You need the seeded Northgate personas (asmith, jpatel, lokafor) and the baseline script, which you re-run at the end to measure the change. The tenant and P1/P2 licence set up in Lab 01 carry forward.
New Graph scope introduced
| Scope | Why it is needed |
|---|---|
Policy.ReadWrite.AuthenticationMethod | Read and change the Authentication Methods policy, including method state, targets and the registration campaign |
Group.ReadWrite.All | Create the SMS exception group used to scope the method down during migration |
User.Read.All, GroupMember.ReadWrite.All | Read users and manage exception group membership |
state (enabled or disabled) and includeTargets (which users or groups it applies to). You manage them individually.
Verify you are still connected and licensed
# From Lab 01 you already have PowerShell 7 and the Graph SDK. Get-MgContext | Select-Object Account,TenantId # Confirm the tenant has premium licensing (needed by later labs and the campaign): (Get-MgSubscribedSku).ServicePlans | Where-Object { $_.ServicePlanName -match 'AAD_PREMIUM' } | Select-Object ServicePlanName,ProvisioningStatus -Unique
Real-World Problem Statement
You cannot retire SMS with a single switch without risking lockouts for users who have no other factor. A safe migration reduces reliance gradually, gives users a prompted path to a stronger method, keeps a controlled exception for genuine edge cases, and measures progress the whole way.
| Dimension | Why this migration matters |
|---|---|
| Risk | SMS is defeated by SIM swap and interception. Moving to Authenticator with number matching removes an entire class of account-takeover attacks. |
| Compliance | App-based and phishing-resistant MFA aligns with NCSC guidance and the direction of financial-sector supervisory expectations. |
| Productivity | The registration campaign moves users to the app without a manual helpdesk drive, and the app is faster to use than waiting for a text. |
| Security posture | Your Lab 01 SMS-reliant count becomes a metric that falls to zero, evidence the programme is working. |
Concrete scenario: Northgate has 900 staff still registered for SMS, of whom around 200 have no app method. A hard cut-off would lock those 200 out on Monday morning. Your job is to move them across without a single preventable lockout, then close SMS behind them.
Skills Mapped to Production Solutions
| Skill learned in this lab | Real-world enterprise application |
|---|---|
| Reading and editing the Authentication Methods policy via Graph | Central, auditable control of which factors exist across the estate |
| Enabling Microsoft Authenticator with app and location context | Reducing MFA fatigue attacks by showing users what they are approving |
| Running an Authenticator registration campaign | Estate-wide method migration without a manual helpdesk programme |
| Scoping a method to a group, then disabling it | Phased retirement of weak factors with a controlled exception path |
| Re-baselining to prove impact | Before-and-after metrics for the programme board and auditors |
Architecture Overview
Everything in this lab sits inside one object: the tenant's Authentication Methods policy. You edit three parts of it, the Microsoft Authenticator configuration, the SMS configuration, and the registration enforcement campaign, and you use one supporting group to hold the shrinking SMS exception list.
Data flow
- You enable Microsoft Authenticator for all users, so a stronger factor is available to everyone.
- The registration campaign intercepts SMS-only users at sign-in and prompts them to add the app.
- As users register the app, you remove them from the SMS-Legacy-Allowed group.
- When the group is empty, you set the SMS configuration state to disabled, retiring the weak factor.
Step-by-Step Implementation
Phase A - Audit the current policy
1Connect and read the existing method states
Purpose: know your starting point before you change anything.
Connect and list which methods are enabled
Connect-MgGraph -Scopes 'Policy.ReadWrite.AuthenticationMethod', 'Group.ReadWrite.All','GroupMember.ReadWrite.All','User.Read.All' -NoWelcome # List every method configuration and its current state. Get-MgPolicyAuthenticationMethodPolicyAuthenticationMethodConfiguration | Select-Object Id, State | Sort-Object Id | Format-Table -AutoSize # Expected IDs include: MicrosoftAuthenticator, Sms, Fido2, Email, # TemporaryAccessPass, SoftwareOath, Voice, X509Certificate.
enabled or disabled. Note the current state of MicrosoftAuthenticator and Sms so you can confirm your changes later.
What just happened? You read the tenant's single source of truth for authentication factors. In many real tenants Authenticator is already enabled but scoped to a subset, and SMS is enabled for everyone, which is precisely the shape you are here to reverse.
Phase B - Enable Microsoft Authenticator for the estate
2Turn on Authenticator with app and location context
Purpose: make a strong factor available to everyone before you remove the weak one.
Context: number matching is enforced by Microsoft for all Authenticator push sign-ins and is not a toggle you set. What you do add here is application name and geographic location context, which show the user what they are approving and cut MFA-fatigue approvals.
Enable Authenticator, target all users, add context
$authenticatorBody = @{
'@odata.type' = '#microsoft.graph.microsoftAuthenticatorAuthenticationMethodConfiguration'
state = 'enabled'
includeTargets = @(
@{
targetType = 'group'
id = 'all_users' # special built-in target meaning the whole tenant
authenticationMode = 'any' # push or passwordless
}
)
featureSettings = @{
displayAppInformationRequiredState = @{
state = 'enabled'
includeTarget = @{ targetType = 'group'; id = 'all_users' }
}
displayLocationInformationRequiredState = @{
state = 'enabled'
includeTarget = @{ targetType = 'group'; id = 'all_users' }
}
}
}
Update-MgPolicyAuthenticationMethodPolicyAuthenticationMethodConfiguration `
-AuthenticationMethodConfigurationId 'MicrosoftAuthenticator' `
-BodyParameter $authenticatorBody
(Get-MgPolicyAuthenticationMethodPolicyAuthenticationMethodConfiguration `
-AuthenticationMethodConfigurationId 'MicrosoftAuthenticator').State
# Expected: enabled
What just happened? Every user can now register and use the Authenticator app, and when they approve a sign-in they will see the requesting application and the sign-in location. That context is a direct, low-cost defence against push-fatigue attacks where a user blindly taps approve.
Phase C - Nudge SMS users onto the app
3Enable the Authenticator registration campaign
Purpose: prompt users who sign in with SMS to install and register Authenticator, without a manual helpdesk drive.
Context: the campaign lives in the policy's registrationEnforcement section. A snoozeDurationInDays of 0 means the prompt appears at every eligible sign-in until the user registers.
Configure the registration campaign for all users
$campaignBody = @{
registrationEnforcement = @{
authenticationMethodsRegistrationCampaign = @{
state = 'enabled'
snoozeDurationInDays = 0
includeTargets = @(
@{
id = 'all_users'
targetType = 'group'
targetedAuthenticationMethod = 'microsoftAuthenticator'
}
)
}
}
}
Update-MgPolicyAuthenticationMethodPolicy -BodyParameter $campaignBody
(Get-MgPolicyAuthenticationMethodPolicy).RegistrationEnforcement.AuthenticationMethodsRegistrationCampaign.State
# Expected: enabled
What just happened? Entra will now interrupt SMS-only users at sign-in with a guided flow to set up the app. This is the engine of the migration, it moves the population for you rather than relying on emails nobody reads.
Phase D - Scope SMS down, then retire it
4Create the SMS exception group and re-target SMS
Purpose: stop SMS applying to everyone. Instead it applies only to a named group you can drain to zero.
Create the group and point the SMS method at it
# 1. Create a security group to hold the shrinking SMS exception list. $grp = New-MgGroup -DisplayName 'SMS-Legacy-Allowed' ` -MailEnabled:$false -MailNickname 'sms-legacy-allowed' ` -SecurityEnabled:$true # 2. Seed it with users who still genuinely need SMS (here: asmith as an example). $domain = (Get-MgOrganization).VerifiedDomains | Where-Object IsDefault | Select-Object -ExpandProperty Name $asmith = Get-MgUser -Filter "userPrincipalName eq 'asmith@$domain'" New-MgGroupMember -GroupId $grp.Id -DirectoryObjectId $asmith.Id # 3. Re-target the SMS method from everyone to just this group. $smsBody = @{ '@odata.type' = '#microsoft.graph.smsAuthenticationMethodConfiguration' state = 'enabled' includeTargets = @( @{ targetType = 'group'; id = $grp.Id; isUsableForSignIn = $true } ) } Update-MgPolicyAuthenticationMethodPolicyAuthenticationMethodConfiguration ` -AuthenticationMethodConfigurationId 'Sms' -BodyParameter $smsBody
(Get-MgPolicyAuthenticationMethodPolicyAuthenticationMethodConfiguration `
-AuthenticationMethodConfigurationId 'Sms').AdditionalProperties.includeTargets
# Expected: a single group target whose id matches $grp.Id, not all_users.
What just happened? SMS is no longer available to the whole tenant. Only members of SMS-Legacy-Allowed can use it. As users adopt the app you remove them from this group, and their SMS option disappears cleanly.
5Drain the group and disable SMS
Purpose: complete the retirement once the exception group is empty.
Remove a migrated user, then disable SMS when the group is empty
# As each user registers the app, remove them from the exception group. Remove-MgGroupMemberByRef -GroupId $grp.Id -DirectoryObjectId $asmith.Id # Check remaining members. $remaining = Get-MgGroupMember -GroupId $grp.Id -All "SMS exception members remaining: $($remaining.Count)" # When the count is zero, disable SMS entirely. if ($remaining.Count -eq 0) { Update-MgPolicyAuthenticationMethodPolicyAuthenticationMethodConfiguration ` -AuthenticationMethodConfigurationId 'Sms' ` -BodyParameter @{ '@odata.type'='#microsoft.graph.smsAuthenticationMethodConfiguration'; state='disabled' } Write-Host 'SMS method disabled.' -ForegroundColor Green }
What just happened? SMS is retired for the tenant only after every dependent user has a stronger factor. This ordered drain is the difference between a clean migration and a Monday-morning flood of lockout tickets.
Testing and Validation
- Sign in as
asmithin a private browser window atoffice.com. You should be prompted by the registration campaign to set up Microsoft Authenticator. - Complete the setup, approving a test prompt. Confirm the prompt shows the application name and location context you enabled in Phase B.
- Re-run the Lab 01 baseline script. The
SMS-reliantcount should fall and asmith should now reportIsMfaCapable = truewithmicrosoftAuthenticatorPushamong the registered methods.
| Symptom | Cause | Resolution |
|---|---|---|
| Campaign never prompts | User already registered a strong method, or campaign targets exclude them | Test with a fresh user, confirm campaign state = enabled and target is all_users |
Update-Mg... returns 400 on SMS | Missing or wrong @odata.type in the body | Include the exact type #microsoft.graph.smsAuthenticationMethodConfiguration |
| all_users target rejected | Typo, the literal string is required | Use id = 'all_users' with targetType = 'group' |
| User locked out after SMS disable | User had no app method registered | Re-enable SMS for that user's group, register the app, then disable again |
Security Analysis
What makes this sound
- Availability before removal: the strong factor is enabled and adopted before the weak one is withdrawn, so no user is left without a method.
- Controlled exception: SMS survives only for a named, auditable group that trends to empty, not for the whole tenant indefinitely.
- Fatigue resistance: app and location context, on top of Microsoft-enforced number matching, defends against blind-approval attacks.
Intentionally simplified for the lab
- The migration timeline is compressed. Production runs the campaign for one to two weeks and watches the registration report before narrowing SMS.
- The exception group is drained manually. At scale you would drive membership dynamically or from a leavers and adoption report.
Production hardening
- Layer this with Conditional Access (Lab 03) so that even where a factor exists, MFA is actually required at sign-in.
- For high-value administrative accounts, move beyond the app to phishing-resistant FIDO2 keys (Lab 04). App push is strong, keys are stronger.
- Alert on any future re-enable of SMS at tenant scope as a change-management tripwire.
Cleanup Instructions
Revert SMS to enabled, disable the campaign, remove the group
# Re-enable SMS for all users (undo the scoping). Update-MgPolicyAuthenticationMethodPolicyAuthenticationMethodConfiguration ` -AuthenticationMethodConfigurationId 'Sms' ` -BodyParameter @{ '@odata.type'='#microsoft.graph.smsAuthenticationMethodConfiguration'; state='enabled'; includeTargets=@(@{ targetType='group'; id='all_users'; isUsableForSignIn=$true }) } # Disable the registration campaign. Update-MgPolicyAuthenticationMethodPolicy -BodyParameter @{ registrationEnforcement=@{ authenticationMethodsRegistrationCampaign=@{ state='disabled' } } } # Remove the exception group. $g = Get-MgGroup -Filter "displayName eq 'SMS-Legacy-Allowed'" if ($g) { Remove-MgGroup -GroupId $g.Id } Disconnect-MgGraph
Recommended Learning Links
Key Takeaways and Next Lab
- The Authentication Methods policy is now the single control plane for factors, the legacy per-user MFA and SSPR method management were retired in September 2025.
- Enable the strong factor and adopt it before removing the weak one. Order is the safety.
- A registration campaign migrates the population for you, a scoped exception group lets you retire SMS without lockouts.
- Re-baselining turns the migration into a measurable, board-ready number.
Identity Bytes // IB-ENTRA-SEC Track // Lab 02 of 12. British English. For lab and training use against a disposable tenant only.