Public/Get-MFAStatus.ps1

function Get-MFAStatus {
    <#
    .SYNOPSIS
        Reports MFA enrollment status for all Microsoft 365 users.
 
    .DESCRIPTION
        Queries Microsoft Graph for user authentication methods and reports
        which users have MFA enabled, what methods they use, and which users
        are unprotected.
 
    .PARAMETER UserType
        Filter by user type: All, Member, or Guest. Defaults to Member.
 
    .PARAMETER IncludeDisabled
        Include disabled/blocked accounts in the report.
 
    .EXAMPLE
        Get-MFAStatus
 
        Returns MFA status for all enabled member accounts.
 
    .EXAMPLE
        Get-MFAStatus -UserType All | Where-Object { -not $_.MFAEnabled }
 
        Lists all users without MFA.
 
    .NOTES
        Requires: Microsoft.Graph.Users, Microsoft.Graph.Authentication
        Scopes: User.Read.All, UserAuthenticationMethod.Read.All
    #>

    [CmdletBinding()]
    param(
        [ValidateSet('All', 'Member', 'Guest')]
        [string]$UserType = 'Member',

        [switch]$IncludeDisabled
    )

    # Get all users
    $userParams = @{
        All      = $true
        Property = @('Id', 'DisplayName', 'UserPrincipalName', 'UserType', 'AccountEnabled', 'CreatedDateTime', 'SignInActivity')
    }

    $users = Get-MgUser @userParams

    if ($UserType -ne 'All') {
        $users = $users | Where-Object UserType -eq $UserType
    }

    if (-not $IncludeDisabled) {
        $users = $users | Where-Object AccountEnabled -eq $true
    }

    $total = $users.Count
    $current = 0

    foreach ($user in $users) {
        $current++
        Write-Progress -Activity "Checking MFA status" -Status "$($user.DisplayName) ($current/$total)" -PercentComplete (($current / $total) * 100)

        try {
            $authMethods = Get-MgUserAuthenticationMethod -UserId $user.Id -ErrorAction Stop

            $methods = $authMethods | ForEach-Object {
                switch ($_.AdditionalProperties['@odata.type']) {
                    '#microsoft.graph.microsoftAuthenticatorAuthenticationMethod' { 'Authenticator App' }
                    '#microsoft.graph.phoneAuthenticationMethod'                 { 'Phone' }
                    '#microsoft.graph.fido2AuthenticationMethod'                 { 'FIDO2 Key' }
                    '#microsoft.graph.windowsHelloForBusinessAuthenticationMethod' { 'Windows Hello' }
                    '#microsoft.graph.emailAuthenticationMethod'                 { 'Email' }
                    '#microsoft.graph.passwordAuthenticationMethod'              { 'Password' }
                    '#microsoft.graph.softwareOathAuthenticationMethod'          { 'TOTP Token' }
                    default { $_.AdditionalProperties['@odata.type'] -replace '#microsoft.graph.', '' }
                }
            }

            # MFA is enabled if they have any method beyond just Password
            $nonPasswordMethods = $methods | Where-Object { $_ -ne 'Password' }
            $mfaEnabled = ($nonPasswordMethods.Count -gt 0)

            $lastSignIn = $user.SignInActivity.LastSignInDateTime

            [PSCustomObject]@{
                DisplayName       = $user.DisplayName
                UserPrincipalName = $user.UserPrincipalName
                UserType          = $user.UserType
                AccountEnabled    = $user.AccountEnabled
                MFAEnabled        = $mfaEnabled
                Methods           = ($nonPasswordMethods -join '; ')
                AllMethods        = ($methods -join '; ')
                LastSignIn        = $lastSignIn
                Created           = $user.CreatedDateTime
            }
        }
        catch {
            Write-Warning "Failed to get auth methods for $($user.UserPrincipalName): $_"
            [PSCustomObject]@{
                DisplayName       = $user.DisplayName
                UserPrincipalName = $user.UserPrincipalName
                UserType          = $user.UserType
                AccountEnabled    = $user.AccountEnabled
                MFAEnabled        = 'Error'
                Methods           = "Error: $_"
                AllMethods        = $null
                LastSignIn        = $null
                Created           = $user.CreatedDateTime
            }
        }
    }

    Write-Progress -Activity "Checking MFA status" -Completed
}