237 lines
8.6 KiB
PowerShell
Raw Normal View History

<#
=============================================================================================
Name: Export Office 365 users' MFA status using Microsoft Graph PowerShell
Description: This script exports O365 users MFA status report to CSV file
Version: 1.0
Website: o365reports.com
Script by: O365Reports Team
Script Highlights :
~~~~~~~~~~~~~~~~~
1. The script exports MFA status for all users.
2. You can filter results based on MFA status. I.e., you can export MFA enabled/disabled users separately.
3. Exports report to CSV file
4. You can filter the result to display Licensed users alone.
5. You can generate MFA report for sign-in allowed users only.
6. Shows MFA registration done through Conditional Access and Security Defaults too.
7. Automatically installs Microsoft Graph PowerShell module (if not installed already) upon your confirmation.
For detailed script execution: https://o365reports.com/2022/04/27/get-mfa-status-of-office-365-users-using-microsoft-graph-powershell
============================================================================================
#>
Param
(
[Parameter(Mandatory = $false)]
[switch]$CreateSession,
[switch]$MFAEnabled,
[switch]$MFADisabled,
[switch]$LicensedUsersOnly,
[switch]$SignInAllowedUsersOnly
)
Function Connect_MgGraph
{
#Check for module installation
$MsGraphBetaModule = Get-Module Microsoft.Graph.Beta -ListAvailable
if($MsGraphBetaModule -eq $null)
{
Write-host "Important: Microsoft Graph Beta module is unavailable. It is mandatory to have this module installed in the system to run the script successfully."
$confirm = Read-Host Are you sure you want to install Microsoft Graph Beta module? [Y] Yes [N] No
if($confirm -match "[yY]")
{
Write-host "Installing Microsoft Graph Beta module..."
Install-Module Microsoft.Graph.Beta -Scope CurrentUser -AllowClobber
Write-host "Microsoft Graph Beta module is installed in the machine successfully" -ForegroundColor Magenta
}
else
{
Write-host "Exiting. `nNote: Microsoft Graph Beta module must be available in your system to run the script" -ForegroundColor Red
Exit
}
}
#Disconnect Existing MgGraph session
if($CreateSession.IsPresent)
{
Disconnect-MgGraph
}
#Connecting to MgGraph beta
Write-Host Connecting to Microsoft Graph...
Connect-MgGraph -Scopes "User.Read.All","UserAuthenticationMethod.Read.All"
}
Connect_MgGraph
Write-Host "`nNote: If you encounter module related conflicts, run the script in a fresh PowerShell window.`n" -ForegroundColor Yellow
if((Get-MgContext) -ne "")
{
Write-Host Connected to Microsoft Graph PowerShell using (Get-MgContext).Account account -ForegroundColor Yellow
}
$ProcessedUserCount=0
$ExportCount=0
#Set output file
$ExportCSV=".\MfaStatusReport_$((Get-Date -format yyyy-MMM-dd-ddd` hh-mm` tt).ToString()).csv"
$Result=""
$Results=@()
#Get all users
Get-MgBetaUser -All -Filter "UserType eq 'Member'" | foreach {
$ProcessedUserCount++
$Name= $_.DisplayName
$UPN=$_.UserPrincipalName
$Department=$_.Department
if($_.AccountEnabled -eq $true)
{
$SigninStatus="Allowed"
}
else
{
$SigninStatus="Blocked"
}
if(($_.AssignedLicenses).Count -ne 0)
{
$LicenseStatus="Licensed"
}
else
{
$LicenseStatus="Unlicensed"
}
$Is3rdPartyAuthenticatorUsed="False"
$MFAPhone="-"
$MicrosoftAuthenticatorDevice="-"
Write-Progress -Activity "`n Processed users count: $ProcessedUserCount "`n" Currently processing user: $Name"
[array]$MFAData=Get-MgBetaUserAuthenticationMethod -UserId $UPN
$AuthenticationMethod=@()
$AdditionalDetails=@()
foreach($MFA in $MFAData)
{
Switch ($MFA.AdditionalProperties["@odata.type"])
{
"#microsoft.graph.passwordAuthenticationMethod"
{
$AuthMethod = 'PasswordAuthentication'
$AuthMethodDetails = $MFA.AdditionalProperties["displayName"]
}
"#microsoft.graph.microsoftAuthenticatorAuthenticationMethod"
{ # Microsoft Authenticator App
$AuthMethod = 'AuthenticatorApp'
$AuthMethodDetails = $MFA.AdditionalProperties["displayName"]
$MicrosoftAuthenticatorDevice=$MFA.AdditionalProperties["displayName"]
}
"#microsoft.graph.phoneAuthenticationMethod"
{ # Phone authentication
$AuthMethod = 'PhoneAuthentication'
$AuthMethodDetails = $MFA.AdditionalProperties["phoneType", "phoneNumber"] -join ' '
$MFAPhone=$MFA.AdditionalProperties["phoneNumber"]
}
"#microsoft.graph.fido2AuthenticationMethod"
{ # FIDO2 key
$AuthMethod = 'Fido2'
$AuthMethodDetails = $MFA.AdditionalProperties["model"]
}
"#microsoft.graph.windowsHelloForBusinessAuthenticationMethod"
{ # Windows Hello
$AuthMethod = 'WindowsHelloForBusiness'
$AuthMethodDetails = $MFA.AdditionalProperties["displayName"]
}
"#microsoft.graph.emailAuthenticationMethod"
{ # Email Authentication
$AuthMethod = 'EmailAuthentication'
$AuthMethodDetails = $MFA.AdditionalProperties["emailAddress"]
}
"microsoft.graph.temporaryAccessPassAuthenticationMethod"
{ # Temporary Access pass
$AuthMethod = 'TemporaryAccessPass'
$AuthMethodDetails = 'Access pass lifetime (minutes): ' + $MFA.AdditionalProperties["lifetimeInMinutes"]
}
"#microsoft.graph.passwordlessMicrosoftAuthenticatorAuthenticationMethod"
{ # Passwordless
$AuthMethod = 'PasswordlessMSAuthenticator'
$AuthMethodDetails = $MFA.AdditionalProperties["displayName"]
}
"#microsoft.graph.softwareOathAuthenticationMethod"
{
$AuthMethod = 'SoftwareOath'
$Is3rdPartyAuthenticatorUsed="True"
}
}
$AuthenticationMethod +=$AuthMethod
if($AuthMethodDetails -ne $null)
{
$AdditionalDetails +="$AuthMethod : $AuthMethodDetails"
}
}
#To remove duplicate authentication methods
$AuthenticationMethod =$AuthenticationMethod | Sort-Object | Get-Unique
$AuthenticationMethods= $AuthenticationMethod -join ","
$AdditionalDetail=$AdditionalDetails -join ", "
$Print=1
#Determine MFA status
[array]$StrongMFAMethods=("Fido2","PhoneAuthentication","PasswordlessMSAuthenticator","AuthenticatorApp","WindowsHelloForBusiness")
$MFAStatus="Disabled"
foreach($StrongMFAMethod in $StrongMFAMethods)
{
if($AuthenticationMethod -contains $StrongMFAMethod)
{
$MFAStatus="Strong"
break
}
}
if(($MFAStatus -ne "Strong") -and ($AuthenticationMethod -contains "SoftwareOath"))
{
$MFAStatus="Weak"
}
#Filter result based on MFA status
if($MFADisabled.IsPresent -and $MFAStatus -ne "Disabled")
{
$Print=0
}
if($MFAEnabled.IsPresent -and $MFAStatus -eq "Disabled")
{
$Print=0
}
#Filter result based on license status
if($LicensedUsersOnly.IsPresent -and ($LicenseStatus -eq "Unlicensed"))
{
$Print=0
}
#Filter result based on signin status
if($SignInAllowedUsersOnly.IsPresent -and ($SigninStatus -eq "Blocked"))
{
$Print=0
}
if($Print -eq 1)
{
$ExportCount++
$Result=@{'Name'=$Name;'UPN'=$UPN;'Department'=$Department;'License Status'=$LicenseStatus;'SignIn Status'=$SigninStatus;'Authentication Methods'=$AuthenticationMethods;'MFA Status'=$MFAStatus;'MFA Phone'=$MFAPhone;'Microsoft Authenticator Configured Device'=$MicrosoftAuthenticatorDevice;'Is 3rd-Party Authenticator Used'=$Is3rdPartyAuthenticatorUsed;'Additional Details'=$AdditionalDetail}
$Results= New-Object PSObject -Property $Result
$Results | Select-Object Name,UPN,Department,'License Status','SignIn Status','Authentication Methods','MFA Status','MFA Phone','Microsoft Authenticator Configured Device','Is 3rd-Party Authenticator Used','Additional Details' | Export-Csv -Path $ExportCSV -Notype -Append
}
}
if((Test-Path -Path $ExportCSV) -eq "True")
{
Write-Host `nThe output file contains $ExportCount users.
Write-Host `nThe Output file available in the current working directory with name: -NoNewline -Foregroundcolor Yellow; Write-Host $ExportCSV
Write-Host `n"For more Microsoft 365 PowerShell scripts, visit: https://o365reports.com"
$Prompt = New-Object -ComObject wscript.shell
$UserInput = $Prompt.popup("Do you want to open output file?",`
0,"Open Output File",4)
If ($UserInput -eq 6)
{
Invoke-Item "$ExportCSV"
}
}
else
{
Write-Host No users found.
}
Write-Host `n~~ Script prepared by AdminDroid Community ~~`n -ForegroundColor Green
Write-Host "~~ Check out " -NoNewline -ForegroundColor Green; Write-Host "admindroid.com" -ForegroundColor Yellow -NoNewline; Write-Host " to get access to 1800+ Microsoft 365 reports. ~~" -ForegroundColor Green `n`n