What it does
The set of ways a Teams policy reaches a user — Global default, direct assignment, group assignment with a rank, batch assignment, and policy packages that bundle several policy types at once. The effective policy is whichever source wins on precedence, and getting that order wrong is the single most common reason "the policy isn't working".
Key facts
- Precedence for a given policy type is: direct assignment (individual or batch) first, then group assignment, then Global (Org-wide default). A direct assignment blocks group inheritance completely until you remove it.
- Where a user sits in several groups with the same policy type, the group assignment with the highest rank wins. Rank 1 is highest; if you don't specify one, the assignment goes to the bottom.
- Ranks are relative to other group assignments of the same policy type. To change a rank you remove the group assignment and add it again.
- Group policy assignment works with Microsoft 365 groups, security groups and distribution lists. Microsoft recommends groups up to 50,000 users; larger groups work but take longer to propagate.
- Nested groups aren't supported — only direct members of the assigned group get the policy. Groups with
HiddenGroupMembershipenabled (Class Teams have it by default) aren't supported either. - Teams App Permission Policy and Teams Upgrade Policy don't support group policy assignment. Team templates policies don't either — individual or batch only.
- PowerShell:
Grant-Cs<PolicyType> -Group <GroupId> -PolicyName <name> -Rank <n>assigns to a group;Get-CsGroupPolicyAssignmentlists them;-PolicyName $nullremoves the group assignment. - Batch assignment uses
New-CsBatchPolicyAssignmentOperationwith a maximum of 5,000 users per batch, identified by object ID or SIP address. Track it withGet-CsBatchPolicyAssignmentOperation. - The Teams admin center can bulk unassign every directly assigned user from a policy (Users > Manage users > Actions > Unassign policies in bulk). Progress and history (last 30 days) show in Dashboard > Activity log.
- Policy packages bundle up to 11 policy types (messaging, meeting, app setup, calling, live events, call park, Teams, voice routing, caller ID, update, events). Microsoft ships prebuilt packages for education, frontline, healthcare, public safety and SMB roles.
- Custom policy packages need Teams Premium for the users they're assigned to. Edits to a package's policies apply to everyone already assigned that package.
When to use / skip
Group policy assignment should be your default for anything beyond a handful of exceptions. Tie policies to groups that already exist for a business reason — a department security group, a dynamic group off an HR attribute — and the joiner-mover-leaver process does the policy work for you. Direct assignment is fine for one-off exceptions and for scripting voice config per user, but every direct assignment is a landmine for the next admin who sets up a group assignment and wonders why it isn't taking.
Prebuilt policy packages are mostly useful in education and frontline deployments, or as a quick reference for what Microsoft thinks a sensible role policy looks like. In a corporate deployment you'll usually get more control from well-named individual policies assigned by group. Custom packages are tidy, but the Teams Premium dependency rules them out for most clients unless Premium is already being bought for other reasons.
Configuration decisions
- Which policy types stay on Global only and which get custom policies. Set Global to cover the majority, then build exceptions — not the other way round.
- Which groups drive assignment: existing security groups, dynamic groups from Entra attributes, or purpose-built "Teams policy" groups.
- A rank scheme per policy type, documented somewhere other than the admin center, so whoever adds the next group knows where it slots in.
- Whether to clean out legacy direct assignments (often left by migrations or old scripts) before moving to group-based assignment.
- Batch versus group for one-off bulk changes — batch is quicker to reason about for a migration cutover, group is better for steady state.
- Whether any client has Teams Premium broadly enough to justify custom policy packages.
Gotchas
- Direct wins, always. If a group assignment "isn't working", check
Get-CsUserPolicyAssignmentfor the user — nine times out of ten there's a direct assignment from an old script. - Nested groups don't flow. Someone will assign a policy to an all-staff group made of department groups and get zero effective users.
- Changing a rank means remove and re-add, which briefly drops the assignment for that group. Do it out of hours on anything that matters, such as calling or voice routing policies.
- Propagation is background work and scales with group size. Big groups can take hours; don't promise a cutover time based on how quickly the admin center accepts the change.
- Deleting a policy that's part of a package doesn't break the package — the policy gets recreated with the predefined settings next time the package is assigned, which can quietly reverse your changes.
- A package touches every policy type it contains, not only the ones you were thinking about. Assigned to a group (
Grant-CsGroupPolicyPackageAssignment) it needs a rank per policy type, so it can collide with your existing group ranks — test on a pilot user and check the effective result before going wide.
Consultant notes
- Before any group-assignment design, export current direct assignments per policy type and agree what gets cleared. The bulk unassign action in the admin center is the quickest way to do it.
- Keep a simple matrix in the design doc: policy type, policy name, assigned group, rank. It's the only way to answer "what will this user get?" without PowerShell.
- For Teams Phone rollouts, batch-assign voice routing and calling policies at cutover, then move to group assignment once the dust settles.
- Use dynamic groups where Entra attributes are reliable; check attribute quality first, because a bad department value puts users on the wrong meeting or calling policy.
- Give support a one-liner they can run:
Get-CsUserPolicyAssignment -Identity user@domainshows the source (direct or group) for each policy.
Worth revisiting if Microsoft adds nested group support or brings the remaining policy types into group assignment