Reporting MFA-Enabled Accounts

What Accounts are Affected By The Problem?

When an issue like the November 19 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 Office 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. 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

Managing the MFA status of Office 365 Accounts – Just terrible!

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 MFA-enabled accounts. The output is a CSV file. If your account is affected by the outage, you’ll need to sign into Office 365 with a breakglass account that can run PowerShell.

$Report = @()
$i = 0
$Accounts = (Get-MsolUser -All | ? {$_.StrongAuthenticationMethods -ne $Null} | Sort DisplayName)
ForEach ($Account in $Accounts) {
   Write-Host "Processing" $Account.DisplayName
   $Methods = $Account | Select -ExpandProperty StrongAuthenticationMethods
   $MFA = $Account | Select -ExpandProperty StrongAuthenticationUserDetails
   $State = $Account | Select -ExpandProperty StrongAuthenticationRequirements
   $Methods | ForEach { If ($_.IsDefault -eq $True) {$Method = $_.MethodType}}
   If ($State.State -ne $Null) {$MFAStatus = $State.State}
      Else {$MFAStatus = "Disabled"}
   $ReportLine = [PSCustomObject]@{
       User      = $Account.DisplayName
       UPN       = $Account.UserPrincipalName
       MFAMethod = $Method
       MFAPhone  = $MFA.PhoneNumber
       MFAEmail  = $MFA.Email
       MFAStatus = $MFAStatus  }
   $Report += $ReportLine      }
Write-Host $i "accounts are MFA-enabled"

$Report | Export-CSV -NoTypeInformation c:\temp\MFAUsers.CSV

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 -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.

7 Replies to “Reporting MFA-Enabled Accounts”

  1. 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.

    1. Just add the following condition to this statement to narrow down the search down to your domain.

      -and $_.userprincipalname -match “”

      $Accounts = (Get-MsolUser -All | ? {$_.StrongAuthenticationMethods -ne $Null -and $_.userprincipalname -match “”} | Sort DisplayName)

  2. Hi, I tried the main report script but it only cam eback with my own account (should have over 80K users). Any ideas?

    1. Are you signed into PowerShell with an account that has administrative permissions for the tenant?

Leave a Reply

This site uses Akismet to reduce spam. Learn how your comment data is processed.