There are a ton of scripts out there that show you if the user has MFA enabled by checking their authentication methods, something very similar to this Get MFA Methods using Graph API script I wrote a while back. However, I haven’t really seen a script to show me what their per-user MFA status is.
Well today, we’re going to do just that. I understand this is the legacy method for setting multi-factor authentication on user accounts, however, there’s a probable chance that you might have forgotten to disable it when you eventually moved on to setting MFA using conditional access policies. I say that because this was the case for me not too long ago.
Table Of Contents
Requirements
In order to get started with checking per-user MFA status, we’re going to need a few things in place to make sure we get a successful output. Let’s list them out here.
- MSOnline (MSOL) PowerShell Module
- Global Administrator Role
Get Per-User MFA Status using Office 365 Portal
Before we get into the Powershell method, I wanted to quickly go over the method using the legacy Office 365 Portal. In order to check this, you will need to be a Global Administrator.
In Azure AD:
- Navigate to Users -> Per-user MFA
- Using the drop down for Multi-Factor Auth status: Choose Enabled or Enforced
Using this method, you have the option to quickly see their status and if you’re up to it, you can disable them right there.
Get Per-User MFA Status using PowerShell
Now that we know how to check in the portal to view the per-user mfa status, let’s take look at how to do this within PowerShell. This requires you to be connected to the MSOnline using Connect-MSolService so let’s take a look now.
Function Get-PerUserMFAStatus { <# .SYNOPSIS Get Per-User MFA Status using MSOnline Powershell Module .NOTES Name: Get-PerUserMFAStatus Author: theSysadminChannel Version: 1.0 DateCreated: 2021-Feb-3 .LINK https://thesysadminchannel.com/get-per-user-mfa-status-using-powershell - #> [CmdletBinding(DefaultParameterSetName='All')] param( [Parameter( Mandatory = $false, ParameterSetName = 'UPN', Position = 0 )] [string[]] $UserPrincipalName, [Parameter( Mandatory = $false, ParameterSetName = 'All' )] [switch] $All ) BEGIN { if (-not (Get-MsolDomain -ErrorAction SilentlyContinue)) { Write-Error "You must connect to the MSolService to continue" -ErrorAction Stop } } PROCESS { if ($PSBoundParameters.ContainsKey('UserPrincipalName')) { $MsolUserList = foreach ($MsolUser in $UserPrincipalName) { try { Get-MsolUser -UserPrincipalName $MsolUser -ErrorAction Stop } catch { Write-Error $_.Exception.Message } } } else { $MsolUserList = Get-MsolUser -All -ErrorAction Stop | Where-Object {$_.UserType -ne 'Guest' -and $_.DisplayName -notmatch 'On-Premises Directory Synchronization'} } #Now that we have our UserList, lets check the per-user mfa status foreach ($User in $MsolUserList) { if ($User.StrongAuthenticationRequirements) { $PerUserMFAState = $User.StrongAuthenticationRequirements.State } else { $PerUserMFAState = 'Disabled' } $MethodType = $User.StrongAuthenticationMethods | Where-Object {$_.IsDefault -eq $true} | select -ExpandProperty MethodType if ($MethodType) { switch ($MethodType) { 'OneWaySMS' {$DefaultMethodType = 'SMS Text Message' } 'TwoWayVoiceMobile' {$DefaultMethodType = 'Call to Phone' } 'PhoneAppOTP' {$DefaultMethodType = 'TOTP' } 'PhoneAppNotification' {$DefaultMethodType = 'Authenticator App' } } } else { $DefaultMethodType = 'Not Enabled' } [PSCustomObject]@{ UserPrincipalName = $User.UserPrincipalName DisplayName = $User.DisplayName PerUserMFAState = $PerUserMFAState DefaultMethodType = $DefaultMethodType } $MethodType = $null } } END {} }
Script Parameters
-UserPrincipalName
DataType: string/array
Description: Specify the UserPrincipalName of the per-user MFA status you would like to see. Multiple UPNs separated by a comma are acceptable.
Example 1 – Specifying UserPrincipalNames separated by a comma
PS C:\> Get-PerUserMFAStatus -UserPrincipalName [email protected], [email protected], ` [email protected], [email protected]
Example 2 – Getting all user’s status in the tenant
PS C:\> Get-PerUserMFAStatus -All
Conclusion
As mentioned, the per-user mfa is not the recommended way to enable MFA for your users. For that, we’ll want to either use conditional access (which require an Azure P1/P2 license). For those that don’t have this license in their tenant, you can use security defaults which enables MFA across the whole tenant.
Hopefully, you were able to find this script useful in finding which users still have the legacy MFA method enabled.
Nice code, using it to create a report so we can keep track on how many we are still to go for MFA and to make sure they have a recorded method… one problem though… we have a few FIDO2-users and they show up as NotEnabled for DefaultMethodType… any ideas how to fix this?
It baffles me that there isn’t an audit log for this…
Could this work with the Duo module for us that utilize this as our MFA solution?
The most used powershell module seems to be https://github.com/mbegan/Duo-PSModule