Scripting in authentication methods for MFA

By | April 9, 2021

It appears that the method for scripting in phone authentication methods using the AzureAD powershell module (as detailed at https://docs.microsoft.com/en-us/azure/active-directory/authentication/howto-sspr-authenticationdata#set-and-read-the-authentication-data-through-powershell) no longer functions – it adds the phone numbe in AAD but does not set it as an authentication method.

There is a note on the article:

which basically seems to indicate that going forward graph is going to be the preferred (only!?) method supported. So how to do this.

I’m assuming you know how to use Graph Explorer or Postman to query graph

1 – List Current Methods

This is straightforward, just run the GET: https://graph.microsoft.com/beta/users/kirkj@starfleet.com/authentication/phoneMethods/

This will return for example:

{
    "@odata.context": "https://graph.microsoft.com/beta/$metadata#users('kirkj@starfleet.com')/authentication/phoneMethods",
    "value": [
        {
            "id": "3179e48a-750b-4051-897c-87b9720928f7",
            "phoneNumber": "+44 7472689147",
            "phoneType": "mobile",
            "smsSignInState": "notAllowedByPolicy"
        }
   

Here the user has one phone type regiostered for auth – auth a moibile. The id is static for phone type across all users and tenants. You can have mobile, alternatemobile and office numbers.

If there are no type set you will get no value returned:

{
    "@odata.context": "https://graph.microsoft.com/beta/$metadata#users('janewayk@starfleet.com')/authentication/phoneMethods",
    "value": []
}

2 – Add a new method

The main use I have for this is to onboard a large number of users to mfa and sidestep the 15,000 helpdesk calls all say “I have logged in and it says I need to provide more information, should I follow the obvious prompts or screen or set fire to my shoes, I’m unsure?”

So we need to add in new numbers. This is pretty easy, Ill show it using the user above with no registered methods, we just need to run a POST with some JSON:

URL: https://graph.microsoft.com/beta/users/janewayk@starfleet.com/authentication/phoneMethods

BODY

{
    "phoneNumber": "+44 1234567890",
    "phoneType": "mobile"
}

This will return:

    "@odata.context": "https://graph.microsoft.com/beta/$metadata#users('janewayk@starfleet.com')/authentication/phoneMethods/$entity",
    "id": "3179e48a-750b-4051-897c-87b9720928f7",
    "phoneNumber": "+44 1234567890",
    "phoneType": "mobile",
    "smsSignInState": "notAllowedByPolicy"
}

Now the phone number has been added as an MFA token. Yay!

3 – Multiple Users – Powershell Graph Module

Okay so now we can add an MFA token to a single user account using a method that is only 5 or 6 times more work than doing it direct in the azure AD portal.

What we need is to be able to do this in a foreach loop with a provided list.

Generally for scripting I use an application to connect to graph and a certificate I keep on my management device but for stuff like this you probably want to be able to run it as your admin user account. (I actually recommend using the application method which I have used throughout this boog – you will need to add two new api permissions to your AAD application if you go that way UserAuthenticationMethod.Read.All and UserAuthenticationMethod.ReadWrite.All)

For this we have a new(ish) graph module that you will need to install:

Install-Module -Name Microsoft.Graph

This module provides cmdlets to all/most/some of the Graph API commands.

Once it is installed you can connect to graph as your user account using the device login mechanism, note that we are requesting a token with two additional scopes:

NOTE: You MUST use the Windows Powershell app NOT Powershell ISE or it wont work, I cant figure out why but ISE doesnt print the code to screen

PS C:\Users\matt> connect-graph -Scopes @("UserAuthenticationMethod.Read.All";"UserAuthenticationMethod.ReadWrite.All")

You will receive the response:

To sign in, use a web browser to open the page https://microsoft.com/devicelogin and enter the code XC32F1UYT to authenticate.

Do as it says and run through the device authentication, admin account login and consent to the scoped in a browser then you’ll get:

Welcome To Microsoft Graph!

We now have a token for graph with our admin account permissions

(HINT: If like me you do everything in Powershell ISE you can now switch back to ISE under the same windows user and run “Connect-Graph” and it will connect under the same session with the same scopes)

The graph module cmdlets we are interested in here are :

Get-MgUserAuthenticationPhoneMethod
and
New-MgUserAuthenticationPhoneMethod

The very first thing we need to do is remember that that the graph user authentication endpoints are in beta and the module targets v1.0 so we need to switch the module to user the Beta endpoints:

Select-MgProfile -Name Beta

Now we can run the Get-MgUserAuthenticationMethod and see the registered methods for our test user:

PS C:\Users\jmatt> Get-MgUserAuthenticationPhoneMethod -UserId janewayk@starfleet.com | fl *



Id                   : 3179e48a-750b-4051-897c-87b9720928f7
PhoneNumber          : +44 1234567890
PhoneType            : mobile
SmsSignInState       : notAllowedByPolicy
AdditionalProperties : {}

We can see the password authentication method which everyone should have and the phone authentication method I added via graph in section 2 above. Ill take that out in the portal just for testing, so now we get:

PS C:\Users\jmatt> Get-MgUserAuthenticationPhoneMethod -UserId janewayk@starfleet.com | fl *

Now we can read the authentication methods we need to also add new ones. Lets add a new number:

PS C:\Users\jmatt> New-MgUserAuthenticationPhoneMethod -UserId janewayk@starfleet.com -phoneType "mobile" -phoneNumber "+44 01234567890"

Id                                   PhoneNumber    PhoneType SmsSignInState    
--                                   -----------    --------- --------------    
3179e48a-750b-4051-897c-87b9720928f7 +44 7593358736 mobile    notAllowedByPolicy

So now we are back to being able to add a single method, we can build out a script to bulk update from a csv…

My CSV file looks like this:

So my script to import, check for existing number and add if there isnt one is:

# install-module Microsoft.Graph
# Select-MgProfile -Name Beta
# Graph Module required and Connect Graph must be run from a Windows Powershell window, can then be run again from Powershell ISE
# connect-graph -Scopes @("UserAuthenticationMethod.Read.All";"UserAuthenticationMethod.ReadWrite.All")

$Users = Import-CSV ./MFAImport.csv
$i=0
ForEach ($user in $users) {
    $i++
    Write-Host "Working on User" $i "of" $users.Count "-" $user.UserPrincipalName -ForegroundColor Yellow
    Write-Host "Setting Number" $user.Mobile -ForegroundColor DarkYellow

    $currentmobile = (Get-MgUserAuthenticationPhoneMethod -UserId $user.UserPrincipalName |where {$_.PhoneType -eq "mobile"}).PhoneNumber
    If ($currentmobile) {
        If ($currentmobile -eq $user.Mobile) {
            Write-Host "Number already matches - No action taken" -ForegroundColor Red
        }
        If ($currentmobile -ne $user.Mobile) {
            Write-Host "Different number is already populated - No action taken" -ForegroundColor Red
        }
    }
    If (!$currentmobile) {
        $void = New-MgUserAuthenticationPhoneMethod -UserId $user.UserPrincipalName -phoneType "mobile" -phoneNumber $user.Mobile
        Write-Host "No current mobile number - populated with" $user.Mobile -ForegroundColor Green
    }
}

Loading

4 thoughts on “Scripting in authentication methods for MFA

  1. Bamba Seye

    Hello Matt,
    Thanks for th post.
    I am looking for a way to define the default method for MFA.
    Thanks.

    Reply
  2. awalker

    Thanks for the blog. wish i could get this working. I keep getting “could not interpret numbers after plus-sign” but if I take out the country code and try to add it as part of string it complains it’s not a valid number.

    any thoughts appreciated.

    Reply
    1. jmattmacd Post author

      Are you seeing this while running the graph command or when using the powershell module? can you reply with the script you are running and/or the csv (obviously change the last 3-4 digits of the numbers and any real user data 🙂 )

      Reply

Leave a Reply

Your email address will not be published. Required fields are marked *