In this post I describe how you can configure call forwarding to external PSTN phone numbers for a call queue or auto attendant in a Microsoft Teams Direct Routing configuration. Microsoft released the capability to forward phone calls via a Teams Auto Attendant and via a Teams Call Queue to a phone number. Also, the operator can have a (external/PSTN) phone number.
In the past this was not feasible this way, therefore you had to implement a workaround by configuring a “forwarding user” to reach the goal. This is no longer necessary. I’ll show you some screenshots to depict what you’ve got now with Teams Calling and Microsoft 365 Phone System.
Teams Auto Attendant – Operator – External Phone Number Option

Teams Auto Attendant – Call Flow – External Phone Number Option

Teams Call Queue – Call Flow – Externa Phone Number Option/s
Within call queues you have two options to forward a call to a phone number. The first option helps to deal with more as the maximum set amount of concurrent calls in a queue. The second option helps to deal with calls waiting in a queue for a certain amount of time.

What do I have to do to make this work with Teams Direct Routing?
Easy, you have to do two things:
- assign a Virtual Phone System User license (!!!) (if not done yet) to the Teams Resource Account (also note the docs.microsoft.com statement saying, “Phone System licenses aren’t supported”, so assigning a E3 + phone system license might not work)
- assign an Online Voice Routing Policy to the resource account which is assigned to the call queue or auto attendant [with PowerShell]
- Wait for some time (as I was testing this, I configured this in the late afternoon and the next morning it was working as expected, this might be different and I’m not aware of a default duration till it is applied and will work)
I’ll not explain how to get and assign the license, I’ll explain the assignment of the Online Voice Routing Policy because at the time of writing this post, you have to assign the policy by using PowerShell.
Assign an Online Voice Routing Policy to a resource account
Using SFBO PowerShell Module (before February 2021, deprecated)
#Teams Direct Routing
#Enable resource account for outbound call in Microsoft Teams Call Queues and Auto Attendants
#Example code
Import-Module SkypeOnlineConnector
#Login
if ($cred -eq $null) {$cred = Get-Credential}
#W/O MFA:
$sfbosession = New-CsOnlineSession -Credential $cred
#WITH MFA:
#$SFBOsession= New-CsOnlineSession ADMIN-UPN
#Import module
Import-PSSession -Session $sfbosession -AllowClobber
#List Online Voice Routing Policies
Get-CsOnlineVoiceRoutingPolicy
#Assign Online Voice Routing Policy to Microsoft Teams Resource Account for Teams Direct Routing
$user = "teams-resource-account@domain.tld"
$userovrp = "teams-direct-routing-online-voice-routing-policy"
Grant-CsOnlineVoiceRoutingPolicy -Identity $user -PolicyName $userovrp
#Get a cup or some more cups of coffee and wait!!!
#Check assignment
Get-CsOnlineUser $user | select UserPrincipalName,OnlineVoiceRoutingPolicy
<#Please note
although it's set quickly it can take quite some time till it is really applied, you can see this on the SBC SIP traces which still points to Teams phone system which is rejecting the referred call with a "403 Forbidden", it detail it states some like that there is no viable outbound route.
#>
Remove-PsSession $sfbosession
Using Teams PowerShell Module (from February 2021 onwards)
Updated February 2022
- Connection String with Teams PowerShell Module
- Please note depending on the Teams PowerShell Module you are using cmdlets might have changed recently. This cmdlets worked with Teams PowerShell Module <3.0.0.
#Teams Direct Routing
#Enable resource account for outbound call in Microsoft Teams Call Queues and Auto Attendants
#Prerequisite Teams PowerShell Module
#Example code
#Connect Microsoft Teams
Connect-MicrosoftTeams
#List Online Voice Routing Policies
Get-CsOnlineVoiceRoutingPolicy
#Assign Online Voice Routing Policy to Microsoft Teams Resource Account for Teams Direct Routing
$user = "teams-resource-account@domain.tld"
$userovrp = "teams-direct-routing-online-voice-routing-policy"
Grant-CsOnlineVoiceRoutingPolicy -Identity $user -PolicyName $userovrp
#Get a cup or some more cups of coffee and wait!!!
#Check assignment
Get-CsOnlineUser $user | select UserPrincipalName,OnlineVoiceRoutingPolicy
<#Please note
although it's set quickly it can take quite some time till it is really applied, you can see this on the SBC SIP traces which still points to Teams phone system which is rejecting the referred call with a "403 Forbidden", it detail it states some like that there is no viable outbound route.
#>
#Disconnect
Disconnect-MicrosoftTeams
Update 03.09.2022
It seems that this is now finally also possible by using the Teams Admin Center, therefore I wrote another post to show you how: Assign a phone number to a Microsoft Teams resource account in Teams Admin Center – erik365.blog
Conclusion, opinion and summary
I’ve been waiting for this for some time by now, and now that the feature is available, without creating a workaround, I like it. Especially, because you can also do some automation by using PowerShell for your cloud hotlines based on Microsoft Teams call queues and auto attendants.
Additional resources
- Microsoft Teams Call Queues and Auto Attendants for Direct Routing
- Manage resource accounts in Microsoft Teams
- Microsoft 365 Phone System – Virtual User license
- Grant-CsTeamsCallingPolicy
- Microsoft Teams Telephony Licensing Notes [Update April 2020]
- Assign a phone number to a Microsoft Teams resource account in Teams Admin Center – erik365.blog [update September 2022]
[…] Enable resource account for outbound call in Microsoft Teams Call Queues and Auto Attendants – eri… […]
LikeLike
[…] (calling plans, direct routing, operator connect) the Teams Resource Account must be able to make an outbound call. In case of direct routing you need to assign the suited Teams Online Voice Routing policy. For […]
LikeLike
Hi Erik,
Since February 2022 I am unable to enterprisevoice enable a resource account via Powershell. Also, I am unable to grant an online voice routing policy to a resource account.
The commands I tried to use and their errors:
PS C:\Users\llameire> Set-CsPhoneNumberAssignment -Identity $UPN -EnterpriseVoiceEnabled $true
Code Message
—- ——-
BadRequest Attribute assignment does not support target type ‘ResourceAccount’
PS C:\Users\llameire> Set-CsUser -Identity $UPN -EnterpriseVoiceEnabled $true
Microsoft.Teams.ConfigAPI.Cmdlets.internal\Set-CsUserGenerated : Invalid user account
At C:\Program Files\WindowsPowerShell\Modules\MicrosoftTeams\3.1.0\net472\custom\PsExt\Set-CsUserModern.ps1:51 char:13
+ Microsoft.Teams.ConfigAPI.Cmdlets.internal\Set-CsUserGene …
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : InvalidOperation: ({ UserId = AA_t…onaryOfString }:f__AnonymousType86`2) [Set-CsUserGenerated_Set], Exception
+ FullyQualifiedErrorId : BadArgument,Microsoft.Teams.ConfigAPI.Cmdlets.Generated.Cmdlets.SetCsUserGenerated_Set
PS C:\Users\llameire> Grant-CsOnlineVoiceRoutingPolicy -Identity $UPN -PolicyName VP-TBdaoustinterim
Microsoft.Teams.ConfigAPI.Cmdlets.internal\Grant-CsUserPolicy : User does not exist
At C:\Program Files\WindowsPowerShell\Modules\MicrosoftTeams\3.1.0\net472\custom\PsExt\Grant-CsUserOrTenantPolicy.ps1:61 char:13
+ Microsoft.Teams.ConfigAPI.Cmdlets.internal\Grant-CsUserPo …
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : InvalidOperation: ({ Identity = AA…ntUserRequest }:f__AnonymousType55`3) [Grant-CsUserPolicy_GrantExpanded], Exception
+ FullyQualifiedErrorId : ClientError,Microsoft.Teams.ConfigAPI.Cmdlets.Generated.Cmdlets.GrantCsUserPolicy_GrantExpanded
I hope you have any idea on how to solve this.
Kind regards,
Lowie
LikeLike
Hello Lowie,
I think that the process of assigning numbers to a resource account did not change. It is still the same even in Teams PowerShell Module 3.1.1 (tested 13.02.2022 successfully). So you cannot use the same cmdlets for enabling a resource account as you would for a common enterprise voice user.
To enable a resource account and assign it with a phone number you can do it as follows (examples):
The difference is the Application ID (either it’s for a Auto Attendant or a Call Queue).
Auto Attendant: ce933385-9390-45d1-9512-c8d228074e07
Call Queue: 11cd3e2e-fccb-42ad-ad00-878b93575e07
Example for an Auto Attendant’s resource account
Set-CsOnlineApplicationInstance -Identity eriksautoattendant01@domain.tld -OnpremPhoneNumber +49711555555555 -ApplicationId ce933385-9390-45d1-9512-c8d228074e07 -DisplayName “eriksautoattendant01”
Example for an Call Queue’s resource account
Set-CsOnlineApplicationInstance -Identity erikscallqueue
@domain.tld -OnpremPhoneNumber +49711555555556 -ApplicationId 11cd3e2e-fccb-42ad-ad00-878b93575e07 -DisplayName “erikscallqueue01”
See https://docs.microsoft.com/en-us/powershell/module/skype/set-csonlineapplicationinstance?view=skype-ps
Best Regards
Erik
LikeLike
thanks, I’m thinking of similar – we have an after hours emergency team, that responds to events, and the business wants one extension for them, and for the team to change the mobile phone number it diverts to on a weekly basis. so can we set someone who’s not a teams voice admin to be able to modify the diversion?
LikeLiked by 1 person
No, currently a teams voice admin is required, unfortunately.
But you could check out a blog from Alex Holmeset who’s writing about an interesting approach to change an Auto Attendand’s holidays by a user. I think this might be modified to change this script with some effort. https://alexholmeset.blog/2021/11/05/self-service-microsoft-teams-auto-attendant-administration/
Or you could create a plan / schedule, configure holidays but instead of actual holidays you configure week by week as a holiday containing the week’s forwarding target for out of business hours and the weekend. Just an idea.
LikeLike
Hi Erik and thank you for this post.
Even if it’s already better than it used to be. I’m still struggling. Maybe you do have an idea… What I would like to achieve is the following :
Based on Date / Hours, forward the call to someone, simultaneously on the mobile phone + Teams client. If no answers after 20 seconds, forward to someone else, also on mobile phone + Teams client.
Even of S4B, forwarding to a mobile phone is a bit, the last step of a workflow and this is annoying as Hell. For the time being, I’m using a third party solution, AudioCodes IVR, which allow me to create the required workflow. I was wondering if I missed something ? Are for example, simultaneous ring possible on a PSTN phone number + Teams client ?
Don’t tell me it’s not possible by design, to protect loop or so, we should have the ability to implement what we need…
Thank you,
Fabien
LikeLiked by 2 people
Hello Fabien,
You are welcome!
What you could do is to create auto attendants configure business and out off hours dates/hours (as needed). So, that you have several auto attendants in place. No call queues. Instead of forwarding a call from an auto attendant to a external pstn number (during business hours), you forward the call to the Teams user directly. And in case one auto attendant is configured with out of business hours the call should go to another auto attendant (resource account) and get handled there.
In each auto attendant you could configure the forwarding to the target Teams user (not to external (pstn) phone number!) and if the enterprise voice enabled teams user has his teams client open plus also configured a call forwarding rule to his pstn/mobile phone number, he’ll receive the call on both, teams client + phone number. The user could also just use the Teams client on his mobile device (as far as mobile internet is available).
Please note, as far as I tested, you can use an auto attendant which forwards the call to a teams user and in case the teams user has call forwarding enabled to a pstn number, the pstn number will receive the call, afaik. This will not work if you forward the call from an auto attendant via call queue to the target teams user/s. Also to note, the forwarding mechanism can add latency to the call flow that’s why it should be tested thoroughly.
Regarding the teams user call forwarding settings, there you can configure the 20 seconds with but than the call forwarding to the mobile / pstn will not work because of the 20 second time which only applies to the call forwarding settings (“Ring for this many seconds before redirecting”) and not for the (“if unanswered”) mechanism. However, you could tweak this and send calls to (“if unanswered”) to the voicemail but instead of (“Let the caller record a message”) in the teams user voicemail settings, you or the Teams user can choose to (“Transfer the call to someone else”) either a pstn phone number or Teams user can be used here, afaik. This is really not easy for users to cope with and includes some other tradeoffs, e.g. no more active voicemail to record messages.
If you are looking for something more interactive where users might interact with a call queue, you might find the post from Luca Vitali helpful, too. https://lucavitali.wordpress.com/2020/11/23/how-to-use-lightweight-bot-and-azure-automation-to-interact-with-teams-call-queue/
I hope this helps.
Best Regards
Erik
LikeLiked by 1 person
Thank you very much Erik,
I’m not able to answer your comment so I create a new one… 😀
What a mess… I can’t implement that at all. For the time being, the guys in charge of customer support can login to our AudioCodes system and define in less than a minute, who are the first and backup engineer (Change every weekend and holidays). But I’ll also check your link, I know Luca’s blog and it’s quite often really helpful.
Maybe something else you may know, I’m able to do the same with AudioCodes and Teams, simultaneous ring on Teams client and mobile phone but when I try to pick up the call on Teams, I get the following : Sorry we couldn’t connect you => The call is droped. I haven’t checked the Teams logs yet, I’m just wondering if you have magic ideas 🙂
Thank you and take care,
Fabien
LikeLiked by 2 people
Regarding the call drop, this is hard to guess without any data.
I’d recommend to take a look into the Audiocode SBC syslogs for sip tracing. There you should see the sequence diagram and this usually helps to figure out why a call is being dropped.
Maybe a reason code or a SIP code will tell why. No magic idea 😉
Thank you and take care, too,
Erik
LikeLiked by 1 person
Hi Erik!
I was expecting this functionality as well.
But I configured it as you did 2 days ago, and it still doesn’t work. I still get a “SIP/2.0 403 Forbidden” when auto attendant try to transfer to external number.
“REASON: Q.850;cause=63;text=”925e1bf9-6eaa-4f5d-a82a-6ba88d91112a;User is not Enterprise Voice enabled. User is not allowed to make user based dial out.”
I’m using AudioCodes in an Azure VM (POC server).
LikeLike
Hi Quati,
did you assign a virtual phone system user license to the resource account?
Did you enable the resource account for enterprise voice? I skipped this steps in my description.
E.g.
Set-CsUser -Identity resource account -EnterpriseVoiceEnabled $true
Best Regards
Erik
LikeLike
After reading this https://techcommunity.microsoft.com/t5/microsoft-teams-blog/auto-attendant-and-call-queues-service-update/ba-p/564521 and some others sites…
I’ve deleted the resource account:
1 – Remove Auto Attendant
2 – Deallocate the license (Virtual Phone User)
3 – Delete the user (AD).
So, recreating the resource account (with another name, but keeping same identity) resolve my issue.
LikeLiked by 1 person
Thank you for the update!
LikeLiked by 1 person