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
}
}
Hello Matt,
Thanks for th post.
I am looking for a way to define the default method for MFA.
Thanks.
Setting the default method is still listed as “not yet supported”, that “yet” at least gives us some hope.
https://docs.microsoft.com/en-us/graph/api/resources/authenticationmethods-overview?view=graph-rest-beta&preserve-view=true#:~:text=Default%20method
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.
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 🙂 )