Reset Microsoft Authentication Methods



Normally, it isn't much effort to Reset the Multifactor Authentication Methods.
Find the User record in Entra ID and require re-registration of the Multifactor Authentication Methods.




If you wondering why we need to reset these authentication methods

What are the Reasons for an Reset ?

  • Device Change
  • Lost or Stolen Device
  • Failed Authentication
  • Phone Number Change
  • Issues with the Authentication App
  • Security Reasons
 

But what if you have a big amount of Tickets a day and it takes time to always login into Azure, grab your PIM Roles and reset the Multifactor. And this for 20 or 30 times a day. Then also give the User a Information you have reseted his Multifactor.
I would say it is a time wasting machine.
So better use a little bit of your time to automate this process. 
I have written a Script that is resetting the MFA Methods.
You will find it below and in my Github Repository.
Also you will find the used Function for sending Mails in the Reset-MFA Script. Make sure you have all needed Permissions.

Github : MFA-Reset : Reset-MFA
Github : Send Mail : Send-GraphMail
Microsoft Documentation : Authentication Methods
There are one thing what have caused error realy often. 

You can't delete the Primary authentication Method first. You need to delete it at the end. Otherwise you will get an Error 😦

This was quite tricky because the default authentication method could not be obtained with the Graph API on the v1.0 Endpoint. You have to catch this explicit error and retry the deletion at the end.
But i was never realy happy with that solution.

After further investigation, I found that the default method could be obtained at the beta Endpoint.

The signInPreferences Endpoint
/beta/users/$($AzureADUser.userPrincipalName)/authentication/signInPreferences

As Result we get back our authentication method as "userPreferredMethodForSecondaryAuthentication"

Now, we only have to adapt and sort our script a bit, and the script is ready to reset MFA without troubles.

As a benefit, you will also get a cool HTML Wrapper for User Information that will be sent by Mail. You have seen it already in the header.
But you're probably wondering how the end users can request the reset themselves?

There are already some automation Engines out in the wild. 

One that I can recommend is au2mator. With this automation Software, you are able to automate all imaginable. You have configureable Question frontend and you are able to use Azure Automation or PowerShell as automation Engine.

Code :
here you will see only the Reset-MFA Code. For the full Script got to GitHub.

Be aware that the Script isn't perfect because it is still under construction. But i'm open for suggestions and improvements.

Param
(
    [Parameter (Mandatory = $false)]
    [String]$Userprincipalname = "AdeleV@contoso.onmicrosoft.com"
)

$ErrorActionPreference = "stop"



function Get-AccessToken {

    [CmdletBinding()]
    param (
        # The Microsoft Azure AD Tenant Name
        [Parameter(ParameterSetName = 'ClientAuth', Mandatory = $true)]  [string]$TenantName,
        # The Microsoft Azure AD TenantId (GUID or domain)
        [Parameter(ParameterSetName = 'ClientAuth', Mandatory = $true)]  [string]$ClientId,
        # An authentication secret of the Microsoft Azure AD Application Registration
        [Parameter(ParameterSetName = 'ClientAuth', Mandatory = $true)] [string]$ClientSecret
    )
    

    $resource = "https://graph.microsoft.com/"  
    
    $tokenBody = @{  
        Grant_Type    = 'client_credentials'  
        Scope         = 'https://graph.microsoft.com/.default'  
        Client_Id     = $ClientId  
        Client_Secret = $clientSecret  
    }  
    
    try { $tokenResponse = Invoke-RestMethod -Uri "https://login.microsoftonline.com/$TenantName/oauth2/v2.0/token" -Method POST -Body $tokenBody -ErrorAction Stop }catch { return "Error generating access token $($_)" }
    Write-Debug "Successfully generated authentication token"
    return $($tokenResponse.access_token)
}



#endregion

#//----------------------------------------------------------------------------
#//  Main routines
#//----------------------------------------------------------------------------

