Entra / Microsoft 365 · Users & guests
Get users with phone MFA method
Find user accounts with a phone-based MFA method so administrators can email them to register a stronger authentication method.
Connect & set up
Run these once per session. All scopes are read-only unless the script makes changes.
Connect-MgGraph -NoWelcome -AppId $AppId -TenantId $TenantId -CertificateThumbprint $Thumbprint
Run it
The main script. Copy it, or download the .ps1 and run it from your console.
param([string] $TenantId = "",[string] $AppId = "")$Thumbprint = '32C9529B1FFD08BCD483A5D98807E47A472C5318'Connect-MgGraph -NoWelcome -AppId $AppId -TenantId $TenantId -CertificateThumbprint $Thumbprint# Find licensed user accounts[array]$Users = Get-MgUser -Filter "assignedLicenses/`$count ne 0 and userType eq 'Member'" `-ConsistencyLevel eventual -CountVariable UsersFound -Sort "displayName" `-Property Id, DisplayName, GivenName , UserPrincipalName, UserType, MailIf (!$Users) {Write-Host "No user accounts found"Exit}Write-Output ("Checking MFA methods for {0} user accounts" -f $UsersFound)$Report = [System.Collections.Generic.List[Object]]::new()ForEach ($User in $Users) {Write-Host ("Checking MFA methods for {0}" -f $User.UserPrincipalName)$Method = $null; $SystemPreferred = $false$Methods = Get-MgBetaUserAuthenticationSignInPreference -UserId $User.IdIf ($Methods.IsSystemPreferredAuthenticationMethodEnabled) {Write-Host ("User {0} has system preferred method enabled" -f $User.UserPrincipalName)$SystemPreferred = $true}# Figure out what secondary method the account usesSwitch ($Methods.UserPreferredMethodForSecondaryAuthentication) {'push' {Write-Host ("User {0} uses the Authenticator app for their MFA method" -f $User.UserPrincipalName)$Method = "App"}'oauth' {Write-Host ("User {0} uses OAuth Token MFA method" -f $User.UserPrincipalName)$Method = "Oauth Token"}'voiceMobile' {Write-Host ("User {0} uses Voice to Mobile for their MFA method" -f $User.UserPrincipalName)$Method = "Voice Mobile"}'voiceAlternateMobile' {Write-Host ("User {0} uses Voice to Alternate Mobile their MFA method" -f $User.UserPrincipalName)$Method = "Voice Mobile Alternate"}'voiceOffice' {Write-Host ("User {0} uses Voice to Office Phone for their MFA method" -f $User.UserPrincipalName)$Method = "Voice Office"}'sms' {Write-Host ("User {0} uses a phone for their MFA method" -f $User.UserPrincipalName)$Method = "SMS"}}If ($null -eq $Methods.UserPreferredMethodForSecondaryAuthentication) {Write-Host ("User {0} has no MFA method" -f $User.UserPrincipalName)$Method = "None"}$DataLine = [PSCustomObject][Ordered]@{UserPrincipalName = $User.UserPrincipalNameDisplayName = $User.DisplayNameGivenName = $User.GivenNameMethod = $MethodMail = $User.Mail'System Preferred' = $SystemPreferred}$Report.Add($DataLine)}# Define domains and specific users that we don't want to send nagging emails to[array]$UserNoNag = 'Azure.Management.Account@office365itpros.com'[array]$DomainsNoNag = 'office365itpros.org','contoso.com'# Find people using SMS as the authentication method that aren't in the excluded list of accounts or domains[array]$UsersToNag = $Report | Where-Object {($_.Method -eq 'SMS') -and ($_.UserPrincipalName -notin $UserNoNag) -and `($_.UserPrincipalName.Split('@')[1] -notin $DomainsNoNag)}# Do the same for users who have no MFA method[array]$UsersNoMFA = $Report | Where-Object {($_.Method -eq 'None') -and ($_.UserPrincipalName -notin $UserNoNag) -and `($_.UserPrincipalName.Split('@')[1] -notin $DomainsNoNag)}Write-Host ("{0} users selected for nagging because they use the SMS MFA method" -f $UsersToNag.Count)Write-Host ("{0} users selected for nagging because their account has no MFA method" -f $UsersNoMFA.Count)# Send Email to the users with SMS MFA method - first define the message sender, which can be the SMTP address for a user or shared mailbox$MsgFrom = 'Customer.Services@office365itpros.com'# Define some variables used to construct the HTML content in the message body#HTML header with styles$HtmlHead="<html><style>BODY{font-family: Arial; font-size: 10pt;}H1{font-size: 22px;}H2{font-size: 18px; padding-top: 10px;}H3{font-size: 16px; padding-top: 8px;}H4{font-size: 8px; padding-top: 4px;}</style>"$MsgSubject = "Important: Please upgrade your MFA method"ForEach ($User in $UsersToNag) {Write-Host ("Sending email to {0} to ask them to change their MFA method" -f $User.UserPrincipalName)$ToRecipients = @{}$ToRecipients.Add("emailAddress",@{'address'=$User.Mail})[array]$MsgTo = $ToRecipients# Customize the message$HtmlHeaderUser = "<h2>"+ $User.DisplayName + ": It's time to say goodbye to SMS authentications</h2>"#Content for the message - obviously, this is very customizable and should reflect what you want to say to new users$HtmlBody = "<body><h1>SMS responses to Multifactor Challenges are no longer secure enough!</h1><h2><u>We need you to increase the strength of your multifactor authentication</u></h2><p><b>Dear $($User.GivenName),</b></p><p>Our records show that you use SMS to respond to multifactor authentication challenges. In other words, you receive a code via SMS and enter that number when prompted by Entra ID.</p><p>SMS was a great method some years ago, but now it's prone to compromise. We need you to upgrade to a more secure authentication method, such as the Microsoft Authenticator app, which is free and easy to use.</p><p>To learn more about the Authenticator app, please <a href=https://support.microsoft.com/en-us/account-billing/about-microsoft-authenticator-9783c865-0308-42fb-a519-8cf666fe0acc>click here</a> </p><p>Have a great time and be sure to call the help desk if you need assistance. And please read all the great articles about Microsoft 365 published on <a href=https://Practical365.com>Practical365.com</a>.</p><p><p><p><h4>Generated:</strong> $(Get-Date -Format g)</h4></p>"$HtmlMsg = "</body></html>" + $HtmlHead + $Htmlheaderuser + $HtmlBody + "<p>"# Construct the message body$MsgBody = @{}$MsgBody.Add('Content', "$($HtmlMsg)")$MsgBody.Add('ContentType','html')$Message = @{}$Message.Add('subject', $MsgSubject)$Message.Add('toRecipients', $MsgTo)$Message.Add('body', $MsgBody)$Params = @{}$Params.Add('message', $Message)$Params.Add('saveToSentItems', $true)$Params.Add('isDeliveryReceiptRequested', $true)Send-MgUserMail -UserId $MsgFrom -BodyParameter $Params}Write-Host ""Write-Host ("All done - nagging emails sent to {0} users" -f $UsersToNag.Count)$UsersToNag | Format-Table DisplayName, Mail -AutoSize
Parameters
ParameterDefaultNotes
-TenantId""Microsoft Entra tenant ID for app-only Graph authentication.-AppId""Application (client) ID for the app registration used to connect.Attribution
Author
Office365itpros