How to Assign and Manage Telephone Numbers in Microsoft Teams Using PowerShell Set-CsPhoneNumberAssignment

In modern enterprise unified communications architectures powered by Microsoft Teams Phone, assigning telephone numbers to users, call queues, auto attendants, and shared common area phones is a core administrative task. Historically, administrators assigned phone numbers using legacy Skype for Business cmdlets such as Set-CsUser -OnPremLineURI. However, Microsoft has completely modernized telephone number lifecycle management, introducing the dedicated Set-CsPhoneNumberAssignment, Get-CsPhoneNumberAssignment, and Remove-CsPhoneNumberAssignment cmdlets in the Microsoft Teams PowerShell module.

This modernized framework provides a unified interface across all three primary telephone connectivity models: Microsoft Calling Plans, Operator Connect, and Direct Routing (SBC). In addition to assigning telephone numbers and extension formats (E.164), Set-CsPhoneNumberAssignment binds emergency location identifiers directly to the user’s phone identity, ensuring regulatory compliance with dynamic emergency calling laws. This guide covers how to query available phone numbers, assign telephone numbers with extensions, bind emergency civic locations, and automate batch provisioning via PowerShell.

Understanding Modern Phone Number Assignment Types

The Set-CsPhoneNumberAssignment cmdlet supports all three primary PSTN connectivity architectures available in Microsoft Teams Phone:

  • CallingPlan: Telephone numbers purchased directly from Microsoft or ported into Microsoft 365. The telephony infrastructure and PSTN breakout are managed entirely in the cloud by Microsoft.
  • OperatorConnect: Numbers provided and provisioned by certified telecommunications carriers via the Operator Connect partner program, managed through Microsoft cloud APIs.
  • DirectRouting: Enterprise-managed numbers routed through on-premises or cloud-hosted Session Border Controllers (SBCs) connected to custom SIP trunks.

Regardless of the connectivity type, all telephone numbers must be formatted according to the international ITU-T E.164 standard (e.g., +442079460123), optionally followed by an extension parameter (e.g., ;ext=104).

Connecting to Teams PowerShell and Auditing Current Numbers

To administer telephone numbers, launch an elevated PowerShell console and authenticate with Microsoft 365 tenant credentials having the Teams Administrator role:

# Import the Teams PowerShell module and authenticate
Import-Module MicrosoftTeams
Connect-MicrosoftTeams

Before assigning a number to a user, inspect all unassigned or available phone numbers configured within your tenant using Get-CsPhoneNumberAssignment:

# List available unassigned numbers in the tenant
Get-CsPhoneNumberAssignment -ActivationState Activated -Capabilities PhoneCall | 
    Where-Object { -not $_.AssignedPstnTargetId } | 
    Select-Object TelephoneNumber, NumberType, City

To inspect the telephone number currently assigned to a specific user:

# Query telephone number assignment for a specific user
Get-CsPhoneNumberAssignment -AssignedPstnTargetId "[email protected]"

Assigning a Direct Routing Phone Number

When provisioning a telephone number routed through your enterprise SBC (Direct Routing), specify the user’s User Principal Name (UPN), the E.164 phone number, and declare the -PhoneNumberType DirectRouting parameter:

# Assign a Direct Routing phone number to a user
Set-CsPhoneNumberAssignment -Identity "[email protected]" `
    -PhoneNumber "+442079460123" `
    -PhoneNumberType DirectRouting

To assign a phone number that includes an internal extension for three-digit or four-digit branch dialing:

# Assign a phone number with an internal extension
Set-CsPhoneNumberAssignment -Identity "[email protected]" `
    -PhoneNumber "+442079460123;ext=104" `
    -PhoneNumberType DirectRouting

Assigning Calling Plan or Operator Connect Numbers with Emergency Locations

For Calling Plan and Operator Connect telephone numbers, telecommunications regulations (such as Kari’s Law and RAY BAUM’S Act in the United States, as well as European emergency routing directives) mandate that every assigned geographic phone number must be associated with a verified emergency civic address.

First, retrieve the unique LocationId of the verified office location:

# Retrieve verified emergency location identifiers
Get-CsOnlineLisCivicAddress | Select-Object CivicAddressId, Description, City, PostCode

Then, assign the telephone number alongside the mandatory -LocationId parameter:

# Assign Calling Plan number with validated emergency location
Set-CsPhoneNumberAssignment -Identity "[email protected]" `
    -PhoneNumber "+442079460125" `
    -PhoneNumberType CallingPlan `
    -LocationId "a1b2c3d4-e5f6-7890-abcd-ef1234567890"

Updating or Reassigning Emergency Locations for Active Users

When an employee relocates to a different office branch or floor, their assigned emergency address must be updated without unassigning their existing phone number. Pass the new LocationId to Set-CsPhoneNumberAssignment:

# Update emergency location for an existing assigned phone number
Set-CsPhoneNumberAssignment -Identity "[email protected]" `
    -PhoneNumber "+442079460125" `
    -PhoneNumberType CallingPlan `
    -LocationId "b2c3d4e5-f6a7-8901-bcde-f12345678901"

Unassigning Phone Numbers from Deprovisioned Users

When an employee leaves the organization or transitions away from a telephony-enabled role, release the telephone number back to the tenant pool using Remove-CsPhoneNumberAssignment:

# Unassign telephone number and return it to the available pool
Remove-CsPhoneNumberAssignment -Identity "[email protected]" `
    -PhoneNumber "+442079460123" `
    -PhoneNumberType DirectRouting

Automating Bulk Phone Number Provisioning via CSV

In large enterprise deployments, manual single-user provisioning is inefficient. Automate the onboarding workflow by importing a structured CSV file containing user email addresses, telephone numbers, number types, and optional location IDs:

# Import CSV containing onboarding telephony batch
$Assignments = Import-Csv -Path "C:\Deploy\TeamsPhoneAssignments.csv"

foreach ($Entry in $Assignments) {
    Write-Host "Assigning $($Entry.PhoneNumber) to $($Entry.UserPrincipalName)..." -ForegroundColor Cyan
    try {
        $Params = @{
            Identity        = $Entry.UserPrincipalName
            PhoneNumber     = $Entry.PhoneNumber
            PhoneNumberType = $Entry.PhoneNumberType
            ErrorAction     = "Stop"
        }
        if ($Entry.LocationId) {
            $Params.LocationId = $Entry.LocationId
        }

        Set-CsPhoneNumberAssignment @Params
        Write-Host "Successfully assigned $($Entry.PhoneNumber)" -ForegroundColor Green
    }
    catch {
        Write-Warning "Failed to assign $($Entry.PhoneNumber) to $($Entry.UserPrincipalName): $_"
    }
}

Troubleshooting Common Phone Number Assignment Errors

When administering Teams Phone assignments, watch out for these common issues:

  • Missing Teams Phone Standard License: Attempting to assign a telephone number to a user without an active Microsoft Teams Phone Standard license will result in a UserIsNotLicensedException error. Ensure licensing is assigned in Microsoft Entra ID prior to executing the cmdlet.
  • Invalid E.164 Formatting: Numbers missing the leading international plus prefix (+) or country code (e.g., entering 02079460123 instead of +442079460123) will be rejected by validation filters.
  • Number Already Assigned: If a number is currently bound to another user or a deprovisioned resource account, Set-CsPhoneNumberAssignment will throw a conflict error. Locate the conflicting assignment using Get-CsPhoneNumberAssignment -TelephoneNumber "+442079460123" and release it with Remove-CsPhoneNumberAssignment before reassigning.
  • Direct Routing Enterprise Voice Flag: When assigning Direct Routing numbers, verify that the user’s Enterprise Voice capability is enabled. Set-CsPhoneNumberAssignment enables Enterprise Voice automatically on modern module releases, but verification can be performed using Get-CsOnlineUser -Identity $User | Select-Object EnterpriseVoiceEnabled.

Using Set-CsPhoneNumberAssignment provides a modern, standardized, and auditable methodology for administering enterprise telephone numbers across global Microsoft Teams deployments.

Get the best tech tips delivered straight to your inbox.

Join thousands of readers mastering Apple, Google, Microsoft, and Linux.