Try {


    $tenantName = "<TenantName>"
    $clientId = "<ClientID>"
    $clientSecret = "<ClientSecret>"
    $token = Get-AccessToken -TenantName $tenantName -ClientId $clientId -ClientSecret $clientSecret
    



    $headers = @{
        "Authorization" = "Bearer $($token)"
        "Content-type"  = "application/json"
        "Accept"        = "application/json"
    }

    Write-Output "Verifying user against Azure AD with Graph API";
    
    $filterurl = "https://graph.microsoft.com/v1.0/users?`$filter=userprincipalname eq '$($Userprincipalname)'&`$select=onPremisesDistinguishedName,userprincipalname,id,Mail,givenname,surname,displayname"
    $AzureADUser = (Invoke-RestMethod -Method Get -Uri $filterurl -Headers $headers).Value
    



    if ($AzureADUser.count -gt 1) {
        Throw "Found more than 1 User"
    }


    #Get Signin Preferences
    $signinpreferencesurl = "https://graph.microsoft.com/beta/users/$($AzureADUser.userPrincipalName)/authentication/signInPreferences"
    $signinpreferences = Invoke-RestMethod -Method Get -Uri $signinpreferencesurl -Headers $headers
    $userPreferredMethodForSecondaryAuthentication = $null
    $userPreferredMethodForSecondaryAuthentication = $signinpreferences.userPreferredMethodForSecondaryAuthentication
    
    #userprefferedtypes = 'push','oath','voiceMobile','voiceAlternateMobile','voiceOffice','sms'

    #Get MFA Methods
    $URIMFAMETHODS = "https://graph.microsoft.com/v1.0/users/$($AzureADUser.userPrincipalName)/authentication/methods"
    $Method2Delete = $null
    $Method2Delete = (Invoke-RestMethod -Method Get -Uri $URIMFAMETHODS -Headers $headers).Value
    $Method2Delete | Add-member -MemberType NoteProperty -Name "defaultsigninmethod" -Value $false
            
    if (!([string]::IsNullOrEmpty($userPreferredMethodForSecondaryAuthentication))) {
        #If user has a preferred method for secondary authentication

        Write-Output "User Preferred Method For Secondary Authentication is : $($userPreferredMethodForSecondaryAuthentication)"

        foreach ($method in $Method2Delete) {

            switch ($userPreferredMethodForSecondaryAuthentication) {
                "push" { 
                    if ($method.'@odata.type'.replace("#", "") -eq "microsoft.graph.microsoftAuthenticatorAuthenticationMethod") {
                        $method.defaultsigninmethod = $true
                        Write-Output "Default sign in method is Push"
                    }
                }
                "oath" { 
                    if ($method.'@odata.type'.replace("#", "") -eq "microsoft.graph.softwareOathAuthenticationMethod") {
                        $method.defaultsigninmethod = $true
                        Write-Output "Default sign in method is Oath"
                    }
                }
                "voiceMobile" { 
                    if ($method.'@odata.type'.replace("#", "") -eq "microsoft.graph.phoneAuthenticationMethod") {
                        $method.defaultsigninmethod = $true
                        Write-Output "Default sign in method is VoiceMobile"
                    }  
                }
                "voiceAlternateMobile" { 
                    if ($method.'@odata.type'.replace("#", "") -eq "microsoft.graph.phoneAuthenticationMethod") {
                        $method.defaultsigninmethod = $true
                        Write-Output "Default sign in method is VoiceAlternateMobile"
                    }
                }
                "voiceOffice" { 
                    if ($method.'@odata.type'.replace("#", "") -eq "microsoft.graph.phoneAuthenticationMethod") {
                        $method.defaultsigninmethod = $true
                        Write-Output "Default sign in method is VoiceOffice"
                    }
                }
                "sms" {
                    if ($method.'@odata.type'.replace("#", "") -eq "microsoft.graph.phoneAuthenticationMethod") {
                        $method.defaultsigninmethod = $true
                        Write-Output "Default sign in method is SMS"
                    }
                            
                }
            }
        }   
                
    }
    else {
        Write-Output "User has no preferred method for secondary authentication"
    }


    $Method2Delete = $Method2Delete | Sort-Object -Property defaultsigninmethod


    $defaulturl = $null
    foreach ($method in $Method2Delete) {

        Write-Output "Try to delete Method $($method)";

        $methodType = $null
        $methodTypes = $method.'@odata.type'.replace("#", "")

        switch ($methodTypes) {
            "microsoft.graph.phoneAuthenticationMethod" { 
                #"Phone"
                $methodType = "phoneMethods"
            }
            "microsoft.graph.microsoftAuthenticatorAuthenticationMethod" { 
                #"AUTH"
                $methodtype = "microsoftAuthenticatorMethods"
            }
            "microsoft.graph.temporaryAccessPassAuthenticationMethod" { 
                #"AUTH"
                $methodtype = "temporaryAccessPassMethods"
            }
            "microsoft.graph.windowsHelloForBusinessAuthenticationMethod" { 
                #"AUTH"
                $methodtype = "windowsHelloForBusinessMethods"
            }
            "microsoft.graph.emailAuthenticationMethod" { 
                #"AUTH"
                $methodtype = "emailMethods"
            }
            "microsoft.graph.passwordAuthenticationMethod" { 
                #"AUTH"
                $methodtype = "passwordMethods"
            }
            "microsoft.graph.softwareOathAuthenticationMethod" { 
                #"AUTH"
                $methodtype = "softwareOathMethods"
            }
            "microsoft.graph.fido2AuthenticationMethod" { 
                #"AUTH"
                $methodtype = "fido2Methods"
            }
        }


        if ([string]$methodType -ne "passwordMethods") {

            $deleteurl = "https://graph.microsoft.com/v1.0/users/$($AzureADUser.userprincipalname)/authentication/$($methodType)/$($method.id)"
    
            try {
                Write-Output "URI for deletion is : $($deleteurl)"; 
                Invoke-RestMethod -Method Delete -Uri $deleteurl -Headers $headers
                Write-Output "Mehtod was deleted : $($methodType)";
            }
            catch {
             
                [array]$errormessage += $_
                Write-Error $errormessage
            }

        }

    }


    [array]$AuthMethods = (Invoke-RestMethod -Method Get -Uri $URIMFAMETHODS -Headers $headers).Value

    
    if ($AuthMethods.count -eq 1) {
    
        Write-Output "All MFA methods have been deleted";
        Write-Output "MFA settings has been removed for account $($AzureADUser.UserPrincipalName)";

    }
    else {
        Write-Output "Following Methods are not deleted : $($AuthMethods.'@odata.type')";
         }       
    


}
Catch {
    $ErrorMessage = $_.Exception.Message + "`nAt Line number: $($_.InvocationInfo.ScriptLineNumber)"
    Write-Error -Message $ErrorMessage
}

—————————–
Thank you for Reading

&

Happy Automating
——————————

Leave a comment