Microsoft Teams Call Queue Agent Lists (And how to Force-Sync them)

The purpose of a call queue in Teams is to distribute incoming calls to multiple call agents. Every call queue stores its own “Agent List”…

The purpose of a call queue in Teams is to distribute incoming calls to multiple call agents. Every call queue stores its own “Agent List” which is basically just an array of Microsoft 365 users object Ids. Incoming Teams or PSTN calls are then distributed to the call queue’s agents. In this post, we’ll take a look at the types of agent lists which are available and how to configure them. We’ll also explore some useful tips how to cope with unexpected behavior during configuration.

Agent List Types

There are three (or four, depending how you look at it) different ways of adding Agents to a queue

  1. Direct user assignments

Users are assigned by display name and will be visible directly in a queue’s settings. This method is suitable for small teams because you can see who’s in the queue in TAC without checking the group members in M365 Admin or AAD. Since you can’t control the order agents will be added in when using a group or channel based agent list, direct assignments are crucial when your queue is using serial routing. You can add up to 20 agents individually.

2. Group assignments

With group assignments, you can add up to 200 agents but you can’t control the order in which the agents are added. Thus, you can’t control the order in which the users are signaled by the queue when using serial routing either. Based on my testing, the order of the agent list will correspond to the order in which the users show up when viewing it in AAD. Although it might not be a common scenario, you can even add multiple groups to the list. All common group types are supported.

3. Combination of direct and groups

If you want to use a group but still need to add other users which are not a member of this group, you can add them individually. Here I’ve got a group called “CQ Agents 1” which has two members.

I’ve also added Mike and Bobby as individual agents. Of course. the queue will add Mike only once.

Unfortunately, querying the queue’s agents only yields object Ids and no display names.

(Get-CsCallQueue -Identity a11d15d3-79d8-4bd2-8a35-xxxxxxxxxxxx).Agents

Output:

ObjectId                             OptIn  
--------                             -----  
76606d0b-4d28-4246-9c08-xxxxxxxxxxxx  True This is Bobby's Object Id  
9a7c1bb4-49db-40ee-9d05-xxxxxxxxxxxx  True This is Mike's Object Id  
fa19b242-8bae-419d-a4eb-xxxxxxxxxxxx  True This is Wendy's Object Id

As you can see, individually added agents will be first in the list, just like TAC is displaying it (individual agents above groups).

I have now replaced the direct assignment of Mike with Wendy and placed her on top.

When we query the agent list again, we can see that Wendy is on top now, even though she would be added last if we’re using just a group.

ObjectId                             OptIn  
--------                             -----  
fa19b242-8bae-419d-a4eb-xxxxxxxxxxxx  True This is Wendy's Object Id  
76606d0b-4d28-4246-9c08-xxxxxxxxxxxx  True This is Bobby's Object Id  
9a7c1bb4-49db-40ee-9d05-xxxxxxxxxxxx  True This is Mike's Object Id

4. Teams channel assignment

The third and last option is to use a Teams Channel. In this case, the group type obviously needs to be a Team. Private or shared channels are not supported. From an agent list perspective this method is the same as a group-based assignment, except that you can’t add individual members or multiple groups as well.

Summary and Caveats

In order for a user to be added as an agent, Enterprise Voice must be enabled. Having a Teams Phone Standard license is not enough. Unfortunately, there’s no straightforward way of checking if EV is enabled in TAC.

You might think that the “Phone System” Column in Teams Users will tell you that but that’s actually just evaluating if the user is licensed for Teams Phone Standard. (I hope Microsoft updates the column name at some point…).

When you try to add a user which is not EV enabled to a queue, TAC will throw an error message:

This is the only way I know of to check if a user is EV enabled or not through a GUI based tool. It’s easy in PS though:

Get-CsOnlineUser -Identity bill@domain.com | ft DisplayName,FeatureTypes,EnterpriseVoiceEnabled

Again, having a Teams Phone service plan, does not mean EV is enabled by default. A user’s feature types can be read from the .FeatureTypes attribute (Teams PS 4.x.x and later).

DisplayName FeatureTypes         EnterpriseVoiceEnabled  
----------- ------------         ----------------------  
Bill Stearn {PhoneSystem, Teams}                  False

Does this mean we can only add groups to an agent list if all the members are already EV enabled? Certainly not. In this case, only EV enabled members will be added to a queue but you won’t see any warnings or errors if your group contains users without EV.

I’ve added Bill to the “CQ Agents 1” group:

