Configuring Teams Direct Routing using an Azure-hosted Ribbon SBC

Getting up and running with Direct Routing is quick and easy thanks to Azure-hosted session border controllers from Ribbon.


What is an SBC anyway?

A session border controller (SBC) is essentially a telephony router/firewall appliance. It’s designed to allow you to connect SIP trunks, ISDN or analogue POTS to a phone system, Skype for Business, Teams or any other telephony platform that supports SIP – like a cloud contact centre.

SBC’s often allow you to have granular control over how each call is routed within your organisation, meaning that you can use an SBC to move from your existing telephony platform to Microsoft Teams at your own pace and often with zero downtime.


Hosted vs On-premises SBCs

If you already have an SBC, there’s a good chance you can use it to connect to Microsoft Teams via direct routing already. If you’re starting from scratch though, or are looking at replacing an existing SBC or are simply wanting to move as many workloads as possible to the cloud, an Azure-hosted SBC is for you.


SIP Trunks

As our SBC is going to be hosted in Azure, we can use any Internet-based SIP trunk service we like. In this example, im using Twilio, but you’re welcome to use your existing carrier, or another internet-based SIP trunking service.


Launching an SBC instance in Azure

To get up and running, you’ll need an Azure subscription. If you don’t already have one, you can sign up for free monthly Azure credit! Simply go to and sign in using your Microsoft Account.

