Script to Reset User Authentication Methods and Add to Group Using Microsoft Graph
Microsoft Graph User Authentication Reset and Group Management Script
Section titled “Microsoft Graph User Authentication Reset and Group Management Script”Overview
Section titled “Overview”This PowerShell script connects to Microsoft Graph API to reset user authentication methods and add users to specified groups based on CSV data. It clears existing authentication methods (email, phone, Microsoft Authenticator, OTP), sets SMS as the default authentication method, and resets user passwords when applicable. The script generates comprehensive reports of temporary passwords assigned and exports results to CSV format.
Key Features
Section titled “Key Features”| Feature | Capability | Business Value |
|---|---|---|
| Authentication Reset | Clears all existing auth methods (email, phone, Authenticator, OTP) | Ensures clean security baseline for users |
| SMS Default Setup | Configures SMS as primary secondary authentication method | Provides reliable backup authentication option |
| Password Reset | Generates temporary passwords for affected users | Enables secure password recovery process |
| Group Management | Automatically adds users to specified Azure AD groups | Streamlines user onboarding and access management |
| CSV Reporting | Exports temporary passwords and results to CSV file | Provides audit trail and documentation |
Script Configuration
Section titled “Script Configuration”Prerequisites
Section titled “Prerequisites”- Microsoft Graph PowerShell SDK installed
- Global Administrator or appropriate permissions
- CSV file with user UPN and phone number columns
Required Variables
Section titled “Required Variables”$GroupID = "xxx" # Target Azure AD Group ID$CSVPath = "$HOME\Desktop\Users.csv" # Path to user data file$TenantId = "xxx.onmicrosoft.com" # Your tenant identifierCore Functions
Section titled “Core Functions”ConvertTo-PsObject Function
Section titled “ConvertTo-PsObject Function”Converts hashtable values to PowerShell objects for proper data handling.
Reset-UserSecurityInfo Function
Section titled “Reset-UserSecurityInfo Function”Purpose: Comprehensive user authentication reset
Actions performed:
- Revokes all active user sessions
- Removes email authentication methods
- Updates or removes phone authentication
- Resets password when applicable
- Removes Microsoft Authenticator methods
- Removes OTP (Software OATH) methods
- Removes passwordless authentication methods
Set-SMSasDefaultAuthentication Function
Section titled “Set-SMSasDefaultAuthentication Function”Purpose: Configure SMS as default secondary authentication method
Features:
- Updates user sign-in preferences via Graph API
- Automatically adds phone number if not present
- Handles authentication method conflicts
Implementation Script
Section titled “Implementation Script”<#ChristieC@M365x95969042.OnMicrosoft.com#>
$GroupID = "xxx"$CSVPath = "$HOME\Desktop\Users.csv"$TenantId = "xxx.onmicrosoft.com"
function ConvertTo-PsObject { param ( [hashtable] $Value )
foreach ( $key in $Value.Keys | Where-Object { $Value[$_].GetType() -eq @{}.GetType() } ) { $Value[$key] = ConvertTo-PsObject $Value[$key] }
New-Object PSObject -Property $Value | Write-Output}
function Reset-UserSecurityInfo { [CmdletBinding()] param ( [Parameter(Mandatory=$true)] [Microsoft.Graph.PowerShell.Models.MicrosoftGraphUser]$User, [Parameter(Mandatory=$true)] [String]$PhoneNumber )
Revoke-MgUserSignInSession -UserId $($User.Id) | Out-Null $AuthenticationMethod = Get-MgUserAuthenticationMethod -UserId $($User.Id) switch ($($AuthenticationMethod.Id)) { "3ddfcfc8-9383-446f-83cc-3ab9be4be18f" { Remove-MgUserAuthenticationEmailMethod -UserId $($User.Id) -EmailAuthenticationMethodId "3ddfcfc8-9383-446f-83cc-3ab9be4be18f" Write-Output "Removing $($User.UserPrincipalName) Email Authentication Method" } "3179e48a-750b-4051-897c-87b9720928f7" { Update-MgUserAuthenticationPhoneMethod -UserId $($User.Id) -PhoneAuthenticationMethodId "3179e48a-750b-4051-897c-87b9720928f7" -PhoneNumber $PhoneNumber Write-Output "Updating $($User.UserPrincipalName) Phone to $PhoneNumber" } "28c10230-6103-485e-b985-444c60001490" { $TempPass = Reset-MgUserAuthenticationMethodPassword -UserId $($User.Id) -AuthenticationMethodId "28c10230-6103-485e-b985-444c60001490" Write-Output "Reseting $($User.UserPrincipalName) Password" } } $AuthenticationMethod | Where-Object {$_.AdditionalProperties.'@odata.type' -eq "#microsoft.graph.microsoftAuthenticatorAuthenticationMethod"} | ForEach-Object {
Remove-MgUserAuthenticationMicrosoftAuthenticatorMethod -UserId $($User.Id) -MicrosoftAuthenticatorAuthenticationMethodId $($_.Id) Write-Output "Removing $($User.UserPrincipalName) Microsoft Authenticator $($_.AdditionalProperties.displayName)" } $AuthenticationMethod | Where-Object {$_.AdditionalProperties.'@odata.type' -eq "#microsoft.graph.softwareOathAuthenticationMethod"} | ForEach-Object {
Remove-MgUserAuthenticationSoftwareOathMethod -UserId $($User.Id) -SoftwareOathAuthenticationMethodId $($_.Id) Write-Output "Removing $($User.UserPrincipalName) OTP" } $Passwordless = Get-MgBetaUserAuthenticationPasswordlessMicrosoftAuthenticatorMethod -UserId $($User.Id) if($Passwordless){ Remove-MgBetaUserAuthenticationPasswordlessMicrosoftAuthenticatorMethod -PasswordlessMicrosoftAuthenticatorAuthenticationMethodId $($Passwordless.Id) -UserId $($User.Id) Write-Output "Removing $($User.UserPrincipalName) Passwordless" } $script:UserTempPass = $($TempPass.NewPassword)}
function Set-SMSasDefaultAuthentication { param ( [Parameter(Mandatory=$true)] [String]$UserId, [Parameter(Mandatory=$true)] [String]$PhoneNumber ) try { $url = "https://graph.microsoft.com/beta/users/$UserId/authentication/signInPreferences" $body = ConvertTo-Json -InputObject @{'userPreferredMethodForSecondaryAuthentication' = 'sms'} Invoke-MgGraphRequest -Method Patch -Uri $url -Body $body -ErrorAction Stop } catch { Write-Output "Add Phone $PhoneNumber" New-MgUserAuthenticationPhoneMethod -UserId $UserId -PhoneNumber $PhoneNumber Start-Sleep 5 Invoke-MgGraphRequest -Method Patch -Uri $url -Body $body }}
Connect-MgGraph -TenantId $TenantId -Scopes "UserAuthenticationMethod.ReadWrite","Directory.ReadWrite.All","Group.ReadWrite.All","GroupMember.ReadWrite.All","User.ReadWrite.All","UserAuthenticationMethod.ReadWrite.All"$GroupMembers = Get-MgGroupMemberAsUser -GroupId $GroupID$CSV = Import-Csv -Path $CSVPath$output = @()foreach ($csvUser in $CSV) { if($($csvUser.UPN) -notin $($GroupMembers.UserPrincipalName)){ try { $MGUser = Get-MgUser -UserId $($csvUser.UPN) Set-SMSasDefaultAuthentication -UserId $($MGUser.Id) -PhoneNumber $($csvUser.Phone) $script:UserTempPass = $null Reset-UserSecurityInfo -User $MGUser -PhoneNumber $($csvUser.Phone) -ErrorAction Stop New-MgGroupMember -GroupId $GroupID -DirectoryObjectId $($MGUser.Id) $output += @{ UPN = $($csvUser.UPN); TempPass = $script:UserTempPass } } catch { Write-Output "Failed to Reset User Security Information. Error: $($_.Exception.Message)" return } } else { Write-Output "$($csvUser.UPN) In Group no change has been made" }}$d = Get-Date$d=$d.ToString('yyyy-MM-dd-HHmmss')#ConvertTo-PsObject -Value $output | Export-Csv -NoTypeInformation -Path "$HOME\Desktop\UsersTempPassword_$d.csv"#Write-Output "Exporting password file to $HOME\Desktop\UsersTempPassword_$d.csv"Execution Process
Section titled “Execution Process”1. Authentication and Setup
Section titled “1. Authentication and Setup”- Connects to Microsoft Graph with required permissions
- Retrieves current group membership
- Imports user data from CSV file
2. User Processing Loop
Section titled “2. User Processing Loop”For each user in CSV:
- Checks if user is already in target group
- Retrieves user object from Microsoft Graph
- Sets SMS as default authentication method
- Resets all existing authentication methods
- Adds user to specified group
- Records temporary password (if generated)
3. Reporting and Export
Section titled “3. Reporting and Export”- Compiles results into output array
- Generates timestamped CSV export
- Provides detailed logging throughout process
CSV File Format
Section titled “CSV File Format”Required columns:
- UPN: User Principal Name (email address)
- Phone: Phone number for SMS authentication
Example format:
UPN,Phoneuser1@company.com,+1234567890user2@company.com,+0987654321Required Permissions
Section titled “Required Permissions”The script requires the following Microsoft Graph permissions:
- UserAuthenticationMethod.ReadWrite
- Directory.ReadWrite.All
- Group.ReadWrite.All
- GroupMember.ReadWrite.All
- User.ReadWrite.All
Conclusion
Section titled “Conclusion”Key Takeaway: This script provides a comprehensive solution for resetting user authentication methods and managing group membership through Microsoft Graph API. It ensures consistent security policies across your organization while maintaining detailed audit trails and reporting capabilities.
Ideal for: Organizations implementing standardized authentication methods or performing bulk user security resets.
<#
ChristieC@M365x95969042.OnMicrosoft.com #>
$GroupID = “xxx” $CSVPath = “$HOME\Desktop\Users.csv” $TenantId = “xxx.onmicrosoft.com”
function ConvertTo-PsObject { param ( [hashtable] $Value )
foreach ( $key in $Value.Keys | Where-Object { $Value[$_].GetType() -eq @{}.GetType() } ) { $Value[$key] = ConvertTo-PsObject $Value[$key] }
New-Object PSObject -Property $Value | Write-Output } function Reset-UserSecurityInfo { [CmdletBinding()] param ( [Parameter(Mandatory=$true)] [Microsoft.Graph.PowerShell.Models.MicrosoftGraphUser]$User, [Parameter(Mandatory=$true)] [String]$PhoneNumber )
Revoke-MgUserSignInSession -UserId $($User.Id) | Out-Null $AuthenticationMethod = Get-MgUserAuthenticationMethod -UserId $($User.Id) switch ($($AuthenticationMethod.Id)) { “3ddfcfc8-9383-446f-83cc-3ab9be4be18f” { Remove-MgUserAuthenticationEmailMethod -UserId $($User.Id) -EmailAuthenticationMethodId “3ddfcfc8-9383-446f-83cc-3ab9be4be18f” Write-Output “Removing $($User.UserPrincipalName) Email Authentication Method” } “3179e48a-750b-4051-897c-87b9720928f7” { Update-MgUserAuthenticationPhoneMethod -UserId $($User.Id) -PhoneAuthenticationMethodId “3179e48a-750b-4051-897c-87b9720928f7” -PhoneNumber $PhoneNumber Write-Output “Updating $($User.UserPrincipalName) Phone to $PhoneNumber” } “28c10230-6103-485e-b985-444c60001490” { $TempPass = Reset-MgUserAuthenticationMethodPassword -UserId $($User.Id) -AuthenticationMethodId “28c10230-6103-485e-b985-444c60001490” Write-Output “Reseting $($User.UserPrincipalName) Password” } } $AuthenticationMethod | Where-Object {$_.AdditionalProperties.’@odata.type’ -eq “#microsoft.graph.microsoftAuthenticatorAuthenticationMethod”} | ForEach-Object {
Remove-MgUserAuthenticationMicrosoftAuthenticatorMethod -UserId $($User.Id) -MicrosoftAuthenticatorAuthenticationMethodId $($.Id) Write-Output “Removing $($User.UserPrincipalName) Microsoft Authenticator $($.AdditionalProperties.displayName)” } $AuthenticationMethod | Where-Object {$_.AdditionalProperties.’@odata.type’ -eq “#microsoft.graph.softwareOathAuthenticationMethod”} | ForEach-Object {
Remove-MgUserAuthenticationSoftwareOathMethod -UserId $($User.Id) -SoftwareOathAuthenticationMethodId $($_.Id) Write-Output “Removing $($User.UserPrincipalName) OTP” } $Passwordless = Get-MgBetaUserAuthenticationPasswordlessMicrosoftAuthenticatorMethod -UserId $($User.Id) if($Passwordless){ Remove-MgBetaUserAuthenticationPasswordlessMicrosoftAuthenticatorMethod -PasswordlessMicrosoftAuthenticatorAuthenticationMethodId $($Passwordless.Id) -UserId $($User.Id) Write-Output “Removing $($User.UserPrincipalName) Passwordless” } $script:UserTempPass = $($TempPass.NewPassword) } function Set-SMSasDefaultAuthentication { param ( [Parameter(Mandatory=$true)] [String]$UserId, [Parameter(Mandatory=$true)] [String]$PhoneNumber ) try { $url = “https://graph.microsoft.com/beta/users/$UserId/authentication/signInPreferences” $body = ConvertTo-Json -InputObject @{‘userPreferredMethodForSecondaryAuthentication’ = ‘sms’} Invoke-MgGraphRequest -Method Patch -Uri $url -Body $body -ErrorAction Stop } catch { Write-Output “Add Phone $PhoneNumber” New-MgUserAuthenticationPhoneMethod -UserId $UserId -PhoneNumber $PhoneNumber Start-Sleep 5 Invoke-MgGraphRequest -Method Patch -Uri $url -Body $body } }
Connect-MgGraph -TenantId $TenantId -Scopes “UserAuthenticationMethod.ReadWrite”,“Directory.ReadWrite.All”,“Group.ReadWrite.All”,“GroupMember.ReadWrite.All”,“User.ReadWrite.All”,“UserAuthenticationMethod.ReadWrite.All” $GroupMembers = Get-MgGroupMemberAsUser -GroupId $GroupID $CSV = Import-Csv -Path $CSVPath $output = @() foreach ($csvUser in $CSV) { if($($csvUser.UPN) -notin $($GroupMembers.UserPrincipalName)){ try { $MGUser = Get-MgUser -UserId $($csvUser.UPN) Set-SMSasDefaultAuthentication -UserId $($MGUser.Id) -PhoneNumber $($csvUser.Phone) $script:UserTempPass = $null Reset-UserSecurityInfo -User $MGUser -PhoneNumber $($csvUser.Phone) -ErrorAction Stop New-MgGroupMember -GroupId $GroupID -DirectoryObjectId $($MGUser.Id) $output += @{ UPN = $($csvUser.UPN); TempPass = $script:UserTempPass } } catch { Write-Output “Failed to Reset User Security Information. Error: $($.Exception.Message)” return } } else { Write-Output ”$($csvUser.UPN) In Group no change has been made” } } $d = Get-Date $d=$d.ToString(‘yyyy-MM-dd-HHmmss’) #ConvertTo-PsObject -Value $output | Export-Csv -NoTypeInformation -Path “$HOME\Desktop\UsersTempPassword$d.csv” #Write-Output “Exporting password file to $HOME\Desktop\UsersTempPassword_$d.csv”