PowerShell Basics: How to check if MFA is enabled in Azure and Office 365

Published Jun 25 2020 12:01 AM 35.1K Views
Microsoft

Security governance has been top of mind for most since the onslaught of human malware has the masses working from home.  This comes with new concerns surrounding identity protection and actually proving that remote users are who they say they are in order to be allowed access to organizational data.  Multi-factor Authentication (MFA) is a great tool to ensure this however the task of knowing which user has it enabled can be tedious. 

 

Enter PowerShell to the rescue to automate reporting of this process.

 

The following script will report on your organizations MFA status per user and report on which users are admins.  The latter being even more crucial that MFA is enabled.

 

Function Get-AzureMFAStatus {

    [CmdletBinding()]
    param(
        [Parameter(
            Position=0,
            ValueFromPipeline=$true,
            ValueFromPipelineByPropertyName=$true
            )]

        [string[]]   $UserPrincipalName,         
        [int]        $MaxResults = 4000,
        [bool]       $isLicensed = $true,
        [switch]     $SkipAdminCheck
    )
 
    BEGIN {
        if ($SkipAdminCheck.IsPresent) {
            $AdminUsers = Get-MsolRole -ErrorAction Stop | foreach {Get-MsolRoleMember -RoleObjectId $_.ObjectID} | Where-Object {$_.EmailAddress -ne $null} | Select EmailAddress -Unique | Sort-Object EmailAddress
        }
    }
 
    PROCESS {
        if ($UserPrincipalName) {
            foreach ($User in $UserPrincipalName) {
                try {
                    Get-MsolUser -UserPrincipalName $User -ErrorAction Stop | select DisplayName, UserPrincipalName, `
                        @{Name = 'isAdmin'; Expression = {if ($SkipAdminCheck) {Write-Output "-"} else {if ($AdminUsers -match $_.UserPrincipalName) {Write-Output $true} else {Write-Output $false}}}}, `
                        @{Name = 'MFAEnabled'; Expression={if ($_.StrongAuthenticationMethods) {Write-Output $true} else {Write-Output $false}}}
                              
                } catch {
                    $Object = [pscustomobject]@{
                        DisplayName       = '_NotSynced'
                        UserPrincipalName = $User
                        isAdmin           = '-'
                        MFAEnabled        = '-' 
                    }
                    Write-Output $Object
                }
            }
        } else {
            $AllUsers = Get-MsolUser -MaxResults $MaxResults | Where-Object {$_.IsLicensed -eq $isLicensed} | select DisplayName, UserPrincipalName, `
                @{Name = 'isAdmin'; Expression = {if ($SkipAdminCheck) {Write-Output "-"} else {if ($AdminUsers -match $_.UserPrincipalName) {Write-Output $true} else {Write-Output $false}}}}, `
                @{Name = 'MFAEnabled'; Expression={if ($_.StrongAuthenticationMethods) {Write-Output $true} else {Write-Output $false}}}
 
            Write-Output $AllUsers | Sort-Object isAdmin, MFAEnabled -Descending
        }
    }
    END {}
}

As always, please share your comments below on bettering the above script or any questions you may have.

 

6 Comments
New Contributor

Very useful script!

 

A small thing you might want to fix is regarding checking if [switch] parameters are used: the "correct" way is 

if ($SkipAdminCheck.IsPresent) { .. }
Microsoft

Thank you @Anders Rask.

Regular Visitor

Thank you for the useful script.

 

It really helped !

Occasional Contributor

This way is easier:

How to get a list of users without MFA enabled:
$UserCredential = Get-Credential Connect-MsolService -Credential $UserCredential
Get-MsolUser -All | where {$_.StrongAuthenticationMethods.Count -eq 0} | Select-Object -Property UserPrincipalName | Sort-Object userprincipalname

Occasional Visitor

I stumbled upon this article and this script is wrong in the core of it.


There is a difference between having StrongAuthenticationMethods configured and enabling MFA. You can register an alternate email or phonenumber without MFA being enforced or enabled.


To know if a user is MFA enabled or not is stored in StrongAuthenticationRequirements their state.


f.e.:

$Req = (Get-MsolUser -UserPrincipalName $UserObject.UserPrincipalName).StrongAuthenticationRequirements
if (($Req.State -eq "Enabled") -or ($Req.State -eq "Enforced")){
      Write-Host "MFA Enabled or Enforced"
}

I even suspect that this bug is present in the Extension for Azure MFA v1.0.1.35 (8/17/2020) because we see the same behavior when we use the NPS extension. It sends an MFA challenge even if MFA isn't enabled/enforced.
(https://www.microsoft.com/en-us/download/details.aspx?id=54688)

Occasional Visitor

Hi @D0mp13 

If MFA, Enabled via Conditional Access, then the state can be shown as Disabled too. 

Seems to me better to check the StrongAuthenticationMethods set or not and get the default one to know the MFA method

Get-MsolUser -UserPrincipalName <<upn@domain.com>> | select DisplayName,UserPrincipalName,@{Name="MFA Status"; Expression={ if( $_.StrongAuthenticationMethods.IsDefault -eq $true) {($_.StrongAuthenticationMethods | Where IsDefault -eq $True).MethodType} else { "Disabled"}}}

 

Co-Authors
Version history
Last update:
‎Apr 27 2021 07:28 AM
Updated by: