<# .SYNOPSIS Pre-registers a mobile phone number as an authentication method for Microsoft Entra ID users. .DESCRIPTION Uses the Microsoft Graph authentication methods cmdlets to add a mobile number that users can use for SMS or voice verification. Users who already have a mobile number registered are left alone unless you pass -Overwrite, because replacing someone's MFA number is effectively resetting their MFA. Takes pipeline input, so a CSV with UserPrincipalName and PhoneNumber columns works as-is. Supports -WhatIf. .PARAMETER UserPrincipalName The user to update. Accepts pipeline input by property name. .PARAMETER PhoneNumber The number in Graph's format: + , for example '+1 4345550142'. .PARAMETER Overwrite Replace an existing, different mobile number. Only do this after you've verified the user. .EXAMPLE .\Set-EntraUserMobilePhoneMethod.ps1 -UserPrincipalName jane.doe@contoso.com -PhoneNumber '+1 4345550142' .EXAMPLE Import-Csv .\new-hires.csv | .\Set-EntraUserMobilePhoneMethod.ps1 -WhatIf #> [CmdletBinding(SupportsShouldProcess)] param( [Parameter(Mandatory, ValueFromPipelineByPropertyName)] [Alias('UPN', 'UserId')] [string]$UserPrincipalName, [Parameter(Mandatory, ValueFromPipelineByPropertyName)] [Alias('Phone', 'MobilePhone')] [ValidatePattern('^\+\d{1,3} \d{4,15}$')] [string]$PhoneNumber, [switch]$Overwrite ) begin { if (-not (Get-MgContext)) { Connect-MgGraph -Scopes 'UserAuthenticationMethod.ReadWrite.All' -NoWelcome } # The mobile phone method always has this fixed ID. Alternate mobile and office use others. $mobileMethodId = '3179e48a-750b-4051-897c-87b9720928f7' } process { $result = [pscustomobject]@{ UserPrincipalName = $UserPrincipalName OldNumber = $null NewNumber = $PhoneNumber Result = $null } try { $existing = Get-MgUserAuthenticationPhoneMethod -UserId $UserPrincipalName -ErrorAction Stop | Where-Object { $_.Id -eq $mobileMethodId } } catch { $result.Result = "Failed: $($_.Exception.Message)" return $result } # Graph returns numbers in the same '+1 4345550142' shape, so compare without spaces to be safe. $normalize = { param($n) ($n -replace '\s', '') } if ($existing) { $result.OldNumber = $existing.PhoneNumber if ((& $normalize $existing.PhoneNumber) -eq (& $normalize $PhoneNumber)) { $result.Result = 'Unchanged' } elseif (-not $Overwrite) { $result.Result = 'Skipped: a different mobile number is already registered (use -Overwrite)' } elseif ($PSCmdlet.ShouldProcess($UserPrincipalName, "Replace mobile MFA number $($existing.PhoneNumber) with $PhoneNumber")) { try { Update-MgUserAuthenticationPhoneMethod -UserId $UserPrincipalName -PhoneAuthenticationMethodId $mobileMethodId -PhoneNumber $PhoneNumber -PhoneType 'mobile' -ErrorAction Stop | Out-Null $result.Result = 'Updated' } catch { $result.Result = "Failed: $($_.Exception.Message)" } } else { $result.Result = 'WhatIf' } } elseif ($PSCmdlet.ShouldProcess($UserPrincipalName, "Register $PhoneNumber as mobile MFA number")) { try { New-MgUserAuthenticationPhoneMethod -UserId $UserPrincipalName -PhoneNumber $PhoneNumber -PhoneType 'mobile' -ErrorAction Stop | Out-Null $result.Result = 'Added' } catch { $result.Result = "Failed: $($_.Exception.Message)" } } else { $result.Result = 'WhatIf' } Write-Verbose "$UserPrincipalName`: $($result.Result)" $result }