Let’s check our queue again by storing it’s properties in the variable $cq:

1
$cq = Get-CsCallQueue -Identity a11d15d3-79d8-4bd2-8a35-xxxxxxxxxxxx

By accessing $cq.DistributionListsLastExpanded we can verify that the queue has indeed updated its agent list when we saved it.

As expected, the object Id of bill does not show up when we check $cq.Agents. I’ve also removed the direct assignments, that’s why we only see two object Ids now.

ObjectId                             OptIn  
--------                             -----  
fa19b242-8bae-419d-a4eb-xxxxxxxxxxxx  True That's Wendy's Object Id  
9a7c1bb4-49db-40ee-9d05-xxxxxxxxxxxx  True That's Mike's Object Id

What’s interesting is that even though the direct assignments were removed, the queue remembered the specific order we defined using direct assignments before. Wendy is still above mike.

No matter in which way the agents are added, in the end, all EV enabled agents will always be stored in one single array on the queue’s properties in the “Agents” attribute.

Agent List Sync

Now you know what types of agent lists you can have and how to configure them. Let’s talk about syncing agent lists. With direct assignments, it’s easy. Every time you add or remove an agent and save the queue, the agent list is updated immediately.

If you’re adding a group which already has a bunch of users in it, that’s no problem either. But what about if you add a Team or a group which does not have any members yet, or if you add new users to an existing group which is already linked to a queue?

I created a new, empty Team called “PS Test CQ” and added it to the queue’s agent list. As expected, TAC now says that this queue has zero agents.

So, let’s head over to Teams and add some members. After a browser refresh, TAC still shows zero call agents. Let’s check again with PowerShell:

(Get-CsCallQueue -Identity a11d15d3-79d8-4bd2-8a35-xxxxxxxxxxxx) | ft Name, DistributionListsLastExpanded, Agents

Although the output at least tells us when the agent list was last synchronized, it also shows no agents:

Name       DistributionListsLastExpanded Agents  
----       ----------------------------- ------  
PS Test CQ 04/10/2022 09:12:22 +00:00    {}

I don’t know the exact interval Teams uses to sync call queue agent lists. But I’m guessing it checks every few hours or so. Is there a way to force a sync?

Force Agent List Sync using TAC

If we’re doing it via TAC, we must change any value of the queue to be able to save it. Otherwise, the submit button will be greyed out.

If you want to do it via TAC, I recommend changing a non-critical value like up the overflow threshold value by 1 and submit.

This will submit the new configuration which will also update the agent list. Now our queue has 1 agent (the one we added to the Team earlier).

To minimize service impact, remember to revert the change back to its original value and submit again.

Since TAC evaluates if you changed anything before you’re allowed to save the queue and you always have to save the queue twice to force a sync, this is a pretty cumbersome way to do it.

Force Agent List Sync by PowerShell

Update 05.04.2023

I wrote a new function to make this even easier. Please check out this article.

Manage Microsoft Teams Call Queues with PowerShell (Force-Sync) | by martin heusser | Apr, 2023 | Medium

/Update

Luckily, PowerShell allows us to save queues, even if none of the values have changed. To test this, I’ve added another EV enabled user to the Team.

With this little code snippet, we will get all our call queues and set the OverflowThreshold value to the exact same value which was returned by PowerShell.

To use Set-CsCallQueue we need to provide at least one property and a value which should be changed. But unlike TAC, PS doesn’t care if the new value is the same as the old value. Hence, we only need to touch each queue once.

Tip: If you only want to sync queues which have no agents at all, just change the first line to:

$callQueues = Get-CsCallQueue | Where-Object {$_.Agents.Count -lt 1}

After running this foreach loop, our queue now shows two agents, and all the other queues settings remain unchanged.

Addendum

There’s also a Cmdlet called “Sync-CsOnlineApplicationInstance”. Microsoft says the following:

Use the Sync-CsOnlineApplicationInstance cmdlet to sync the application instance from Azure Active Directory into Agent Provisioning Service.

Based on my testing, this had no effect on a queue’s agent list. Since it’s also the only Cmdlet containing *Sync-Cs* in its name, I assume that there currently is no easier workaround as the one described by me in this blog post.

I hope that this information is useful to you when planning and deploying Microsoft Teams Phone solutions. But most importantly, I hope that you don’t get chills when all your queues show up with no agents even though you long added the Team or group members!

Licensed under CC BY-NC-SA 4.0
comments powered by Disqus
Hosted on GitHub Pages
Built with Hugo
Theme Stack designed by Jimmy