Users with Weak or No MFA

#Requires -Modules Microsoft.Graph.Authentication, Microsoft.Graph.Users
#Requires -Version 7.0

<#
.SYNOPSIS
    Checks Microsoft 365 users for weak or no MFA configurations and splits results into two lists.
.DESCRIPTION
    This script connects to Microsoft Graph and identifies users with no MFA or weak MFA methods (SMS or voice).
    It generates separate reports for users with no MFA and users with weak MFA.
.NOTES
    Requires Microsoft Graph PowerShell SDK and appropriate permissions (UserAuthenticationMethod.Read.All, User.Read.All).
    Must be run in PowerShell 7.0 or later.
    Run with Global Admin or equivalent credentials.
#>

# Verify PowerShell version
if ($PSVersionTable.PSVersion.Major -lt 7) {
    Write-Error "This script requires PowerShell 7.0 or later. Current version: $($PSVersionTable.PSVersion). Please run in PowerShell 7."
    exit 1
}

# Connect to Microsoft Graph with required scopes
Connect-MgGraph -Scopes "UserAuthenticationMethod.Read.All", "User.Read.All" -NoWelcome

# Initialize report array
$report = @()

# Get all users
$users = Get-MgUser -All -Select "id,displayName,userPrincipalName,accountEnabled"

foreach ($user in $users) {
    if (-not $user.AccountEnabled) { continue } # Skip disabled accounts

    # Get authentication methods for the user
    $authMethods = Get-MgUserAuthenticationMethod -UserId $user.Id

    # Initialize MFA status
    $mfaStatus = "No MFA"
    $isWeakMFA = $false
    $details = @()

    foreach ($method in $authMethods) {
        switch ($method.AdditionalProperties["@odata.type"]) {
            "#microsoft.graph.microsoftAuthenticatorAuthenticationMethod" {
                $mfaStatus = "Strong MFA"
                $details += "Microsoft Authenticator"
            }
            "#microsoft.graph.fido2AuthenticationMethod" {
                $mfaStatus = "Strong MFA"
                $details += "FIDO2 Security Key"
            }
            "#microsoft.graph.windowsHelloForBusinessAuthenticationMethod" {
                $mfaStatus = "Strong MFA"
                $details += "Windows Hello"
            }
            "#microsoft.graph.phoneAuthenticationMethod" {
                $mfaStatus = "Weak MFA"
                $isWeakMFA = $true
                $phoneType = $method.AdditionalProperties["phoneType"]
                $details += "Phone ($phoneType)"
            }
            "#microsoft.graph.passwordAuthenticationMethod" {
                # Password alone doesn't count as MFA
                if ($mfaStatus -eq "No MFA") { $details += "Password Only" }
            }
        }
    }

    # Create report entry
    $reportEntry = [PSCustomObject]@{
        DisplayName       = $user.DisplayName
        UserPrincipalName = $user.UserPrincipalName
        MFAStatus         = $mfaStatus
        IsWeakMFA         = $isWeakMFA
        AuthMethods       = ($details -join ", ")
    }

    $report += $reportEntry
}

# Disconnect from Microsoft Graph
Disconnect-MgGraph -ErrorAction SilentlyContinue

# Split into two lists
$noMFAUsers = $report | Where-Object { $_.MFAStatus -eq "No MFA" }
$weakMFAUsers = $report | Where-Object { $_.IsWeakMFA }

# Output No MFA users to console
Write-Host "`nUsers with No MFA:" -ForegroundColor Red
if ($noMFAUsers.Count -eq 0) {
    Write-Host "No users found with no MFA." -ForegroundColor Green
} else {
    $noMFAUsers | Format-Table DisplayName, UserPrincipalName, MFAStatus, AuthMethods -AutoSize
}

# Output Weak MFA users to console
Write-Host "`nUsers with Weak MFA:" -ForegroundColor Yellow
if ($weakMFAUsers.Count -eq 0) {
    Write-Host "No users found with weak MFA." -ForegroundColor Green
} else {
    $weakMFAUsers | Format-Table DisplayName, UserPrincipalName, MFAStatus, AuthMethods -AutoSize
}

# Export to CSV
$timestamp = Get-Date -Format 'yyyyMMdd_HHmmss'
$noMFACsvPath = "NoMFAReport_$timestamp.csv"
$weakMFACsvPath = "WeakMFAReport_$timestamp.csv"

if ($noMFAUsers.Count -gt 0) {
    $noMFAUsers | Export-Csv -Path $noMFACsvPath -NoTypeInformation
    Write-Host "No MFA report exported to $noMFACsvPath" -ForegroundColor Green
} else {
    Write-Host "No MFA CSV not created (no users found)." -ForegroundColor Yellow
}

if ($weakMFAUsers.Count -gt 0) {
    $weakMFAUsers | Export-Csv -Path $weakMFACsvPath -NoTypeInformation
    Write-Host "Weak MFA report exported to $weakMFACsvPath" -ForegroundColor Green
} else {
    Write-Host "Weak MFA CSV not created (no users found)." -ForegroundColor Yellow
}

# Summary
$totalUsers = $users.Count
$noMFACount = $noMFAUsers.Count
$weakMFACount = $weakMFAUsers.Count

Write-Host "`nSummary:" -ForegroundColor Cyan
Write-Host "Total Users: $totalUsers"
Write-Host "Users with No MFA: $noMFACount"
Write-Host "Users with Weak MFA: $weakMFACount"
1 Star2 Stars3 Stars4 Stars5 Stars (No Ratings Yet)
Loading...