In a previous blog post, the ability to use Skype for Business certified IP Phones in a Teams environment was discussed and how users who have migrated from Skype for Business to Teams can continue to use these IP phones to make and receive calls. In this post, we continue the discussion and provide an overview of how Teams users can be enable for enterprise voice. Unlike its predecessor, Teams is a pure cloud service and there are no on-premise Teams servers, and hence majority of the Voice configurations have to be performed in the O365 tenant using powershell. Our tenant has a E5 license which enables the Phone System (formely CloudPBX) feature for this to work, but E1/E3 users can also be enabled via the Add-on license |
Beginning with the basics, enterprise voice in Teams is similar to Skype for Business in terms of the various configuration objects that allow users to be assigned a phone number (TelURI), dial plans for numbers to be normalized into E.164 format and the PSTN usages that link voice routes to voice policies that determine what external calls users are allowed to make along with which PSTN gateway are used. There are only 2 ways in which Teams users can reach the PSTN which are Microsoft Calling Plans and Direct Routing. The former is available in countries such as North America and UK while in APAC it is only available in Australia via Telstra. The rest of APAC countries will have to rely on Direct Routing which will be discussed in more detail later. To begin configuring for voice in Teams, we look at the creating tenant dial plans that specify what normalization rules are required for users when making calls. Tenant dial plans were covered in detail in a previous blog post and so we just a summary will be provided here. Using the following powershell cmdlet examples, we create a new tenant dial plan and add normalization rules:
New-CsTenantDialPlan -Identity MyTenantDP
$nr = New-CsVoiceNormalizationRule -Parent Global -name SG7Digit -Description "Internal 4Digit1" -Pattern '^(1\d{3})$' -Translation '+656389$1' -IsInternalExtension $True -InMemory
Set-CsTenantDialPlan -Identity MyenantDP -NormalizationRules @{Add=$nr}
Once we're done we can verify the dial plan and assign to user accounts using the grant-CsTenantDialPlan cmdlet as shown below:
Next we look at the Voice Routes, PSTN Usages and Voice Routing Policy, which are all related. Each Teams user is assigned one and only one Voice Routing Policy (VRP). The VRP contains one or more PSTN Usages which specify Voice Routes. Each Voice Route is a calling number matching pattern and its corresponding PSTN Gateway. An example diagram representing the various voice configuration objects and how they route calls to/from the PSTN is shown below:
New-CsOnlinePSTNGateway -Identity teamstrunk.ucprimer.com -Enabled $true -SipSignallingPort 5061 -MaxConcurrentSessions 10
Set-CsOnlinePstnUsage -Identity Global -Usage @{Add="International"}
New-CsOnlineVoiceRoute -Identity "SG-PBX" -NumberPattern "^\+65(\d{8})$" -OnlinePstnGatewayList teamstrunk.ucprimer.com -Priority 0 -OnlinePstnUsages "SGLocal"
2018-12-18T09:21:24.204Z Inf UserAppsStore: Attempting to add calling with the following flags: {"isCallingEnabledByTenant":true,"isSfbCloud":true,"isEvEnabled":true,"disableCallingForHybridVoice":true,"pstnType":"OnPrem","isBusinessVoicePath":false,"isByotEnabled":true,"isOneToOneCallingEnabled":true,"isCallingSupportedEnvironment":true,"enableVoipCallTab":false,"result":"added"}
2018-12-18T09:21:24.204Z Inf UserAppsStore: Calling app added, flags: {"isCallingEnabledByTenant":true,"isSfbCloud":true,"isEvEnabled":true,"disableCallingForHybridVoice":true,"pstnType":"OnPrem","isBusinessVoicePath":false,"isByotEnabled":true,"isOneToOneCallingEnabled":true,"isCallingSupportedEnvironment":true,"enableVoipCallTab":false,"result":"added"}
2018-12-18T09:21:24.204Z Inf UserAppsStore: Calling app added with isFirstParty as true
2018-12-18T09:21:24.204Z Inf UserAppsStore: shouldShowCallingApp resolved to true
This will help to identify the cause which could be due to parameters not set correctly or the VRP has not been assigned.