Added
This commit is contained in:
@@ -0,0 +1,56 @@
|
|||||||
|
<#
|
||||||
|
.SYNOPSIS
|
||||||
|
Export-CAPolicies.ps1
|
||||||
|
|
||||||
|
.DESCRIPTION
|
||||||
|
Export Conditional Access policies to JSON files for backup purposes.
|
||||||
|
|
||||||
|
.LINK
|
||||||
|
www.alitajran.com/export-conditional-access-policies/
|
||||||
|
|
||||||
|
.NOTES
|
||||||
|
Written by: ALI TAJRAN
|
||||||
|
Website: www.alitajran.com
|
||||||
|
LinkedIn: linkedin.com/in/alitajran
|
||||||
|
|
||||||
|
.CHANGELOG
|
||||||
|
V1.00, 11/16/2023 - Initial version
|
||||||
|
V1.10, 03/23/2026 - Skip Microsoft-managed policies on export
|
||||||
|
#>
|
||||||
|
|
||||||
|
# Connect to Microsoft Graph API
|
||||||
|
Connect-MgGraph -Scopes 'Policy.Read.All' -NoWelcome
|
||||||
|
|
||||||
|
# Export path for CA policies
|
||||||
|
$ExportPath = "C:\temp"
|
||||||
|
|
||||||
|
try {
|
||||||
|
# Retrieve all conditional access policies from Microsoft Graph API
|
||||||
|
$AllPolicies = Get-MgIdentityConditionalAccessPolicy -All
|
||||||
|
|
||||||
|
if ($AllPolicies.Count -eq 0) {
|
||||||
|
Write-Host "There are no CA policies found to export." -ForegroundColor Yellow
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
# Iterate through each policy
|
||||||
|
foreach ($Policy in $AllPolicies) {
|
||||||
|
try {
|
||||||
|
# Skip Microsoft-managed policies
|
||||||
|
if ($Policy.DisplayName -like 'Microsoft-managed:*') {
|
||||||
|
Write-Host "Skipped Microsoft-managed policy: $($Policy.DisplayName)" -ForegroundColor Cyan
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
$PolicyName = $Policy.DisplayName -replace '[\\/:*?"<>|]', ''
|
||||||
|
$PolicyJSON = $Policy | ConvertTo-Json -Depth 6
|
||||||
|
$PolicyJSON | Out-File "$ExportPath\$PolicyName.json" -Force
|
||||||
|
Write-Host "Successfully backed up CA policy: $($Policy.DisplayName)" -ForegroundColor Green
|
||||||
|
}
|
||||||
|
catch {
|
||||||
|
Write-Host "Error occurred while backing up CA policy: $($Policy.DisplayName). $($_.Exception.Message)" -ForegroundColor Red
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch {
|
||||||
|
Write-Host "Error occurred: $($_.Exception.Message)" -ForegroundColor Red
|
||||||
|
}
|
||||||
@@ -0,0 +1,122 @@
|
|||||||
|
<#
|
||||||
|
.SYNOPSIS
|
||||||
|
Get-MFAReport.ps1
|
||||||
|
|
||||||
|
.DESCRIPTION
|
||||||
|
Export Microsoft 365 per-user MFA report with Micrososoft Graph PowerShell.
|
||||||
|
|
||||||
|
.LINK
|
||||||
|
www.alitajran.com/export-office-365-users-mfa-status-with-powershell/
|
||||||
|
|
||||||
|
.NOTES
|
||||||
|
Written by: ALI TAJRAN
|
||||||
|
Website: www.alitajran.com
|
||||||
|
LinkedIn: linkedin.com/in/alitajran
|
||||||
|
|
||||||
|
.CHANGELOG
|
||||||
|
V1.00, 04/04/2021 - Initial version
|
||||||
|
V2.00, 08/04/2024 - Rewritten for Microsoft Graph PowerShell
|
||||||
|
#>
|
||||||
|
|
||||||
|
# Connect to Microsoft Graph with the required scopes
|
||||||
|
Connect-MgGraph -Scopes "User.Read.All", "Policy.ReadWrite.AuthenticationMethod", "UserAuthenticationMethod.Read.All"
|
||||||
|
|
||||||
|
# CSV export file path
|
||||||
|
$CSVfile = "C:\temp\MFAUsers.csv"
|
||||||
|
|
||||||
|
# Get properties
|
||||||
|
$Properties = @(
|
||||||
|
'Id',
|
||||||
|
'DisplayName',
|
||||||
|
'UserPrincipalName',
|
||||||
|
'UserType',
|
||||||
|
'Mail',
|
||||||
|
'ProxyAddresses',
|
||||||
|
'AccountEnabled',
|
||||||
|
'CreatedDateTime'
|
||||||
|
)
|
||||||
|
|
||||||
|
# Get all users
|
||||||
|
[array]$Users = Get-MgUser -All -Property $Properties | Select-Object $Properties
|
||||||
|
|
||||||
|
# Initialize the report list
|
||||||
|
$Report = [System.Collections.Generic.List[Object]]::new()
|
||||||
|
|
||||||
|
# Check if any users were retrieved
|
||||||
|
if (-not $Users) {
|
||||||
|
Write-Host "No users found. Exiting script." -ForegroundColor Red
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
# Initialize progress counter
|
||||||
|
$counter = 0
|
||||||
|
$totalUsers = $Users.Count
|
||||||
|
|
||||||
|
# Loop through each user and get their MFA settings
|
||||||
|
foreach ($User in $Users) {
|
||||||
|
$counter++
|
||||||
|
|
||||||
|
# Calculate percentage completion
|
||||||
|
$percentComplete = [math]::Round(($counter / $totalUsers) * 100)
|
||||||
|
|
||||||
|
# Define progress bar parameters with user principal name
|
||||||
|
$progressParams = @{
|
||||||
|
Activity = "Processing Users"
|
||||||
|
Status = "User $($counter) of $totalUsers - $($User.UserPrincipalName) - $percentComplete% Complete"
|
||||||
|
PercentComplete = $percentComplete
|
||||||
|
}
|
||||||
|
|
||||||
|
Write-Progress @progressParams
|
||||||
|
|
||||||
|
# Get MFA settings
|
||||||
|
$MFAStateUri = "https://graph.microsoft.com/beta/users/$($User.Id)/authentication/requirements"
|
||||||
|
$Data = Invoke-MgGraphRequest -Uri $MFAStateUri -Method GET
|
||||||
|
|
||||||
|
# Get the default MFA method
|
||||||
|
$DefaultMFAUri = "https://graph.microsoft.com/beta/users/$($User.Id)/authentication/signInPreferences"
|
||||||
|
$DefaultMFAMethod = Invoke-MgGraphRequest -Uri $DefaultMFAUri -Method GET
|
||||||
|
|
||||||
|
# Determine the MFA default method
|
||||||
|
if ($DefaultMFAMethod.userPreferredMethodForSecondaryAuthentication) {
|
||||||
|
$MFAMethod = $DefaultMFAMethod.userPreferredMethodForSecondaryAuthentication
|
||||||
|
Switch ($MFAMethod) {
|
||||||
|
"push" { $MFAMethod = "Microsoft authenticator app" }
|
||||||
|
"oath" { $MFAMethod = "Authenticator app or hardware token" }
|
||||||
|
"voiceMobile" { $MFAMethod = "Mobile phone" }
|
||||||
|
"voiceAlternateMobile" { $MFAMethod = "Alternate mobile phone" }
|
||||||
|
"voiceOffice" { $MFAMethod = "Office phone" }
|
||||||
|
"sms" { $MFAMethod = "SMS" }
|
||||||
|
Default { $MFAMethod = "Unknown method" }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
$MFAMethod = "Not Enabled"
|
||||||
|
}
|
||||||
|
|
||||||
|
# Filter only the aliases
|
||||||
|
$Aliases = ($User.ProxyAddresses | Where-Object { $_ -clike "smtp*" } | ForEach-Object { $_ -replace "smtp:", "" }) -join ', '
|
||||||
|
|
||||||
|
# Create a report line for each user
|
||||||
|
$ReportLine = [PSCustomObject][ordered]@{
|
||||||
|
UserPrincipalName = $User.UserPrincipalName
|
||||||
|
DisplayName = $User.DisplayName
|
||||||
|
MFAState = $Data.PerUserMfaState
|
||||||
|
MFADefaultMethod = $MFAMethod
|
||||||
|
PrimarySMTP = $User.Mail
|
||||||
|
Aliases = $Aliases
|
||||||
|
UserType = $User.UserType
|
||||||
|
AccountEnabled = $User.AccountEnabled
|
||||||
|
CreatedDateTime = $User.CreatedDateTime
|
||||||
|
}
|
||||||
|
$Report.Add($ReportLine)
|
||||||
|
}
|
||||||
|
|
||||||
|
# Complete the progress bar
|
||||||
|
Write-Progress -Activity "Processing Users" -Completed
|
||||||
|
|
||||||
|
# Display the report in a grid view
|
||||||
|
$Report | Out-GridView -Title "Microsoft 365 per-user MFA Report"
|
||||||
|
|
||||||
|
# Export the report to a CSV file
|
||||||
|
$Report | Export-Csv -Path $CSVfile -NoTypeInformation -Encoding utf8
|
||||||
|
Write-Host "Microsoft 365 per-user MFA Report is in $CSVfile" -ForegroundColor Cyan
|
||||||
Reference in New Issue
Block a user