I'm a Microsoft Certified Solution Master for Communication, aka Skype for Business. As a consultant I work in all areas of SfB design, deployments, and support, with a particular focus on voice workloads, networking, and high availability.
Click on one of the 5 topic areas on the left. Let’s stick with voice. On the right, you see a list of common issues. “Dial pad is missing” comes up All. The. Time. So, click on it.
You’ll see a nice long sidebar menu:
And how awesome is this? There are “Insights”, letting you know what’s required for the dialpad to be visible. There’s also recommended articles for deeper learning. And finally, right up top is a lovely area where you can enter the username or email address for your problem user and Teams will diagnose it for you, letting you know if it’s found something that’s wrong.
Now, this isn’t perfect. For example, the insights list “make sure the user has a calling plan assigned”, and that would only be true for Calling Plan users, and not Direct Routing or Operator Connect users. If you’re not a Calling Plan user, you reaaaaly don’t want a calling plan license assigned. And if you’re a Direct Routing user, you need to make sure you have a Voice Routing Policy assigned, and that needs to be a valid Voice Routing Policy, and not just some random placeholder you’ve created.
However, I still feel that this is an absolute goldmine for organizations and admins new to Teams, and also grizzled veterans like myself. I will absolutely head here first if I have a user with no dialpad, rather than splunk around inside Teams looking to solve the problem on my own – I’m not lazy, I’m efficient!
Teams Auto Attendants and Call Queues have the ability to deliver voicemails to Microsoft 365 group mailboxes. Call Queues will also allow you to forward calls directly to a user’s voicemail box. Let’s talk through each option and discuss why you would or wouldn’t want to use each.
First, Call Queue transfers to a user’s personal voicemail box. I rarely see this used. This works when there is a low volume of voicemail, or if you want callers to be able to reach the user’s voicemail but not to actually ring the user – perhaps a municipality? The best case for this is in a boss-admin delegation scenarios, where if the admins in the call queue don’t answer the call, it should go to the boss’s voicemailbox.
The difficulty I see with this option otherwise is that a user’s personal mailbox leaves little option for delegation or access should that user be out for vacation, sickness, or whatever other reason. Usually, if a call hits a Call Queue or Auto Attendant it’s a team, office, or organizational number that was called and so sending voicemails to the mailbox of just one user doesn’t fit this scenario.
Microsoft 365 groups are what I typically see, even if a personal mailbox might make sense in some circumstances. Keeping everything the same makes support easier. Note that Microsoft 365 group mailboxes are not the same thing as Exchange shared mailboxes. Call Queues and Auto Attendants cannot deliver to Exchange shared mailboxes. From the perspective of Teams, you can safely assume that Exchange shared mailboxes have been replaced with M365 group mailboxes.
When an M365 group is created (or modified), there are a few settings that I like to review with customers, as they can have impact ranging from “annoying” to “holy cow what just happened”. They are:
Here, you’ll want to choose Microsoft 365 group. That’s your only option for Auto Attendant and Call Queue voicemail.
Give the group a meaningful name, and expand upon it in the description as you see fit.
You can add group owners on this tab. Be careful here, group owners can modify group membership from Outlook. Make sure that anyone who is made a group owner knows about this.
Add the members of the group here. Owners are also automatically considered members, you don’t need to add them again. Members (and owners) will have access to the group mailbox.
Here you get to select the group email address. If this is a group solely for voicemail for an Auto Attendant or Call Queue, consider using the same naming scheme here as the Resource Account for the AA or CQ, and add “-vm” to the end of it.
You’ll likely want to select “Private” for the privacy type, otherwise anyone in your organization can add themselves to the group, and thus get access to the voicemails.
And lastly, you don’t need to create a Team for the group. If you want to create a team for the group members – this makes sense for IT Helpdesk, for example – I’d suggest creating the team via Teams so you can get that configuration setup properly. Then you can use the group email address for voicemails, without this group creation process. Otherwise, clear this checkbox so that a team is not created.
And you’re done. The Finish step gives you an option to review and correct anything.
A couple of notes here. If you create the group via PowerShell, you will be automatically added as an owner. Be sure to assign owners and remove yourself.
For the email address, note above that I’ve used my torren.ca domain. If I look at this group in Microsoft 365 admin center, I see that the @torren.ca is actually an alias, and the onmicrosoft.com domain is the actual email address. That’s not an issue for voicemail usage. In fact, if you’re in a hybrid environment and you select a vanity domain (like @torren.ca) and your autodiscover DNS points to your on-prem environment, the desktop Outlook client won’t be able to find the mailbox. Outlook web will, however. If you then change the primary address of the group to be the onmicrosoft.com, Outlook will be able to find the group, since onmicrosoft.com is online-only.
And finally, if you now edit the group in M365 Admin Center you’ll find some more settings to configure:
You can see an option to have the voicemail/email for the group delivered to the members’ inboxes as well as to the group mailbox. If the messages are copied to the users’ inboxes, then each inbox has its own “read”/”replied” status within that inbox. This is fine if you need everyone to consume the message. If someone needs to respond to the message or take some action, you will need to either a) implement some way of communicating who has/will deal with a message, or b) don’t copy the messages to users’ inboxes, and use the status in the group mailbox to track if someone has read or responded.
There’s also the “Don’t show team email address in Outlook” which you might want to set for voicemail-only groups, and “Let people outside the organization email this team” which you likely don’t want set for a voicemail-only group, and may or may not want set if you also use the group for email.
Where The Folder Lives
If you don’t copy the message to the users’ inboxes, then you should have them browse to the group mailbox in the Groups folder at the bottom of the Outlook folder list. In that list, Groups are tucked away down at the bottom. You can have users right click on the folder to add it to their favorites. This will help ensure that the group mailbox isn’t hidden out of sight, out of mind from the members.
Roaming policies are a relatively new addition to Microsoft Teams. Their predecessor in Skype for Business was called Call Admission Control, which is an industry term for “should I admit this call onto the link it’s destined for, or will that overload it and cause issues?”.
The SfB configuration for CAC was (is?)…. not fun. You needed to build out policies based on each sites connection to other sites and regions, you had to sort per-user and per-site restrictions, and you had to make broad assumptions around how much bandwidth particular calls may consume. It did allow for calls to be placed from one SfB user to another via the PSTN in situations where the WAN link was at capacity (or down), and that configuration was fun. (Or maybe I was just tired?)
But Dear Reader, bandwidth consumption is highly dependent on payload/user activity! For example, a video of a user sitting in front of a webcam, in front of a blank wall, will consume different amounts of bandwidth if that user is wearing a plain shirt versus a patterned shirt. Why? Video compression/encoding depends on changes between frames, and a patterned shirt will result more changes than an equivalent plain shirt. So I’m supposed to plan bandwidth consumption based on the shirts people wear? Well no, that’s just one example. Screenshares of a static document will consume less than a video, or a screenshare of a web page with ads popping up all over the place. A voice through an SBC call may flip to G711 and consume 64k (plus overhead) across a WAN, where as a voice call between two clients may use a “better” protocol and consume 8 or 16k.
A second consideration was that CAC couldn’t account for backup WAN links, or SDWAN capabilities, it only used the values you told it were available between the two sites. If you had a backup link that had a lower bandwidth and you were adventurous, you could try to restrict usage over that backup link using things like DSCP priority tags – you could, for example, block video traffic from the backup link, allowing voice traffic through.
The other complication with CAC, is that it didn’t take in to consideration what the actual available amount of bandwidth on the link was. You had to ballpark that “this is a 100Mb WAN link, and we’ll say that SfB can use 10Mb of that”. Well, if the actual available bandwidth is 40Mb, why are we restricting SfB to 10Mb? There were thoughts and some options about software defined networks and having the network able to talk to the applications and make dynamic decisions, but that sounds like as much fun as dumping a couple dozen forks in your bed and trying to go to sleep.
When Teams launched, there was no consideration for CAC until Roaming Profiles came along. Roaming profiles greatly simplify things. You don’t need to indicate the size of any links, which makes sense given that Teams could use WAN/SDWAN links or Internet connectivity, and that WAN/SDWAN links might be running as VPNs over the Internet link anyway. The net result is that you can restrict whether users in that site can use video, and the maximum media bitrate that each user can consume.
How this works is pretty simple. The parameters is this policy (applied to the site) override the parameters in the user’s policy (either the global or per user policy), while the user is in the site.
And one more catch: There’s another policy setting that allows the Roaming Policy to take effect if the user isn’t voice enabled:
To enable the network roaming policy for users who are not enterprise voice enabled, you must also enable the AllowNetworkConfigurationSettingsLookup setting in TeamsMeetingPolicy. This setting is off by default.
If you need backup or alternate agents to answer a call, Call Queues offer a number of ways to do this with call distribution methods like round robin or serial routing. Every so often, I encounter an organization that wants to have a second Call Queue be a backup or escalation for a primary Call Queue.
This could be because the primary Call Queue already has multiple agents that are busy, so a second Call Queue is needed to add a second list of ordered agents. It can often be because the organization wants a different call routing method used for the backup vs the primary. For example, the primary might be round-robin, and the back might be attendant. That would be a case of “if you’ve tried everyone available in customer service in round-robin, now try everyone in inside sales at the same time”.
There are some considerations here with Call agent alert time (how long each agent rings for) and call timeout handling (how long the caller is in this queue before some timeout action takes place), as well as the Call overflow handling (what to do when there are too many callers waiting in this queue).
Let’s start with a simple example. If you have an Agent Alert time of 15 seconds and a Call Timeout value of 20 seconds, the caller will remain in the queue for 30 seconds:
This is because the “Call Timeout” value is only considered each time the Agent Alert Time expires. At the 15 second mark, the first Agent Alert time has expired, Teams checks the Call Timeout and it has not expired, so it rings another agent and keeps the caller in the Queue.
After 30 seconds when the second Agent Alert time expires, Teams checks the call Timeout and finds it has expired and takes the timeout action that you’ve defined.
Call Overflow handling takes place when a new caller would be added to the Queue. If the Overflow value is 10 and the 11th caller tries to join, Teams will instead use the call Overflow action that you’ve defined.
Let’s say your second queue overflow and timeout actions send the caller to voicemail. Your primary queue call timeout should send callers to the second queue. However, your primary queue overflow should send users directly to the voicemail and not to the second queue. This is because these callers are new and sending them directly to the second queue means that they are skipping the line and now have less time to wait for an agent than those callers waiting in the primary queue:
Perhaps the most time consuming portion of the Teams voice projects that I’m involved in relates to location… A Teams user’s location can be used for emergency calling, bandwidth consumption over constricted WAN or internet links, or things like location based routing and local media optimization.
One of the first questions I ask is: “Do you have subnets that span multiple buildings, especially for wifi”. For emergency calling, each building or facility may need to be broken up into “dispatchable locations” if you’re reading legislation or “places” in Teams lingo. Essentially, if you’re a large building like a school or factory, how do the first responders find you? That’s your “emergency response location” or your “place”. You’ll need a network characteristic to establish which place a Teams client is in. That could be subnet, the switch chassis ID, or the switch port on that switch you are connected to, or it could be the BSSID, which reflects which access point you’re connected to.
If you have IP subnets that span buildings, you will need to re-subnet in order to get the proper physical granularity that’s needed for location-based functions in Teams. There are a couple of exceptions to this.
First, if the only spanned subnets you have are for server/storage infrastructure, you’re fine. Just ensure that phones can’t be plugged into this network (which you should be doing anyway!), especially a server room phone.
The second exception would be if you don’t need any Network Site based policies other than Emergency Calling Policy. This is the one that notifies someone at the facility that an emergency call has been placed. In the US, the FCC website says (this is Kari’s law):
“When a 911 call is placed on a MLTS system, the system must be configured to notify a central location on-site or off-site where someone is likely to see or hear the notification.”
Typically, you would need to notify someone at that site about the emergency call, and “that site” has IP subnets associated with it, and an Emergency Calling Policy associated with it. The Emergency Calling Policy handles the notifications, so if a subnet spans multiple sites, you can see how this makes it impossible to notify someone only at the site from which the call was placed.
There are two options or scenarios here. The first is one in which you can notify parties at both/all sites, and train them how to tell when a call is from their site, and to take appropriate action. The second would be when you have something like a central security desk that can be notified, and that security desk can then take appropriate action – commonly this is facilitating first responder access to the building, but it could also be first aid or security teams responding to the incident.
A university campus is an example of a site where I common encounter IP subnets that span sites/buildings/facilities. It’s also a great example of a site where this many not matter, and every university that I’ve encountered has security and/or police departments who can handle responses to these notifications.
An example of where things don’t work with spanned subnets would be a wifi subnet that spans the facilities for a municipality that doesn’t have a security desk (though they may have some “in charge” of security). A call to emergency services from a library would need to notify someone at the library, and not HR, IT or city hall reception. This isn’t so much because they couldn’t in turn notify someone else at the library to take action. My concern here would mainly be around availability and hours of work. If the library is open until 9pm and HR, IT, and city hall are all closed, you’re not notifying anyone.
In a case like this, I would recommend the city to re-subnet their wifi. In some cases, depending on their wifi controller(s), this could be a painful exercise, as some wifi controllers cannot have a single SSID (which is desirable) across the organization use a different subnet at each location. Instead, one SSID would need to be created per location, and then all of the wifi clients at that location would need to have their wireless connections updated to the new SSID. That’s no fun but is necessary in many cases to properly meet emergency calling legislation, or to use other location-based policies like Network Roaming (WAN/Internet bandwidth consumption limits for Teams, based on the site).
When you’re configuring emergency calling, there are a number of spots where you need to configure things. If you’re on Direct Routing, one of the things you need to configure is the Emergency Call Routing Policy. This lets Teams know what your emergency numbers are for a given location, and where those calls should be routed to.
If you’re using Calling Plans or Direct Routing however, you do not need to configure anything for Emergency Call Routing. This is all handled by Microsoft (for Calling Plans) and your operator (for Operator Connect). You don’t even need to flip the “use dynamic 911” switch.
If you’re concerned over this, you can test out emergency calling before you deploy. Assign a Calling Plan or Operator Connect number to a user (your Operator Connect operator can either get you a test number, or they’ll likely allow you to call out from Teams before a number port, if you’re porting in). Call 933, which is the test number for 911 on these platforms. If you want to test your dynamic address capabilities, you’ll need to at least configure your Trusted IP address and a subnet for the location you’re testing from.
Heads-up! If you have notifications turned on in the Emergency Calling Policy (Calling, not Call Routing, Policy), the users that you have configured to receive notifications will see the exact same notification if you call 933 as if you had called 911. From the Teams perspective, there is NO difference between 933 as a test, and 911 as a true emergency call. The only difference is at your carrier/operator, in which case they’ll direct 933 calls to their test bot rather than to a live emergency call taker/operator. You should give those people that are configured for notifications enough notice of the test so they don’t panic, and then you should advise them when your testing is complete, so they know any subsequent notifications are true emergencies.
Teams Phone firmware updates need to be part of your deployment and operating plans. If you look in Teams Admin Center you can find a list of your phone devices:
You can select different groups of device by usage (user, common area/shared device, and conference room tabs), and there’s also a filter available.
You can see from these screens if the phone firmware is up to date. If you click on an individual phone, you can see the firmware and other updatable components:
Here’s what these five items are:
Teams Admin Agent is the Teams management agent on the phone
Firmware is the, well, firmware on the device. Android, in this case.
Company Portal App is the bits that handle modern authentication and security, and enrollment in M365/Azure
OEM Agent App is the phone vendors management app
Teams App is, well, Teams!
If we click on the “See available updates” link, we see this:
We can see that automatic updates for this phone are deferred by 30 days, and we also have an option to deploy the update “now-ish”, or to flip the Schedule slider and pick a date and time.
I said “now-ish” because while that will kickoff the update process, it’s a background process and the phone will wait until it’s idle to restart. If you need an immediate update, you may need to download firmware from the vendor and upload/apply it via the HTTPS interface on the phone.
For ongoing updates, there are three options that you can configure. Immediate, within 30 days, and within 90 days. Most organizations will be fine with the 30 day option, this should provide enough time for any bugs to be found by others and rectified.
If you are worried about changes to user experience, updating your procedures and documents, or bugs that might only apply in a use case specific to your organization, you can setup a couple of devices on the immediate upgrade path. These users need to be aware that they’re on this path, and to be sure to report any issues immediately no matter how minor they seem. You should not pick critical phones or an entire group of similar users for this function. A bug or change that affects your entire accounts payable department might be frustrating, one that takes out your entire reception, helpdesk, or sales group would be unacceptable. Be sure to account for different phone makes and models, as well as use cases. Receptionists will use a phone differently than a lunch room phone would be used.
The phones on the 30-day plan won’t all update at exactly the same time, however if having them all update close to each other is a risk that you don’t want, you can split your phone fleet and have some on the 30 day plan and some on the 90 day plan.
When you create a Resource Account in Teams Admin Center (or via PowerShell), you need to specify whether the Resource Account will be for a Call Queue or an Auto Attendant. Under the hood of Teams, that makes a difference.
Every so often, a customer I’m working with needs to change a Resource Account from an Call Queue to an Auto Attendant, usually to take advantage of schedule that’s present in Auto Attendants. If you need to do this, you can use the Set-CsOnlineApplicationInstance.
First, use Get-CsOnlineApplicationInstance to see what you have
You can tell by the DisplayName field that my first two items are Call Queues, the other three happen to be Auto Attendants.
If I want to change “TestQueue” to be for an Auto Attendant instead, I can do this
Note that 11cd3e2e-fccb-42ad-ad00-878b93575e07 is the ApplicationID for a Call Queue object, and ce933385-9390-45d1-9512-c8d228074e07 is for Auto Attendants.
If you have a large number of physical phones for a Teams deployment, you may have some logistical challenges in getting the phones deployed at cutover time. This could be physical access to a building, not having enough staff, or significant travel time between sites.
Layering users on top of that, you have further complications – the users need to be present in order to logon, especially with 2FA (you ARE using 2FA, right?). From experience, I can tell you that users will not be at their desk when you need them to be, so you will always need to plan to handle these exceptions.
There are a few ways to arrange things to make life as easy as possible.
If you are lucky enough to have free PoE ports so that you can deploy the phones ahead of a cutover, do that. This lets you get the users logged in before the cutover, and still maintain their existing phone. The old phones can be collected after the cutover – this doesn’t require technical staff to do, nor any particular schedule.
If you need to do a phone swap at cutover time, you may be able to pre-configure the user devices. You’ll need an office, room or space for this, at least 1 PC or laptop, and some PoE network capacity. Users can logon to a phone in this area or room, then label the phone so you know where it needs to be deployed later.
Not having enough IT staff for a large phone deployment, or for a deployment in distant sites, is a challenge that often needs to be sorted. You’ll need to hire extra support or recruit some non-IT staff from the sites you’re deploying to. They’ll need to know the logon process for the phones, how to factory reset the phones (in case you need to “start again” with one, or if there’s a glitch), and to ensure the right jacks on the back of the phone are used (for the network and PC connections). This help could be all at cutover time, or you could use the phone pre-configuration approach followed by physical deployment, mentioned above.
If those options don’t work, you can help remotely. You may have to try and walk users through the steps over the phone. Have a PDF ready of the steps they’ll need to take, including a picture of the phone showing what keys they’d need to press/hold for a factory reset, what the ports on the bottom of the phone look like, and what the URL is that they’ll need to enter in their browser. You could take a step up from the phone call and do a Teams meeting with video using a USB webcam, so you can see what they’re seeing and doing rather than trying to have them describe what they see. This same document and set of steps will be helpful for your helpdesk team for the initial deployment efforts, as well as for ongoing support.
And lastly, if it’s possible to have the phones logged in and to remain powered up, you should head to Teams Admin Center and push firmware updates. If this isn’t possible, then do play for firmware updates to be pushed at the end of the business day for the site(s) you’ve deployed.
Restricting where a user can call internal to your organization is complex. If you must do this for compliance reasons, you need to take a look at Information Barriers.
One of the complexities is that in a Teams client the user can find another user by name and click to call them. They can do this same type of lookup on phones too.
Common Area Phones are more restricted than users, and it’s a simple policy change to allow or prohibit the lookup of users on a phone. We’ll typically see this restriction in place on phones in public areas, like a lobby courtesy phone. If you want to further restrict that public area phone can call by dialing numbers, you have just one option.
In a previous post, we talked about a Dial Plan normalization rule that would translate one phone number into a different, invalid phone number to prevent the original number from being called. If you want to restrict a CAP from calling anything other than one internal number, you can use the same procedure, but instead of the invalid number, translate all numbers to the number you want the phone to be able to call.
This sample rule allows the CAP to only call +14255551212, the security desk in my example:
And if I want the CAP to be able to call HR at 6789 and then have all other calls go to security, I could do something like this with two rules, since they’re processing in top-down sequence:
And you could add as many rules as you wanted, just make sure they’re above the ^(.*)$, which is the catch-all that should be at the bottom of the list.