Bulk Policy Assignment for Teams Users

How to Assign a Teams Messaging Policy to Multiple Users

In yesterday’s post about disabling chat for Teams users, the conclusion was that assigning a messaging policy to users is the best approach. As explained in the post, it’s easy to create a policy. All the pain comes in assigning the policy to users, especially when this must be done for hundreds or even thousands of users.

Assigning a messaging policy to a single user is easy. Select the user in the Teams admin center, edit the policies assigned to their account, and make sure that the assigned messaging policy is the one which disables chat (Figure 1).

Assigning a no-chat messaging policy to a Teams user
Figure 1: Assigning a no-chat messaging policy to a Teams user

Using PowerShell to Assign a Messaging Policy

The same can be done with PowerShell using the Grant-CsTeamsMessagingPolicy cmdlet. This is loaded using the Skype for Business Online module (and soon, the Teams module). Here’s an example of assigning a messaging policy to a user:

Grant-CsTeamsMessagingPolicy -PolicyName "Restricted - No Chat" -Identity James.Joyce@office365itpros.com

Assigning Policies to Multiple Teams Users

The problem is how best to assign a policy to multiple Teams users. You could write a script to loop through a set of users and assign the policy with Grant-CsTeamsMessagingPolicy, but it’s easier to do this with a bulk (or batch) policy assignment, which runs a background job to assign a policy to multiple users.

Find the Target Users

The first thing to do is to determine the users we wish to assign the policy to. One way to approach the problem is to output a list of users to a CSV file, have someone edit the file to remove the accounts who should not be assigned the policy, and then use the edited CSV as the input for a bulk assignment of the messaging policy.

To create the CSV, run the Get-ExoMailbox cmdlet to fetch details of all mailboxes and then export the output to a CSV:

$Users = Get-ExoMailbox -RecipientTypeDetails UserMailbox | Select UserPrincipalName
$Users | Export-Csv -NoTypeInformation c:\temp\UsersToProcess.CSV

The CSV looks like the file shown in Figure 2. You should remove the entries for users who are not to be assigned the messaging policy and save the file.

Editing a CSV file to use as input for a Teams bulk policy assignment job
Figure 2: Editing a CSV file to use as input for a Teams bulk policy assignment job

Up to 5,000 accounts can be processed in a bulk policy assignment job, so if you have more than this number, you’ll need to split the accounts across several files.

Submit a Bulk Policy Assignment Job

To submit the job, we read the CSV file data into a list variable and process it to extract just the user principal names, which is what’s expected as input for a bulk assignment job.

$TargetUsers = Import-CSV c:\temp\UsersToProcess.CSV
$PolicyUsers = [System.Collections.Generic.List[Object]]::new()
ForEach ($U in $TargetUsers) { $PolicyUsers.Add($U.UserPrincipalName) }

Then call the New-CsBatchPolicyAssignmentOperation cmdlet to associate the policy we want to assign with the set of target users. The response is a GUID to identify the batch job:

New-CsBatchPolicyAssignmentOperation -PolicyType TeamsMessagingPolicy -PolicyName "Restricted – No Chat” -Identity $PolicyUsers -OperationName "Teams Messaging Policy Assignment"
d9458f56-e03e-4f3d-9620-1d348547fb3b

We can use the GUID as input to the Get-CsBatchPolicyAssignmentOperation cmdlet to track the progress of the job:

Get-CsBatchPolicyAssignmentOperation -OperationId d9458f56-e03e-4f3d-9620-1d348547fb3b | Format-List

OperationId     : d9458f56-e03e-4f3d-9620-1d348547fb3b
OperationName   : Teams Messaging Policy Assignment
OverallStatus   : NotStarted
CreatedBy       : 53f08764-07d4-418c-8403-a737a8fac7b3
CreatedTime     : 07/07/2020 17:34:37
CompletedTime   :
CompletedCount  : 0

It is normal that a little while elapses before the batch processor begins working on a job. Eventually, the job will start, and the policy assignments will happen. You can then find out what was done by running a command to fetch the status of each user:

Get-CsBatchPolicyAssignmentOperation -OperationId d9458f56-e03e-4f3d-9620-1d348547fb3b | Select -ExpandProperty UserState

Id                                   Result                  State
--                                   ------                  -----
Imran.Khan@Office365itpros.com       Success                 Completed
Jeff.Guillet@office365itpros.com     Success                 Completed
Marc.Vigneau@office365itpros.com     Success                 Completed
Jane.Sixsmith@office365itpros.com    Unknown error occurred. Completed

The error reported might be due to the account already being assigned the policy. This is easily checked by viewing the account through the Teams admin center to see what policy is assigned.

The Value of Bulk Assignment

Assigning Teams policies in background jobs is most advantageous when you have thousands of accounts to manage. But even if you have just a few hundred, you’ll still find that it’s easier to kick off a background job than to write some PowerShell to assign a policy to a bunch of users.


Struggling with the complexities of managing Microsoft Teams? Secure your copy of the Office 365 for IT Pros eBook and learn how to manage Teams effectively and efficiently.

3 Replies to “Bulk Policy Assignment for Teams Users”

  1. Hello Tony!

    There seems to be a small error in the example script. In the New-CsBatchPolicyAssignmentOperation commandlet, you process $TargetUsers, that should be $PolicyUsers, no?

    I also wonder why you do it this way and not Import-CSV users.CSV | Select -ExpandProperty UserPrincipalName
    There is more than one ways to skin a cat and I am new to Powershell, so I am curious if there is a particular reason to go the explicit route for building the list.

    1. Hi Martin,

      You’re right. That was a cut and paste error on my part.

      I wrote the code like that because I like sticking data into hash tables. It must have been automatic on my part. In any case, the important thing is that you provide a simple list of UPNs as input for the job, no matter how you generate it.

  2. I take it there’s no way to cancel a Batch Policy Assignment yet? I’ve got an incorrect assignment in the activity log, that hasn’t started 4 hours later. I’d love to be able to cancel it but can’t find a way to.

Leave a Reply

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