Table of Contents
Managing Microsoft 365 Group Settings with Container Management Labels
Container management labels are sensitivity labels configured with management controls that Microsoft 365 groups and their associated SharePoint Online sites and teams inherit from labels assigned on the creation of new groups or by administrators afterward. Important settings include external sharing of SharePoint content (Figure 1) and whether guest members are allowed in groups.

The settings inherited from assigned labels cannot by changed by group or team owners. However, a group owner can change the effective settings for a site by choosing to apply a different container management label. An organization can monitor for label assignments to groups and reserve those changes if necessary. However, this isn’t standard functionality and must be enabled using a tool like PowerShell (here’s an example).
Container Management Labels
Sensitivity labels are available in tenants licensed with Office 365 E3 or above. If you’re in this position, container management labels are an excellent way to ensure consistency in group settings. An organization can deploy and use container management labels even if they don’t use sensitivity labels for information protection and document marking. In fact, even though it’s possible to use the same set of sensitivity labels for both purposes, it’s a good idea to maintain two sets of labels: one for container management and the other for information protection.
Checking Container Management Label Assignments
Two PowerShell methods are available to check group information:
- The Get-UnifiedGroup cmdlet from the Exchange Online management module.
- The Get-MgGroup cmdlet from the Microsoft Graph PowerShell SDK.
Because it must fetch information for many aspects of a Microsoft 365 group, Get-UnifiedGroup is a “heavy” cmdlet. The cmdlet will find all groups, but it will be slow. Get-MgGroup is faster because it retrieves fewer properties for each group. The downside is that Get-MgGroup doesn’t include sensitivity labels in its set of properties. A separate Graph call is required to fetch the label assigned to a group.
To illustrate the point, this code finds all Microsoft 365 groups in a tenant and highlights any group that doesn’t have an assigned sensitivity label.
Connect-MgGraph -Scopes Directory.Read.All Write-Host "Finding Microsoft 365 Groups to process..." [array]$Groups = Get-MgGroup -Filter "groupTypes/any(c:c eq 'unified')" -All If (!($Groups)) { Write-Host "Whoops - can't find any Microsoft 365 Groups" ; break } ForEach ($Group in $Groups) { $LabelId = $Null; $LabelName = $Null $Uri = ("https://graph.microsoft.com/v1.0/groups/{0}?`$select=assignedLabels" -f $Group.Id) $LabelData = Invoke-GraphRequest -Uri $Uri $LabelName = $LabelData.assignedLabels.displayName $LabelId = $LabelData.assignedLabels.labelId [array]$GroupOwners = Get-MgGroupOwner -GroupId $Group.Id $GroupOwnerNames = $GroupOwners.additionalProperties.displayName -join ", " If (!($LabelName)) { Write-Host ("The {0} group has no label. Owner(s) {1}" -f $Group.displayName, $GroupOwnerNames) -foregroundcolor Red } } }
By contrast, Get-UnifiedGroup includes sensitivity label data in its properties. However, the property holds the GUID for an assigned sensitivity label instead of its display name. Some additional effort is required to resolve the label GUID to a display name by first fetching the set of sensitivity labels in the tenant (with the Get-Label cmdlet) and building a table of GUIDs and display names to lookup.
This code illustrates how to use the Get-UnifiedGroup cmdlet to accomplish the same goal:
Write-Host "Finding Microsoft 365 Groups to process..." [array]$Groups = Get-UnifiedGroup -ResultSize Unlimited If (!($Groups)) { Write-Host "Whoops - can't find any Microsoft 365 Groups" ; break } ForEach ($Group in $Groups) { [array]$GroupOwnerNames = $Null; $LabelId = $Null; $LabelName = $Null $LabelId = $Group.SensitivityLabel.Guid If ($LabelId) { $LabelName = $LabelHash[$LabelId] } [array]$GroupOwners = $Group.ManagedBy ForEach ($Owner in $GroupOwners) { [string]$Owner = $Owner $GroupOwnerNames += (Get-Mailbox -Identity $Owner -ErrorAction SilentlyContinue).DisplayName } [string]$GroupOwnerNames = $GroupOwnerNames -join ", " If (!($LabelName)) { Write-Host ("The {0} group has no label. Owner(s) {1}" -f $Group.displayName, $GroupOwnerNames) -foregroundcolor Red } }
The code doesn’t include the commands to connect to Exchange Online and the compliance endpoint (to get label information), nor does it include the code to build the hash table used for label lookups. These commands add about ten seconds of overhead. This isn’t usually a problem.
Testing against 250 groups, the Get-MgGroup method took 1 minute 12 seconds while Get-UnifiedGroup took 1 minute 28 seconds. Generally speaking, Graph-based cmdlets are always faster than the more complex cmdlets used by workloads like Exchange, especially when running at scale against thousands of objects.
Completing the Job
After deciding which approach to use, to finish the job, we put the results of the scan into a PowerShell list and generate a report. The final result is a little more complicated than the processing described above to format the output (Figure 2) and include some additional sections like listing groups that don’t have a label, groups that don’t have any owners, and summary data like how many assignments to groups for each label.

The final script is available from GitHub. Feel free to improve the output!
Learn how to exploit the data available to Microsoft 365 tenant administrators through the Office 365 for IT Pros eBook. We love figuring out how things work.
HI Tony,
Thanks for your scripts they have been very helpful. I was trying to add Customattribute14 to the report but I haven’t been able to, Please how do I add a tab for customattribute 14.
Thanks
Instead of:
$ReportLine = [PSCustomObject][Ordered]@{
Id = $Group.Id
Name = $Group.DisplayName
Owners = $GroupOwnerNames
Label = $LabelName
LabelId = $LabelId
Status = $Status }
Use:
$ReportLine = [PSCustomObject][Ordered]@{
Id = $Group.Id
Name = $Group.DisplayName
Owners = $GroupOwnerNames
Label = $LabelName
LabelId = $LabelId
State = $Group.CustomAttribute14
Status = $Status }
$Report.Add($ReportLine)
HI Tony
The state came out blank. Is there anything else I need to change. I forked your github repo to edit it from.
https://github.com/ayotec2015/Office365itpros/blob/master/Report-ContainerManagementLabels.PS1
Thanks for your assistance. I really enjoy reading your blog.
The problem (which I should have noticed) is that the script uses Get-MgGroup to find Microsoft 365 groups. Get-MgGroup doesn’t return the on-premises extension attributes like Get-MgUser does. In any case, I updated the code in your fork to use the Get-UnifiedGroup cmdlet instead. It works now.
Hey, Thanks for your response. I can’t seem to see any changes by you. The last changes was done by me 3hrs ago.. Did you forget to push 🙂
Check now.
HI Tony
Thanks I saw the changes you made. I tried similar but kept missing bits but all good with your help “).. Thanks for your help .. I also added a summary for mismatch label that compares _.LabelId -ne $Group.CustomAttribute14 Hopefully someone else will need it.