Once you have an Azure Account:

  1. Click Create a Resource and search for Ribbon and select SBC SWe Lite Quick Launch

  2. Select an active Azure subscription, create a new resource group, and choose the region to deploy your SBC.

    Enter a Virtual Machine Name you wish to use for the SBC
    Set the required number of simultaneous calls – which will size your SBC VM accordingly.

  3. You can leave the virtual machine settings and network settings as-is.

  4. Under SBC SWe Lite Settings, set a username and password. Leave the Management terminal remote IP address as * for now (keep in mind this opens your SBC to the entire world on HTTPS).

    Set the DNS host name of the SBC, and enter the DNS domain name (e.g

  5. When ready, review and create the SBC.


Connecting to your SBC Instance

Once your SBC instance has deployed successfully:

  1. Open the SBC resource group
  2. Select Deployments then select the deployment starting with ribboncommunications

  3. Click Outputs to view the SBC management URL (to connect to your SBC’s admin interface) and the public IP address you can use for Teams Direct Routing. Make a note of this IP.

  4. Browse to the URL of your SWe Lite management address to be presented with the login screen. Enter your username and password you configured when you launched the instance.

    Note: both the Username and Password is case sensitive 


Initial SBC Config

The easiest way of configuring Direct Routing on the SBC is to use the Easy Config Wizard. You’ll find this under System.

Step 1:

Name the Scenario – Teams DR
Select the Telephone Country
Enter the number of concurrent SIP sessions

Click Next


Step 2:

Enter your SIP providers SIP trunk FQDN or IP, protocol and port information. In my example, i’m using a Twilio SIP trunk.

Enter the NAT Public IP address you took note of above from the Azure portal

Click Next to move to Step 3.

Step 3

Confirm the details and click Finish to save the config.


Configure DNS and Certificates

Direct Routing requires an SSL certificate to function.

First, we need to configure a DNS record that points towards our SBC’s NAT Public IP address. This IP is used by Office 365 for signaling/media.

For my example, I’m going to use My DNS is hosted in Azure, but you’ll need to create this DNS record wherever your DNS is hosted

Next we need to set the host name on the SBC under System > Node-Level settings > Host Name

Next we need to generate an SSL CSR. to go Tasks > Certificates and click Generate CSR

Fill out the details, and click OK

Copy the generated CSR to a notepad file. you’ll need this to generate your SSL certificate with whichever certificate provider you choose.

Once you have generated your certificate, you’ll need to import the Trusted CA Intermediate and Root certificates first under the Trusted CA tab, and then import your signed certificate under SBC Primary Certificate

You’ll also need to import the Microsoft “Baltimore CyberTrust Root” certificate on the SBC under the Trusted CA tab too, otherwise you’ll receive SIP TLS errors and the Teams Direct Routing link wont establish.

To do this:

  1. Download the Microsoft 365 Root Certificate Bundle from here: Microsoft 365 encryption chains – Microsoft 365 Compliance | Microsoft Docs
  2. Open the certificate on your PC, and export the Baltimore CyberTrust Root certificate to .cer format
  3. Import this certificate to your SBC under Trusted CAs


Configuring Office 365 to connect to your SBC

Let’s go ahead and configure Office 365 to connect to our SBC:

  1. Connect to Teams Powershell:


  2. Create a new PSTN gatway:

    Set-CsOnlinePSTNGateway -Identity -SipSignalingPort 5061 -MaxConcurrentSessions 5

Verify Connectivity

Now that we’ve configured our SBC and our PSTN Gateway in Office 365, we can verify connectivity between the SBC and Office 365.

Under Monitor on the SBC, we can see our 5 channels are enabled and green showing they’re up.

We can also see the SBC status in the Teams Admin Centre under Voice > Direct Routing

Do note that this section can take an hour or two to update, though.


Configuring Voice Settings in Teams

To be able to make a call, we’re going to need to configure PSTN UsagesVoice Routes, Dial Plans and Voice Routing Policies.

Let’s start with our PSTN usage. We’re going to create a usage for our Australian based users who will be making calls out the SBC in azure.

By the way, if you haven’t already heard to Ken Laskos amazing I highly recommend you check it out! The tool allows you to easily create Teams direct routing dial plans that you can import easily via PowerShell. A shoutout to Ken and his amazing tool for helping to put together the below regex.

In PowerShell, run:

Set-CsOnlinePstnUsage -Identity Global -Usage @{Add="Australia-USG"}

Next we’re going to create our Voice Routes.

These are our voice routes to handle our local calls, based on where the user is within Australia. These allow a user to dial a local in-state number by only dialling 8 digits, rather than the full national number.

e.g. A user can call 8123 4567 to reach +61 2 8123 4567

New-CsOnlineVoiceRoute -Identity "NSW-ACT-Local" -NumberPattern "^\+610?2([2-9]\d{7})" -OnlinePstnGatewayList -Priority 1 -OnlinePstnUsages "Australia-USG"

New-CsOnlineVoiceRoute -Identity "VIC-TAS-Local" -NumberPattern "^\+610?3([2-9]\d{7})" -OnlinePstnGatewayList -Priority 1 -OnlinePstnUsages "Australia-USG"

New-CsOnlineVoiceRoute -Identity "QLD-Local" -NumberPattern "^\+610?7([2-9]\d{7})" -OnlinePstnGatewayList -Priority 1 -OnlinePstnUsages "Australia-USG"

New-CsOnlineVoiceRoute -Identity "SA-WA-NT-Local" -NumberPattern "^\+610?8([2-9]\d{7})" -OnlinePstnGatewayList -Priority 1 -OnlinePstnUsages "Australia-USG"

Next, we’ll create national-based voice routes for all other types of calls for Australian-based users. These allow a user to call national numbers in other states, mobile numbers, 13 and 18 numbers as well as triple 0 for emergencies.

New-CsOnlineVoiceRoute -Identity "AUS-National" -NumberPattern "^\+610?[23578]\d{8}" -OnlinePstnGatewayList -Priority 2 -OnlinePstnUsages "Australia-USG"

New-CsOnlineVoiceRoute -Identity "AUS-TollFree" -NumberPattern "^\+61180(0\d{6}|\d{4})$" -OnlinePstnGatewayList -Priority 3 -OnlinePstnUsages "Australia-USG"

New-CsOnlineVoiceRoute -Identity "AUS-Mobile" -NumberPattern "^\+61([45]\d{8})$" -OnlinePstnGatewayList -Priority 4 -OnlinePstnUsages "Australia-USG"

New-CsOnlineVoiceRoute -Identity "AUS-Service" -NumberPattern "^\+?(000|1[0125]\d{1,8}|(13(\d{4}|00\d{6})))$" -OnlinePstnGatewayList -Priority 5 -OnlinePstnUsages "Australia-USG"

New-CsOnlineVoiceRoute -Identity "AUS-International" -NumberPattern "^\+((1[2-9]\d\d[2-9]\d{6})|((?!(61))([2-9]\d{6,14})))" -OnlinePstnGatewayList -Priority 6 -OnlinePstnUsages "Australia-USG"


Lastly, let’s create our Voice Routing Policies

New-CsOnlineVoiceRoutingPolicy "Australia-VRP" -OnlinePstnUsages "Australia-USG"

Once our routes and USG’s are created, we can go ahead and assign a voice routing policy to our end user:

Grant-CsOnlineVoiceRoutingPolicy -Identity -PolicyName "Australia-VRP"


Dial Plans

There are 3 different kinds of dial plans in teams:

Service Country Dial Plan
The service country dial plan is a default dial plan created by Microsoft and assigned to users automatically, based on their service location.

the service country dial plans are pretty simple, and will allow you to make basic calls, but won’t support local dialling, or service numbers.

Tenant Global Dial Plan
The tenant global dial plan is assigned to end users who don’t have an assigned user dial plan. This is useful if you want to create a simple dial plan for the majority of your users (such as if you want to allow extension dialling).

User Dial Plan
User dial plans are assigned to end users, and contain specific entries for that users location. An example of a user dial plan would be a state-based dial plan that allows users to dial local numbers without having to dial the full national number. Of course, each state would require its own dial plan to achieve this.


How Dial Plans Are Inherited

Dial plan heritance works as follows.

  • If you don’t create a global tenant dial plan, users will inherit the service country dial plan by default.
  • If you create a global tenant dial plan, users will inherit a merged version of your global tenant dial plan, and the service country dial plan.
  • If you create a user dial plan and assign it to a user, that user will inherit a merged version of the user dial plan, and the service country dial plan.
  • Users never inherit a merged copy of the user dial plan and global dial plan.

My advice here is to create user dial plans that are specific to your end users.


Dial Plan Creation

To make life easier for our end users, let’s create Australian state-specific dial plans to allow end users to dial 8 digit local numbers rather than having to enter the full 10 digit national number.

First, we’ll create our 4 new tenant dial plans:

New-CsTenantDialPlan "AUS-NSW-ACT-DP" -Description "Normalisation rules for NSW and ACT, Australia"

New-CsTenantDialPlan "AUS-VIC-TAS-DP" -Description "Normalisation rules for VIC and TAS, Australia"

New-CsTenantDialPlan "AUS-QLD-DP" -Description "Normalisation rules for QLD, Australia"

New-CsTenantDialPlan "AUS-SA-WA-NT-DP" -Description "Normalisation rules for SA, WA, and NT, Australia"


Next, we’ll create our voice normalisation rules for each state and add them to our tenant dial plans


$ruleNSWACTLOCALNR += New-CsVoicenormalizationRule -Name "AU-NSW-ACT-Local-NR" -Parent "AUS-NSW-ACT-DP" -Inmemory -Pattern '^([2-9]\d{7})$' -Translation '+612$1' -Description "Local number normalisation for NSW, ACT, Australia"

Set-CsTenantDialPlan -Identity "AUS-NSW-ACT-DP" -NormalizationRules @{add=$ruleNSWACTLOCALNR}


$ruleVICTASLOCALNR += New-CsVoicenormalizationRule -Name "AU-VIC-TAS-Local-NR" -Parent "AUS-VIC-TAS-DP" -Inmemory -Pattern '^([2-9]\d{7})$' -Translation '+613$1' -Description "Local number normalisation for VIC, TAS, Australia"

Set-CsTenantDialPlan -Identity "AUS-VIC-TAS-DP" -NormalizationRules @{add=$ruleVICTASLOCALNR}

$ruleQLDLOCALNR = @()

$ruleQLDLOCALNR += New-CsVoicenormalizationRule -Name "AU-QLD-Local-NR" -Parent "AUS-QLD-DP" -Inmemory -Pattern '^([2-9]\d{7})$' -Translation '+617$1' -Description "Local number normalisation for QLD, Australia"

Set-CsTenantDialPlan -Identity "AUS-QLD-DP" -NormalizationRules @{add=$ruleQLDLOCALNR}


$ruleSAWANTLOCALNR += New-CsVoicenormalizationRule -Name "AU-SA-WA-NT-Local-NR" -Parent "AUS-SA-WA-NT-DP" -Inmemory -Pattern '^([2-9]\d{7})$' -Translation '+618$1' -Description "Local number normalisation for SA, WA, NT, Australia"

Set-CsTenantDialPlan -Identity "AUS-SA-WA-NT-DP" -NormalizationRules @{add=$ruleSAWANTLOCALNR}


Lastly, let’s add the Australia-wide normalisation rules to each of our dial plans. some of these are already captured as part of the Service country dial plan, but for completion we’ll add them anyways.

$ruleAUSTRALIANR = @()

$ruleAUSTRALIANR += New-CsVoicenormalizationRule -Name 'AUS-TollFree' -Parent global -Pattern '^(180(0\d{6}|\d{4}))\d*$' -Inmemory -Translation '+61$1' -Description "TollFree number normalisation for Australia"

$ruleAUSTRALIANR += New-CsVoicenormalizationRule -Name 'AUS-Premium' -Parent global -Pattern '^(19\d{4,8})$' -Inmemory -Translation '+61$1' -Description "Premium number normalisation for Australia"

$ruleAUSTRALIANR += New-CsVoicenormalizationRule -Name 'AUS-Mobile' -Parent global -Pattern '^0(([45]\d{8}))$' -Inmemory -Translation '+61$1' -Description "Mobile number normalisation for Australia"

$ruleAUSTRALIANR += New-CsVoicenormalizationRule -Name 'AUS-National' -Parent global -Pattern '^0([23578]\d{8})\d*(\D+\d+)?$' -Inmemory -Translation '+61$1' -Description "National number normalisation for Australia"

$ruleAUSTRALIANR += New-CsVoicenormalizationRule -Name 'AUS-Service' -Parent global -Pattern '^(000|1[0125]\d{1,8}|(13(\d{4}|00\d{6})))$' -Inmemory -Translation '$1' -Description "Service number normalisation for Australia"

$ruleAUSTRALIANR += New-CsVoicenormalizationRule -Name 'AUS-International' -Parent global -Pattern '^(?:\+|0011)(1|7|2[07]|3[0-46]|39\d|4[013-9]|5[1-8]|6[0-6]|8[1246]|9[0-58]|2[1235689]\d|24[013-9]|242\d|3[578]\d|42\d|5[09]\d|6[789]\d|8[035789]\d|9[679]\d)(?:0)?(\d{6,14})(\D+\d+)?$' -Inmemory -Translation '+$1$2' -Description "International number normalisation for Australia"

Set-CsTenantDialPlan -Identity "global" -NormalizationRules @{add=$ruleAUSTRALIANR}

Set-CsTenantDialPlan -Identity "AUS-NSW-ACT-DP" -NormalizationRules @{add=$ruleAUSTRALIANR}

Set-CsTenantDialPlan -Identity "AUS-VIC-TAS-DP" -NormalizationRules @{add=$ruleAUSTRALIANR}

Set-CsTenantDialPlan -Identity "AUS-QLD-DP" -NormalizationRules @{add=$ruleAUSTRALIANR}

Set-CsTenantDialPlan -Identity "AUS-SA-WA-NT-DP" -NormalizationRules @{add=$ruleAUSTRALIANR}


Assign a dial plan and phone number to a user

Now that our dial plans are created, lets assign our NSW dial plan to our user:

Grant-CsTenantDialPlan -Identity -PolicyName AUS-NSW-ACT-DP

We’ll also need to assign a phone number to our user:

Set-CsUser -Identity -LineURI tel:+61281002000 -EnterpriseVoiceEnabled $true -HostedVoiceMail $true

Note: There’s an issue with the latest Microsoft Teams PowerShell module. If you encounter errors, remove it, and install the Microsoft Teams module version 2.0.0

  1. Uninstall-Module -Name MicrosoftTeams
  2. Install-Module -Name MicrosoftTeams -RequiredVersion 2.0.0

Testing our dial plans

We can test our dial plan in Powershell:

Test-CsEffectiveTenantDialPlan -Identity -DialedNumber 81234567


Making a call

Alright! We’re ready to make a call via Direct Routing! I’ve placed an outbound call from Teams to my mobile and upon checking the SBC can see the call is connected via my Twilio SIP trunk.


Next Steps

You’ve successfully configured Direct Routing for Teams!

The next steps from here are to enable more users with calling, to enable auto attendants and call queues, and to tidy up and secure your SBC in Azure.

Questions/Comments? leave them below.

0 0 votes
Article Rating
Notify of

This site uses Akismet to reduce spam. Learn how your comment data is processed.

Newest Most Voted
Inline Feedbacks
View all comments
1 month ago


Thank you for the great post. I’m just wondering how I can authenticate to the SIP trunk (in this case Twilio). My SIP trunk provider requires authentication via a password