Applying Teams Policies to a group
(Updated 4th Sept 2020: Use New-CsBatchPolicyPackageAssignmentOperation instead of Grant-CsUserPolicyPackage now)
I've recently needed to apply a PolicyPackage to a group of users (well 2 packages to 2 groups) using PowerShell - as the Teams Admin centre only allows you to apply to users by typing in all the names one at a time and pressing Add and discovered the New-CsGroupPolicyAssignment cmdlet, which looks good - however this applies a policy to a group, but I want to apply a policy package.
Instead we can use New-CsBatchPolicyPackageAssignmentOperation and pass it an array of UPNs (max 5000 in one go) along with the policy package name. Here's the environment: - Two groups set up in AD, synced to Azure AD, containing students and teachers (U AllStudents and U AllStaff). These aren't mail enabled, just synced security groups. - Students want to have the Secondary Student Policy Package - Teachers want to have the Teacher Policy Package
You will need the AzureAD and MicrosoftTeams modules, you can get this by running Install-Module AzureAD and Install-Module MicrosoftTeams in an elevated PowerShell window.
Once you're done, return to a non-elevated PowerShell and run the following:
Import-Module AzureAD
Import-Module MicrosoftTeams
Connect-AzureAD
Connect-MicrosoftTeams
$StaffUPNs = @()
$group = Get-AzureADGroupMember -All:$true -ObjectId ((Get-AzureADGroup -All:$true).Where{$_.DisplayName -eq "U AllStaff"}).objectID
foreach ($member in $group) {
Write-Host $member.UserPrincipalName
$StaffUPNs += $member.UserPrincipalName
}
New-CsBatchPolicyPackageAssignmentOperation -Identity $StaffUPNs -PackageName "Education_Teacher"
This brings all the members of the aforementioned group into an array, outputs them to screen so you can see what it's doing and then assigns the policy package to them. Same again for the students:
$StudentUPNs = @()
$group = Get-AzureADGroupMember -All:$true -ObjectId ((Get-AzureADGroup -All:$true).Where{$_.DisplayName -eq "U AllStudents"}).objectID
foreach ($member in $group) {
Write-Host $member.UserPrincipalName
$StudentUPNs += $member.UserPrincipalName
}
New-CsBatchPolicyPackageAssignmentOperation -Identity $StudentUPNs -PackageName "Education_SecondaryStudent"
This doesn't run straight away, it queues up a batch operation. To view the progress you can run Get-CsBatchPolicyAssignmentOperation but don't expect it to be quick.
Once your batch policy assignment has completed, if it's got a few errors you can expand the UserState value to see which have failed:
Get-CsBatchPolicyAssignmentOperation -OperationId ad64a258-5d99-4a8a-b77a-54474b55bea1 | Select -ExpandProperty UserState | Where {$_.Result -ne "Success"}
The next step I had issues with was preventing students from creating private channels. There's no setting for this within any of the policy packages, so you have to create a new Teams Policy (Teams Admin Centre -> Teams -> Policy). Create one called Student and set it to not permit private channel creation.
Applying this to all the students is a little more complicated, as it uses a cmdlet in the Skype for Business powershell module. This isn't in PSGallery so has to be downloaded and installed from https://www.microsoft.com/en-us/download/details.aspx?id=39366
Import-Module SkypeOnlineConnector
$sfbSession = New-CsOnlineSession
Import-PSSession $sfbSession
$group = Get-AzureADGroupMember -All:$true -ObjectId ((Get-AzureADGroup -All:$true).Where{$_.DisplayName -eq "U AllStudents"}).objectID
foreach ($member in $group) {
Write-Host $member.UserPrincipalName
Grant-CsTeamsChannelsPolicy -Identity $member.UserPrincipalName -PolicyName "Student"
}
This takes quite a while as it doesn't appear to accept arrays as a parameter (at least not according to the documentation). Similar to above this runs through all the students in the AzureAD U AllStudents group.
And that's about it really, took a couple of hours researching and trying various commands but saved me from manually typing hundreds of names into that, quite frankly awful, Teams Admin centre.