To export policy assignments in Microsoft Teams, list the user accounts with Get-CsOnlineUser and read each person's effective policies with Get-CsUserPolicyAssignment, which says whether each came directly or from a group. The cmdlet reads 1 person at a time, so a large tenant is slow, and a policy type it does not return is the Global (Org-wide default) policy.
| Method | Best fit |
|---|---|
| PowerShell | A CSV of every person's effective Teams policies and where each came from. |
| Admin centre | Checking 1 person's policies, or the groups a policy is assigned to. |
| Altivane | Recommended for recurring reviews, with every user's policies in 1 workbook and direct assignments listed apart. |
Before you start
Use an account with the Teams Administrator role, or Teams Reader to read without changing anything. The module needs Windows PowerShell 5.1 or PowerShell 7.2 or later. The example passes no permission or scope: its access is the signed-in account's role.
A person has 1 effective policy of each type. A policy assigned directly wins; without one, the highest ranked group assignment applies; without either, the Global (Org-wide default) policy applies. Group assignments reach direct members of the group only, not nested groups, and can take a while to reach everyone. The examples read and export; they assign or remove no policy.
Option 1
Export policy assignments with PowerShell
Install the module once, then connect and export 1 row for each person and policy type that is not the Global policy.
# Install once, if the module is not already installed.
Install-Module MicrosoftTeams -Scope CurrentUser$ErrorActionPreference = 'Stop'
Connect-MicrosoftTeams | Out-Null
try {
$filter = 'AccountType -eq ''User'' -and SoftDeletionTimestamp -eq $null'
$users = @(Get-CsOnlineUser -Filter $filter)
$report = @(foreach ($user in $users) {
$identity = $user.UserPrincipalName
if (-not $identity) { continue }
foreach ($policy in Get-CsUserPolicyAssignment -Identity $identity) {
$sources = @($policy.PolicySource | ForEach-Object {
"$($_.AssignmentType): $($_.PolicyName)"
})
[pscustomobject]@{
User = $identity
PolicyType = $policy.PolicyType
Policy = $policy.PolicyName
Sources = $sources -join '; '
}
}
})
if ($report.Count -eq 0) {
Write-Output "All $($users.Count) users have the Global policy of every type."
} else {
$report | Sort-Object User, PolicyType |
Export-Csv -Path './teams-policy-assignments.csv' -NoTypeInformation -Encoding utf8
Write-Output "$($report.Count) policy assignments for $($users.Count) users exported."
}
} finally {
Disconnect-MicrosoftTeams
}The CSV has 1 row for each person and policy type. Sources lists every assignment the person has for that type, such as Direct: Kiosk; Group: AllOn, so you can see a direct assignment that is hiding a group one. To read only 1 type, add -PolicyType TeamsMeetingPolicy to Get-CsUserPolicyAssignment.
List the groups a policy type is assigned to
Reconnect with Connect-MicrosoftTeams, then read the group assignments of 1 policy type with their ranking. The export above disconnects when it finishes.
# Run while connected to Microsoft Teams. Rank 1 wins over higher numbers.
Get-CsGroupPolicyAssignment -PolicyType TeamsMeetingPolicy |
Select-Object GroupId, PolicyType, PolicyName, RankOption 2
Review policy assignments in the admin centre
- Sign in to the Microsoft Teams admin centre for the correct tenant.
- Go to Users > Manage users, select a person and open the Policies tab to read the policies that apply to them.
- To see which groups a policy type is assigned to, go to its policy page, such as Meetings > Meeting policies, and select the Group policy assignment tab.
- Read each group with its ranking and policy.
- Leave each page without choosing Edit settings, Assign users, Add group or Remove, so nothing changes.
This suits checking 1 person, or 1 policy type's group assignments. It does not suit an export, since each person's policies are on their own page.
Option 3 ยท Recommended for recurring reviews
Run Altivane's Teams Users and Policies report
- Open Altivane and choose the tenant.
- Run the Teams Users and Policies report for Teams.
- Open the Excel workbook and read the table of the same name: each User with their Account type, Teams Phone, Phone numbers and Assigned policies, such as Meeting: AllOn; Messaging: Staff (through a group).
- For only the people given policies directly, build the tenant's documents with the Teams Users and Phones scorecard report in full and read Direct Policy Assignments.
Altivane reads every user's effective policies in 1 pass rather than 1 person at a time. Policy types that use Global are left out of Assigned policies, so a blank cell means the person has every default. Direct Policy Assignments also leaves out the Skype for Business types older accounts still carry. The report needs a tenant signed in with a certificate.
Contact usCommon questions
Why didn't a person get the policy assigned to their group?
A policy assigned directly to the person wins over any group assignment of the same type, so remove the direct one first. A group assignment also reaches only direct members of the group, and it can take some time to reach a large group.
Why is a policy type missing for a person?
Get-CsUserPolicyAssignment returns no row for a type when the person has the Global policy for it, either the tenant's own Global settings or Microsoft's default.
Which policy controls who people can chat with outside the organisation?
External access policies, assigned like any other Teams policy, narrow the organisation's external access settings for the people they apply to. To read those settings, see how to check external access settings in Microsoft Teams.
Microsoft references
Technical references checked on 6 November 2026. The example scripts have been reviewed and syntax checked; they have not been run against a live tenant.