Table of Contents
Per-User MFA State Available for User Accounts Through the Graph
On June 10, 2024, the Microsoft Graph changelog included some interesting additions to the beta version of the authentication resource type to make the settings for per-user MFA retrievable for user accounts. Until now, it’s been possible to see this information through the Entra admin center but not to fetch it programmatically.
The addition of the per-user MFA state is interesting because Microsoft is doing its level best to eliminate per-user MFA from Entra ID. Today, Office 365 E3 and above licenses include the ability to use per-user MFA when connecting to Office 365 services. Per-user Entra ID MFA covers all connections processed by the Microsoft identity service.
Microsoft’s long-term plan for enforcement of multifactor authentication is to use conditional access policies. They’ve put enormous effort over the past few years to build out the capabilities of these policies. The latest update was the ability to block connections using the device code authentication flow, something that all tenants should consider unless a solid business need exists to support device code authentication.
Moving Away from Per-User MFA
To make the transition easier for tenants, some Microsoft-managed conditional access policies are available to organizations with Entra ID P1 or P2 licenses, including one to assist the migration of per-user MFA. A potential issue for those with Office 365 MFA is that moving to conditional access policies requires Entra ID P1 licenses. This isn’t a problem if the organization has purchased Entra ID P1 for other reasons, like self-service password reset, but it is a hurdle to overcome for others. Security defaults is another option for tenants who don’t want to use conditional access policies, especially in the small to medium-sized sectors.
Knowing who still uses per-user MFA is invaluable information for anyone planning to migrate. It’s possible to get details about per-user MFA through the Users section of the Entra admin center, but the user interface is antiquated and unwieldy and the list includes both member and guest accounts (Figure 1).
Being able to extract the information via the Graph allows us to do something like this to find licensed member accounts, check each account for its per-user MFA state, and report the findings. The new capability is in beta for now with no indication of when the V1.0 (production) will support it. Reading the per-user MFA state requires consent to use the Policy.ReadWrite.AuthenticationMethod application permission.
Connect-MgGraph -Scope Policy.ReadWrite.AuthenticationMethod, User.Read.All -NoWelcome # Get licensed users [array]$Users = Get-MgUser -Filter "assignedLicenses/`$count ne 0 and userType eq 'Member'" -ConsistencyLevel eventual -CountVariable UsersFound -All -PageSize 999 If ($Users) { Write-Host ("{0} users found" -f $Users.Count) } Else { Write-Host "No users found" Break } $Report = [System.Collections.Generic.List[Object]]::new() Foreach ($User in $Users){ $Uri = ("https://graph.microsoft.com/beta/users/{0}/authentication/requirements" -f $user.id) $Data = Invoke-MgGraphRequest -Uri $Uri -Method Get $ReportLine = [PSCustomObject][ordered]@{ User = $User.UserPrincipalName Name = $User.displayName "MFA State" = $Data.PerUserMfaState } $Report.Add($ReportLine) } $Report | Export-CSV -Path "C:\Temp\MFAState.csv" -NoTypeInformation -Encoding utf8
Accounts can be in one of three states for per-user MFA: disabled, enabled, or enforced. To update the per-user MFA state for an account, use the Patch method:
$Body= @{} $Body.Add("perUserMFAState", "enabled") $Uri = ("https://graph.microsoft.com/beta/users/{0}/authentication/requirements" -f $user.id) Invoke-MgGraphRequest -Uri $Uri -Method Patch -Body $Body
Enhancing the User Passwords and MFA Report
Being able to generate a quick report of per-user MFA states is nice; integrating that data with other sources to create a comprehensive view of account password and MFA properties is even better. In January, I wrote about the inability to query the Graph to find which accounts use MFA. This is because when you use conditional access policies, MFA is the outcome of an assessment against policy for inbound connections rather than a fixed property of user accounts (like per-user MFA). The script I described in the article therefore uses information from several sources, including Entra ID sign-in logs, to report registration of MFA methods, and password change information. The report shows the last time when accounts successfully used MFA to connect, which is the acid test to know if an account uses MFA or not. User registration of MFA methods is one step along the path; using those methods when connecting to Entra ID is what we want to see.
Now that per-user MFA state information is available, I have updated the script (available from GitHub) to include that data. The HTML report generated by the script highlights accounts enabled or enforced for per-user MFA (Figure 2).
The end of the report includes a summary of the findings (Figure 3), including the number of accounts in the enabled or enforced per-user MFA states and the display names of the users in those categories.
The report also generates a CSV file for you to slice and dice the data as you wish.
Nice Addition to Entra ID Data
Being able to report per-user MFA states is a nice addition to the data available to Entra ID administrators. Whether it will convince organizations currently using per-user MFA to move to conditional access policies remains to be seen.
Support the work of the Office 365 for IT Pros team by subscribing to the Office 365 for IT Pros eBook. Your support pays for the time we need to track, analyze, and document the changing world of Microsoft 365 and Office 365.