Report per-user MFA status in Entra using Microsoft Graph PowerShell

The Microsoft Graph API is slowly achieving feature parity with its predecessor, the Azure Graph API. One of the settings that was previously unavailable, before June 2024, was the ability to view the per-user MFA status of users in your environment, to support migration efforts to more secure tools such as Conditional Access. 

In this article, I will show you how to use Microsoft Graph PowerShell to report the per-user MFA status of all users in your tenant.

What is the per-user MFA state in Microsoft Entra?

In Microsoft Entra, there are still some legacy MFA settings kicking around in a configuration known as per-user MFA. Per-user MFA allows you to configure and enforce MFA per user in the legacy admin portal as well as define some available MFA methods. 

You won’t get the best experience using this setting, the user’s authentication experience won’t always be seamless and you won’t be able to enforce stronger authentication methods at a granular level. For a long time now, it has been recommended to migrate to Conditional Access as soon as possible.

If you need to, you can still access these settings from the Entra admin portal by following the below steps:

  1. Log in to https://entra.microsoft.com/
  2. Select Users > All users.
  3. Select per-user MFA.

Requirements to view the per-user MFA state with PowerShell

As of June 2024, the per-user MFA settings are only available through the Beta Microsoft Graph endpoint. As such, to use PowerShell to obtain this information the following modules are necessary:

  • Microsoft.Graph.Authentication
  • Microsoft.Graph.Beta.Users (optional and not used in the below example)
Per-user MFA state
Per-user MFA state

You will also require access to a Global Administrator account to consent to the User.Read.All permission in Microsoft Graph.

How to view the per-user MFA state for all users with PowerShell

The short script below can be used to obtain a list of all users in your environment and whether they have per-user MFA enabled on their accounts. Unfortunately, filtering is not yet supported with these user properties so each user must be looped through one by one and added to a collection. 

#Connet to Microsoft Graph
Connect-MgGraph -Scope Policy.ReadWrite.AuthenticationMethod

#Get all users and select only required properties
$allUsers = Get-MgUser -all -select Id, UserPrincipalName

#initialise array
$allUsersPerUserMFAState = [System.Collections.Generic.List[Object]]::new()

#Loop through each user and add results to array
Foreach ($user in $allusers){
    $pumfa = Invoke-MgGraphRequest -Method GET -Uri "/beta/users/$($user.id)/authentication/requirements" -OutputType PSObject
    $obj = [PSCustomObject][ordered]@{
        "User" = $user.UserPrincipalName
        "Per-user MFA State" = $pumfa.PerUserMfaState
    }
    $allUsersPerUserMFAState.Add($obj)
}

#output in grid view
$allUsersPerUserMFAState | Out-GridView

The script will display the per-user MFA report in a pop-out window, although you can alter the code as required to customise the output.

Per user MFA report output
Per user MFA report output

Daniel Bradley

My name is Daniel Bradley and I work with Microsoft 365 and Azure as an Engineer and Consultant. I enjoy writing technical content for you and engaging with the community. All opinions are my own.

Leave a Reply