Table of Contents
Knowing Which Accounts Are MFA-Enabled and Those That Don’t
When an issue like the November 19 2018 Azure outage occurs, the first thing that an administrator needs to know is what users are affected. In this case, the problem was that users whose accounts were enabled for multi-factor authentication (MFA) couldn’t complete the sign-in process and therefore weren’t able to access Exchange, SharePoint, and other Office 365 apps.
You can, of course go to the Microsoft 365 Admin Center and manage the MFA status of accounts there (Go to Active Users, click the More drop-down, and select Multifactor Authentication setup). However, the GUI is awful (Figure 1). It’s not part of Office 365 (it comes from Azure), hasn’t been updated in years, is slow, and is painful to navigate when you have a large tenant with many accounts.

Because the GUI is so terrible and slow, I usually turn to PowerShell to manage MFA for Office 365 accounts. The cmdlets you need are in the MSOnline module.
PowerShell Report
To start, let’s find out what accounts are MFA-enabled. Here’s a script to find and report the MFA status of all user accounts. The output is a CSV file. In a situation where an MFA outage is happening and you can’t access your normal administrative account, you’ll need to sign into Office 365 with a breakglass account.
CLS Write-Host "Finding Azure Active Directory Accounts..." $Users = Get-MsolUser -All | ? {$_.IsLicensed -eq $True} $Report = [System.Collections.Generic.List[Object]]::new() # Create output file Write-Host "Processing" $Users.Count "accounts..." ForEach ($User in $Users) { $MFAMethods = $User.StrongAuthenticationMethods.MethodType $MFAEnforced = $User.StrongAuthenticationRequirements.State $DefaultMFAMethod = ($User.StrongAuthenticationMethods | ? {$_.IsDefault -eq "True"}).MethodType If (($MFAEnforced -eq "Enforced") -or ($MFAEnforced -eq "Enabled")) { Switch ($DefaultMFAMethod) { "OneWaySMS" { $MethodUsed = "One-way SMS" } "TwoWayVoiceMobile" { $MethodUsed = "Phone call verification" } "PhoneAppOTP" { $MethodUsed = "Hardware token or authenticator app" } "PhoneAppNotification" { $MethodUsed = "Authenticator app" } } #End Switch } Else { $MFAEnforced= "Not Enabled" $MethodUsed = "MFA Not Used" } $ReportLine = [PSCustomObject] @{ User = $User.UserPrincipalName Name = $User.DisplayName MFAUsed = $MFAEnforced MFAMethod = $MethodUsed } $Report.Add($ReportLine) } # End For Write-Host "Report is in c:\temp\MFAUsers.CSV" $Report | Select Name, MFAUsed, MFAMethod | Out-GridView $Report | Export-CSV -NoTypeInformation c:\temp\MFAUsers.CSV
Figure 2 shows the contents of the report as viewed through the Out-GridView cmdlet.

Update: The script described in this post uses the Microsoft Services Online module (MSOL). Microsoft will deprecate the module at the end of 2022. You should upgrade scripts to use Graph API queries or cmdlets from the Microsoft Graph PowerShell SDK. See this post for information about how to extract and report details of authentication methods used by Azure AD accounts.
Azure Active Directory Sign-in Log
Because the refresh token of MFA-enabled accounts don’t necessarily expire during an outage, a more nuanced approach is to check the Azure Active Directory sign-in logs for events with error codes 50076, 50074, or 50058, all of which flag problems signing in with an MFA-enabled account. You can review sign-ins interactively or download events to a CSV file. You can then use Excel to look through the failed sign-ins or import the CSV file into Power BI to analyze it there. In either case, you’ll end up with a set of accounts who are experiencing problems signing into Office 365.
Disabling MFA for Accounts
When a cloud outage happens, there’s no guarantee when normal service will resume. As everyone discovered on November 18, the process to figure out the root cause of a problem, come up with a fix, test it, and then deploy into production across a massive multi-tenant infrastructure can take many hours. While this process was in going on, the only workaround administrators had was to disable MFA for user accounts. This is easily done for a specific user:
$MFAOptions = @() Set-MsolUser -UserPrincipalName Kim.Akers@Office365itpros.com -StrongAuthenticationRequirements $MFAOptions
To disable a batch of users, simply form a collection and call the Set-MsolUser cmdlet for each account. In this case, we disable MFA for all members of the Marketing department. If you extract failed sign-in data from Azure Active Directory, you can create a CSV file holding the set of accounts to process and use it as the input.
$MFAOptions = @() $Accounts = Get-MsolUser -Department Marketing | ? {$_.StrongAuthenticationMethods -ne $Null} ForEach ($A in $Accounts) { Set-MsolUser -UserPrincipalName $A.UserPrincipalName -StrongAuthenticationRequirements $MFAOptions}
Enabling MFA for Accounts
Later on when the outage is over, we need to re-enable MFA for the same set of accounts (we’ll assume that you have saved details of the accounts and populated those names in the $Accounts variable). The PowerShell snippet shown below sets up MFA based on one-way SMS (text) messages containing 6-digit codes.
$MFA = New-Object –TypeName Microsoft.Online.Administration.StrongAuthenticationRequirement $MFA.RelyingParty = "*" $MFA.State = "Enabled" $MFAOptions = @($MFA) $MFAMethod = New-Object –TypeName Microsoft.Online.Administration.StrongAuthenticationMethod $MFAMethod.IsDefault = $True $MFAMethod.MethodType = "OneWaySMS" $MFAMethods = @($MFAMethod) ForEach ($A in $Accounts) { Set-MsolUser –UserPrincipalName $A.UserPrincipalName –StrongAuthenticationRequirements $MFAOptions –StrongAuthenticationMethods $MFAMethods }
These examples aren’t a complete solution. Instead, they’re intended to give administrators a start to figure out how to manage MFA settings with PowerShell.
For more details about Office 365 MFA, see the online documentation.
We cover multi-factor authentication for Office 365 in Chapter 3 of the Office 365 for IT Pros eBook.
is there a way to get the MFA status for a particular domain using Powershell?
We have multiple domains, and I would like to know in what domain the MFA is enabled.
Just add the following condition to this statement to narrow down the search down to your domain.
-and $_.userprincipalname -match “@yourdomain.com”
$Accounts = (Get-MsolUser -All | ? {$_.StrongAuthenticationMethods -ne $Null -and $_.userprincipalname -match “@yourdomain.com”} | Sort DisplayName)
Hi, I tried the main report script but it only cam eback with my own account (should have over 80K users). Any ideas?
Are you signed into PowerShell with an account that has administrative permissions for the tenant?
Great script many thanks!
The best script I found so far, for exporting MFA information. Thank you!
Hi, is this script going to work if MFA conditional access is enabled?
I haven’t tried. The script depends on the information written into the Azure AD accounts, so I imagine that it would – but it’s good to check and easy to test.
I might try and report back. What privileges do you need to run this script successfully?
Tenant administrator or user account administrator, I believe.
In my organization, I have delegated the “Authentication Administrator” role to our helpdesk, and I created some PowerShell scripts to enable/disable MFA, and to reset MFA contact methods. The helpdesk uses these tools effectively. We have another issue which I haven’t been able to resolve. Occasionally, someone in our organization gets their MFA blocked. Right now, a Global Administrator must use the GUI to review and unblock these users. It would be nice to delegate this. I can’t find an Azure cmdlet to report on or block/unblock users, and I don’t know if we can even delegate permissions to do so. Any idea if this is possible?