Reset MFA for Microsoft 365 Users

This commit is contained in:
AdminDroid 2024-10-19 10:20:29 +05:30
parent 0d70236ad6
commit afb5f5e27d

View File

@ -0,0 +1,238 @@
<#
=========================================================================================
Name: Reset MFA for Microsoft 365 Users
Version: 1.0
Website: blog.admindroid.com
~~~~~~~~~~~~~~~~~~
Script Highlights:
~~~~~~~~~~~~~~~~~~
1. The script covers 25+ usecases to reset MFA for Microsoft 365 users more granularly.   
2. Users scope
- Single user
- Bulk users (inout CSV)
- All users
- Admin accounts
- Guest accounts 
- Licensed users
- Disabled users
3. Supported Authentication methods
- Email
- FIDO2
- Microsoft Authenticator
- Phone
- Software OATH
- Temporary Access Pass
- Windows Hello for Business    
3. Exports log file.     
4. The script supports certificate-based authentication too. 
For detailed script execution: https://blog.admindroid.com/reset-mfa-for-microsoft-365-users/
=========================================================================================
#>
Param
(
[Parameter(Mandatory = $false)]
[ValidateSet(
'Email',
'FIDO2',
'Microsoft Authenticator',
'Phone',
'Software OATH',
'Temporary Access Pass',
'Windows Hello for Business'
)]
[string]$ResetMFAMethod,
[string]$UserId,
[string]$CsvFilePath,
[switch]$AllUsers,
[switch]$AdminsOnly,
[switch]$GuestUsersOnly,
[switch]$LicensedUsersOnly,
[switch]$DisabledUsersOnly,
[string]$TenantId,
[string]$ClientId,
[string]$CertificateThumbprint
)
# Function to connect to Microsoft Graph
function Connect_ToMgGraph {
# Check if Microsoft Graph module is installed
$MsGraphModule = Get-Module Microsoft.Graph -ListAvailable
if ($MsGraphModule -eq $null) {
Write-Host "`nImportant: Microsoft Graph 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 module? [Y] Yes [N] No"
if ($confirm -match "[yY]") {
Write-Host "Installing Microsoft Graph module..."
Install-Module Microsoft.Graph -Scope CurrentUser -AllowClobber
Write-Host "Microsoft Graph module is installed in the machine successfully" -ForegroundColor Magenta
} else {
Write-Host "Exiting. `nNote: Microsoft Graph module must be available in your system to run the script" -ForegroundColor Red
Exit
}
}
Write-Host "`nConnecting to Microsoft Graph..."
if (($TenantId -ne "") -and ($ClientId -ne "") -and ($CertificateThumbprint -ne "")) {
# Use certificate-based authentication if TenantId, ClientId, and CertificateThumbprint are provided
Connect-MgGraph -TenantId $TenantId -AppId $ClientId -CertificateThumbprint $CertificateThumbprint -NoWelcome
} else {
# Use delegated permissions (Scopes) if credentials are not provided
Connect-MgGraph -Scopes "User.Read.All", "UserAuthenticationMethod.ReadWrite.All" -NoWelcome
}
# Verify connection
if ((Get-MgContext) -ne $null) {
Write-Host "Connected to Microsoft Graph PowerShell using account: $((Get-MgContext).Account)`n"
} else {
Write-Host "Failed to connect to Microsoft Graph." -ForegroundColor Red
Exit
}
}
# Function to log details of authentication method removal
function Log-MFAReset {
param (
[string]$UserId,
[string]$AuthMethodType,
[boolean]$Status
)
$Timestamp = (Get-Date).ToLocalTime()
if ($Status) {
$LogEntry = "$Timestamp - MFA reset for $UserId on $AuthMethodType has been successful."
} else {
$LogEntry = "$Timestamp - MFA reset for $UserId on $AuthMethodType has been failed."
}
Add-Content -Path $LogFilePath -Value $LogEntry
}
# Function to reset MFA authentication method for users
function Reset-MFA {
param(
[string]$UserId,
[object[]]$UserAuthenticationDetail
)
$MethodType = $UserAuthenticationDetail.AdditionalProperties['@odata.type']
$FriendlyAuthName = $AuthMethods.Keys | Where-Object { $AuthMethods[$_] -eq $MethodType }
if ($MethodType -eq '#microsoft.graph.passwordAuthenticationMethod' ) { continue }
# Perform removal based on the method type
switch ($MethodType) {
'#microsoft.graph.emailAuthenticationMethod' {
$Script:ResetStatus = Remove-MgUserAuthenticationEmailMethod -UserId $UserId -EmailAuthenticationMethodId $UserAuthenticationDetail.Id -PassThru
}
'#microsoft.graph.fido2AuthenticationMethod' {
$Script:ResetStatus = Remove-MgUserAuthenticationFido2Method -UserId $UserId -Fido2AuthenticationMethodId $UserAuthenticationDetail.Id -PassThru
}
'#microsoft.graph.microsoftAuthenticatorAuthenticationMethod' {
$Script:ResetStatus = Remove-MgUserAuthenticationMicrosoftAuthenticatorMethod -UserId $UserId -MicrosoftAuthenticatorAuthenticationMethodId $UserAuthenticationDetail.Id -PassThru
}
'#microsoft.graph.phoneAuthenticationMethod' {
$Script:ResetStatus = Remove-MgUserAuthenticationPhoneMethod -UserId $UserId -PhoneAuthenticationMethodId $UserAuthenticationDetail.Id -PassThru
}
'#microsoft.graph.softwareOathAuthenticationMethod' {
$Script:ResetStatus = Remove-MgUserAuthenticationSoftwareOathMethod -UserId $UserId -SoftwareOathAuthenticationMethodId $UserAuthenticationDetail.Id -PassThru
}
'#microsoft.graph.temporaryAccessPassAuthenticationMethod' {
$Script:ResetStatus = Remove-MgUserAuthenticationTemporaryAccessPassMethod -UserId $UserId -TemporaryAccessPassAuthenticationMethodId $UserAuthenticationDetail.Id -PassThru
}
'#microsoft.graph.windowsHelloForBusinessAuthenticationMethod' {
$Script:ResetStatus = Remove-MgUserAuthenticationWindowsHelloForBusinessMethod -UserId $UserId -WindowsHelloForBusinessAuthenticationMethodId $UserAuthenticationDetail.Id -PassThru
}
}
# Log the MFA reset based on the MFA reset status
Log-MFAReset -UserId $UserId -AuthMethodType $FriendlyAuthName -Status $Script:ResetStatus
}
# Function to call reset MFA for each users in array
function Reset-MfaForUsers {
param(
[string[]]$Users,
[string]$SpecificAuthMethod
)
$AuthMethods = @{
"Email" = "#microsoft.graph.emailAuthenticationMethod";
"FIDO2" = "#microsoft.graph.fido2AuthenticationMethod";
"Microsoft Authenticator" = "#microsoft.graph.microsoftAuthenticatorAuthenticationMethod";
"Phone" = "#microsoft.graph.phoneAuthenticationMethod";
"Password" = "#microsoft.graph.passwordAuthenticationMethod";
"Software OATH" = "#microsoft.graph.softwareOathAuthenticationMethod";
"Temporary Access Pass" = "#microsoft.graph.temporaryAccessPassAuthenticationMethod";
"Windows Hello for Business" = "#microsoft.graph.windowsHelloForBusinessAuthenticationMethod"
}
foreach ($User in $Users) {
if (-not [string]::IsNullOrEmpty($SpecificAuthMethod)) {
$UserAuthenticationDetails = Get-MgUserAuthenticationMethod -UserId $User | Select-Object Id, AdditionalProperties | Where-Object { $_.AdditionalProperties['@odata.type'] -eq $AuthMethods[$SpecificAuthMethod] }
} else {
$UserAuthenticationDetails = Get-MgUserAuthenticationMethod -UserId $User | Select-Object Id, AdditionalProperties
}
foreach ($UserAuthenticationDetail in $UserAuthenticationDetails) {
$Script:ResetStatus = $false
Reset-MFA -UserId $User -UserAuthenticationDetail $UserAuthenticationDetail
if (!$Script:ResetStatus) {
Reset-MFA -UserId $User -UserAuthenticationDetail $UserAuthenticationDetail
}
}
}
}
# Connecting to the Microsoft Graph PowerShell Module
Connect_ToMgGraph
# Define log file path and get users
$LogFilePath = "$(Get-Location)\MFA_Reset_Log_$((Get-Date -format yyyy-MMM-dd-ddd` hh-mm-ss` tt).ToString()).txt"
$Users = Get-MgUser -All -Property AccountEnabled, AssignedLicenses, UserType, UserPrincipalName | Select-Object -Property AccountEnabled, AssignedLicenses, UserType, UserPrincipalName
if (-not [string]::IsNullOrEmpty($CsvFilePath)) {
# Load users from the CSV file
$Users = Import-CSV -Path $CsvFilePath
$Users.Name | ForEach-Object { Reset-MfaForUsers -Users $_ -SpecificAuthMethod $ResetMFAMethod }
}
elseif (-not [string]::IsNullOrEmpty($UserId)) {
Reset-MfaForUsers -Users $UserId -SpecificAuthMethod $ResetMFAMethod
}
elseif (!$DisabledUsersOnly -and !$LicensedUsersOnly -and !$GuestUsersOnly -and !$AdminsOnly -and !$AllUsers) {
$UserId = Read-Host "Enter the User ID or UPN of a User to Reset MFA"
Reset-MfaForUsers -Users $UserId -SpecificAuthMethod $ResetMFAMethod
}
elseif ($AllUsers.IsPresent) {
$Users | ForEach-Object { Reset-MfaForUsers -Users $_.UserPrincipalName -SpecificAuthMethod $ResetMFAMethod }
}
elseif ($DisabledUsersOnly.IsPresent) {
$Users | Where-Object { $_.AccountEnabled -eq $false } | ForEach-Object { Reset-MfaForUsers -Users $_.UserPrincipalName -SpecificAuthMethod $ResetMFAMethod }
}
elseif ($LicensedUsersOnly.IsPresent) {
$Users | Where-Object { $_.AssignedLicenses } | ForEach-Object { Reset-MfaForUsers -Users $_.UserPrincipalName -SpecificAuthMethod $ResetMFAMethod }
}
elseif ($GuestUsersOnly.IsPresent) {
$Users | Where-Object { $_.UserType -eq "Guest" } | ForEach-Object { Reset-MfaForUsers -Users $_.UserPrincipalName -SpecificAuthMethod $ResetMFAMethod }
}
elseif ($AdminsOnly.IsPresent) {
$Users | Where-Object { Get-MgUserTransitiveMemberOfAsDirectoryRole -UserId $_.UserPrincipalName } | ForEach-Object { Reset-MfaForUsers -Users $_.UserPrincipalName -SpecificAuthMethod $ResetMFAMethod }
}
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 1900+ Microsoft 365 reports. ~~" -ForegroundColor Green `n
# Disconnect from Microsoft Graph
Disconnect-MgGraph | Out-Null
if((Test-Path -Path $LogFilePath) -eq "True") {
Write-Host " The MFA reset log file available in: " -NoNewline -ForegroundColor Yellow; Write-Host "$LogFilePath"
$Prompt = New-Object -ComObject wscript.shell
$UserInput = $Prompt.popup("Do you want to open the log file?",` 0,"Open Log File",4)
if ($UserInput -eq 6) {
Invoke-Item "$LogFilePath"
}
}
else {
Write-Host "`nUser(s) not found or a specific Registration method(s) not configured."
}