Skip to content

Commit 1072570

Browse files
AllowedToCreateGroups
1 parent ffd1d69 commit 1072570

2 files changed

Lines changed: 91 additions & 29 deletions

File tree

Config/standards.json

Lines changed: 17 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1459,10 +1459,23 @@
14591459
"cat": "Entra (AAD) Standards",
14601460
"tag": ["CISA (MS.AAD.21.1v1)", "SMB1001 (2.8)"],
14611461
"appliesToTest": ["SMB1001_2_8", "ZTNA21868"],
1462-
"helpText": "Restricts M365 group creation to certain admin roles. This disables the ability to create Teams, SharePoint sites, Planner, etc",
1463-
"docsDescription": "Users by default are allowed to create M365 groups. This restricts M365 group creation to certain admin roles. This disables the ability to create Teams, SharePoint sites, Planner, etc",
1464-
"executiveText": "Restricts the creation of Microsoft 365 groups, Teams, and SharePoint sites to authorized administrators, preventing uncontrolled proliferation of collaboration spaces. This ensures proper governance, naming conventions, and resource management while maintaining oversight of all collaborative environments.",
1465-
"addedComponent": [],
1462+
"helpText": "Restricts M365 group creation to certain admin roles. This disables the ability to create Teams, SharePoint sites, Planner, etc. Optionally allows members of a specific security group to keep creating groups (GroupCreationAllowedGroupId).",
1463+
"docsDescription": "Users by default are allowed to create M365 groups. This restricts M365 group creation to certain admin roles. This disables the ability to create Teams, SharePoint sites, Planner, etc. Optionally, a security group can be named whose members remain allowed to create groups; the group is resolved by display name in each tenant and can be created automatically when it does not exist. When no group is named, the existing GroupCreationAllowedGroupId value in the tenant is left untouched.",
1464+
"executiveText": "Restricts the creation of Microsoft 365 groups, Teams, and SharePoint sites to authorized administrators, preventing uncontrolled proliferation of collaboration spaces. This ensures proper governance, naming conventions, and resource management while maintaining oversight of all collaborative environments. An approved group of designated users can optionally retain the ability to create groups.",
1465+
"addedComponent": [
1466+
{
1467+
"type": "textField",
1468+
"name": "standards.DisableM365GroupUsers.AllowedGroupName",
1469+
"label": "Optional: name of the group whose members may still create M365 groups",
1470+
"required": false
1471+
},
1472+
{
1473+
"type": "switch",
1474+
"name": "standards.DisableM365GroupUsers.CreateGroup",
1475+
"label": "Create the allowed group if it does not exist",
1476+
"required": false
1477+
}
1478+
],
14661479
"label": "Disable M365 Group creation by users",
14671480
"impact": "Low Impact",
14681481
"impactColour": "info",

Modules/CIPPStandards/Public/Standards/Invoke-CIPPStandardDisableM365GroupUsers.ps1

Lines changed: 74 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -7,17 +7,19 @@ function Invoke-CIPPStandardDisableM365GroupUsers {
77
.SYNOPSIS
88
(Label) Disable M365 Group creation by users
99
.DESCRIPTION
10-
(Helptext) Restricts M365 group creation to certain admin roles. This disables the ability to create Teams, SharePoint sites, Planner, etc
11-
(DocsDescription) Users by default are allowed to create M365 groups. This restricts M365 group creation to certain admin roles. This disables the ability to create Teams, SharePoint sites, Planner, etc
10+
(Helptext) Restricts M365 group creation to certain admin roles. This disables the ability to create Teams, SharePoint sites, Planner, etc. Optionally allows members of a specific security group to keep creating groups (GroupCreationAllowedGroupId).
11+
(DocsDescription) Users by default are allowed to create M365 groups. This restricts M365 group creation to certain admin roles. This disables the ability to create Teams, SharePoint sites, Planner, etc. Optionally, a security group can be named whose members remain allowed to create groups; the group is resolved by display name in each tenant and can be created automatically when it does not exist. When no group is named, the existing GroupCreationAllowedGroupId value in the tenant is left untouched.
1212
.NOTES
1313
CAT
1414
Entra (AAD) Standards
1515
TAG
1616
"CISA (MS.AAD.21.1v1)"
1717
"ZTNA21868"
1818
EXECUTIVETEXT
19-
Restricts the creation of Microsoft 365 groups, Teams, and SharePoint sites to authorized administrators, preventing uncontrolled proliferation of collaboration spaces. This ensures proper governance, naming conventions, and resource management while maintaining oversight of all collaborative environments.
19+
Restricts the creation of Microsoft 365 groups, Teams, and SharePoint sites to authorized administrators, preventing uncontrolled proliferation of collaboration spaces. This ensures proper governance, naming conventions, and resource management while maintaining oversight of all collaborative environments. An approved group of designated users can optionally retain the ability to create groups.
2020
ADDEDCOMPONENT
21+
{"type":"textField","name":"standards.DisableM365GroupUsers.AllowedGroupName","label":"Optional: name of the group whose members may still create M365 groups","required":false}
22+
{"type":"switch","name":"standards.DisableM365GroupUsers.CreateGroup","label":"Create the allowed group if it does not exist","required":false}
2123
IMPACT
2224
Low Impact
2325
ADDEDDATE
@@ -55,21 +57,74 @@ function Invoke-CIPPStandardDisableM365GroupUsers {
5557
return
5658
}
5759

60+
# Optional: a group whose members remain allowed to create M365 groups
61+
# (GroupCreationAllowedGroupId). Resolved by display name per tenant, since group ids
62+
# differ between tenants. When no name is configured the setting is left untouched,
63+
# which keeps existing deployments unchanged.
64+
$AllowedGroupName = [string]$Settings.AllowedGroupName
65+
$DesiredGroupId = $null
66+
if (-not [string]::IsNullOrWhiteSpace($AllowedGroupName)) {
67+
try {
68+
$GroupFilter = [System.Uri]::EscapeDataString("displayName eq '$($AllowedGroupName -replace "'", "''")'")
69+
$AllowedGroup = @(New-GraphGetRequest -Uri "https://graph.microsoft.com/beta/groups?`$filter=$GroupFilter&`$select=id,displayName" -tenantid $Tenant)
70+
if ($AllowedGroup.Count -gt 1) {
71+
Write-LogMessage -API 'Standards' -tenant $Tenant -message "Multiple groups named '$AllowedGroupName' found, using the first match ($($AllowedGroup[0].id))." -sev Warning
72+
}
73+
$DesiredGroupId = $AllowedGroup | Select-Object -First 1 -ExpandProperty id
74+
} catch {
75+
$ErrorMessage = Get-NormalizedError -Message $_.Exception.Message
76+
Write-LogMessage -API 'Standards' -tenant $Tenant -message "Could not resolve the allowed group '$AllowedGroupName': $ErrorMessage" -sev Error
77+
}
78+
}
79+
80+
$CurrentEnableGroupCreation = ($CurrentState.values | Where-Object { $_.name -eq 'EnableGroupCreation' }).value
81+
$CurrentAllowedGroupId = ($CurrentState.values | Where-Object { $_.name -eq 'GroupCreationAllowedGroupId' }).value
82+
$CreationDisabled = $CurrentEnableGroupCreation -eq 'false'
83+
# Only enforce the allowed group when one is configured; a configured name that cannot be
84+
# resolved (and is not set for creation) counts as non-compliant so it surfaces in alerts
85+
$AllowedGroupCorrect = [string]::IsNullOrWhiteSpace($AllowedGroupName) -or ($DesiredGroupId -and $CurrentAllowedGroupId -eq $DesiredGroupId)
86+
$StateIsCorrect = $CreationDisabled -and $AllowedGroupCorrect
87+
5888
if ($Settings.remediate -eq $true) {
59-
if (($CurrentState.values | Where-Object { $_.name -eq 'EnableGroupCreation' }).value -eq 'false') {
89+
if ($StateIsCorrect) {
6090
Write-LogMessage -API 'Standards' -tenant $tenant -message 'Users are already disabled from creating M365 Groups.' -sev Info
6191
} else {
6292
try {
93+
# Create the allowed group when requested and it does not exist yet
94+
if (-not [string]::IsNullOrWhiteSpace($AllowedGroupName) -and -not $DesiredGroupId -and $Settings.CreateGroup -eq $true) {
95+
$GroupUsername = ($AllowedGroupName -replace '[^a-zA-Z0-9]', '')
96+
if ($GroupUsername.Length -gt 64) { $GroupUsername = $GroupUsername.Substring(0, 64) }
97+
$GroupObject = @{
98+
groupType = 'generic'
99+
displayName = $AllowedGroupName
100+
username = $GroupUsername
101+
securityEnabled = $true
102+
}
103+
$NewGroup = New-CIPPGroup -GroupObject $GroupObject -TenantFilter $Tenant -APIName 'Standards'
104+
$DesiredGroupId = $NewGroup.GroupId
105+
Write-LogMessage -API 'Standards' -tenant $Tenant -message "Created group '$AllowedGroupName' ($DesiredGroupId) for allowed M365 group creation." -sev Info
106+
}
107+
if (-not [string]::IsNullOrWhiteSpace($AllowedGroupName) -and -not $DesiredGroupId) {
108+
Write-LogMessage -API 'Standards' -tenant $Tenant -message "The allowed group '$AllowedGroupName' does not exist in the tenant and 'Create the allowed group' is not enabled. Group creation will be disabled without an allowed group." -sev Warning
109+
}
110+
63111
if (!$CurrentState) {
64112
# If no current configuration is found, we set it to the default template supplied by MS.
65113
$CurrentState = '{"id":"","displayName":"Group.Unified","templateId":"62375ab9-6b52-47ed-826b-58e47e0e304b","values":[{"name":"NewUnifiedGroupWritebackDefault","value":"true"},{"name":"EnableMIPLabels","value":"false"},{"name":"CustomBlockedWordsList","value":""},{"name":"EnableMSStandardBlockedWords","value":"false"},{"name":"ClassificationDescriptions","value":""},{"name":"DefaultClassification","value":""},{"name":"PrefixSuffixNamingRequirement","value":""},{"name":"AllowGuestsToBeGroupOwner","value":"false"},{"name":"AllowGuestsToAccessGroups","value":"true"},{"name":"GuestUsageGuidelinesUrl","value":""},{"name":"GroupCreationAllowedGroupId","value":""},{"name":"AllowToAddGuests","value":"true"},{"name":"UsageGuidelinesUrl","value":""},{"name":"ClassificationList","value":""},{"name":"EnableGroupCreation","value":"true"}]}'
66114
New-GraphPostRequest -tenantid $tenant -Uri "https://graph.microsoft.com/beta/settings/$($CurrentState.id)" -AsApp $true -Type POST -Body $CurrentState -ContentType 'application/json'
67115
$CurrentState = (New-GraphGetRequest -Uri 'https://graph.microsoft.com/beta/settings' -tenantid $tenant) | Where-Object -Property displayname -EQ 'Group.unified'
68116
}
69117
($CurrentState.values | Where-Object { $_.name -eq 'EnableGroupCreation' }).value = 'false'
118+
if ($DesiredGroupId) {
119+
($CurrentState.values | Where-Object { $_.name -eq 'GroupCreationAllowedGroupId' }).value = "$DesiredGroupId"
120+
}
70121
$body = "{values : $($CurrentState.values | ConvertTo-Json -Compress)}"
71122
$null = New-GraphPostRequest -tenantid $tenant -asApp $true -Uri "https://graph.microsoft.com/beta/settings/$($CurrentState.id)" -Type patch -Body $body -ContentType 'application/json'
72-
Write-LogMessage -API 'Standards' -tenant $tenant -message 'Disabled users from creating M365 Groups.' -sev Info
123+
if ($DesiredGroupId) {
124+
Write-LogMessage -API 'Standards' -tenant $tenant -message "Disabled users from creating M365 Groups. Members of '$AllowedGroupName' remain allowed to create groups." -sev Info
125+
} else {
126+
Write-LogMessage -API 'Standards' -tenant $tenant -message 'Disabled users from creating M365 Groups.' -sev Info
127+
}
73128
} catch {
74129
$ErrorMessage = Get-NormalizedError -Message $_.Exception.Message
75130
Write-LogMessage -API 'Standards' -tenant $tenant -message "Failed to disable users from creating M365 Groups: $ErrorMessage" -sev 'Error'
@@ -78,38 +133,32 @@ function Invoke-CIPPStandardDisableM365GroupUsers {
78133
}
79134
if ($Settings.alert -eq $true) {
80135

81-
if ($CurrentState) {
82-
if (($CurrentState.values | Where-Object { $_.name -eq 'EnableGroupCreation' }).value -eq 'false') {
83-
Write-LogMessage -API 'Standards' -tenant $tenant -message 'Users are disabled from creating M365 Groups.' -sev Info
84-
} else {
85-
Write-StandardsAlert -message 'Users are not disabled from creating M365 Groups.' -object $CurrentState -tenant $tenant -standardName 'DisableM365GroupUsers' -standardId $Settings.standardId
86-
Write-LogMessage -API 'Standards' -tenant $tenant -message 'Users are not disabled from creating M365 Groups.' -sev Info
87-
}
136+
if ($StateIsCorrect) {
137+
Write-LogMessage -API 'Standards' -tenant $tenant -message 'Users are disabled from creating M365 Groups.' -sev Info
138+
} elseif ($CreationDisabled -and -not $AllowedGroupCorrect) {
139+
Write-StandardsAlert -message "Users are disabled from creating M365 Groups, but the allowed group '$AllowedGroupName' is not configured as GroupCreationAllowedGroupId." -object ($CurrentState ?? @{CurrentState = $null }) -tenant $tenant -standardName 'DisableM365GroupUsers' -standardId $Settings.standardId
140+
Write-LogMessage -API 'Standards' -tenant $tenant -message "Users are disabled from creating M365 Groups, but the allowed group '$AllowedGroupName' is not configured." -sev Info
88141
} else {
89-
Write-StandardsAlert -message 'Users are not disabled from creating M365 Groups.' -object @{CurrentState = $null } -tenant $tenant -standardName 'DisableM365GroupUsers' -standardId $Settings.standardId
142+
Write-StandardsAlert -message 'Users are not disabled from creating M365 Groups.' -object ($CurrentState ?? @{CurrentState = $null }) -tenant $tenant -standardName 'DisableM365GroupUsers' -standardId $Settings.standardId
90143
Write-LogMessage -API 'Standards' -tenant $tenant -message 'Users are not disabled from creating M365 Groups.' -sev Info
91144
}
92145
}
93146
if ($Settings.report -eq $true) {
94-
if ($CurrentState) {
95-
if (($CurrentState.values | Where-Object { $_.name -eq 'EnableGroupCreation' }).value -eq 'false') {
96-
$CurrentState = $true
97-
} else {
98-
$CurrentState = $false
99-
}
100-
} else {
101-
$CurrentState = $false
102-
}
103-
104147
$CurrentValue = [PSCustomObject]@{
105-
M365GroupUserCreationDisabled = $CurrentState
148+
M365GroupUserCreationDisabled = $CreationDisabled
106149
}
107150
$ExpectedValue = [PSCustomObject]@{
108151
M365GroupUserCreationDisabled = $true
109152
}
153+
# Only include the allowed-group comparison when a group is configured, so existing
154+
# deployments without one keep their original compare shape (backward compatible)
155+
if (-not [string]::IsNullOrWhiteSpace($AllowedGroupName)) {
156+
$CurrentValue | Add-Member -NotePropertyName AllowedCreationGroupCorrect -NotePropertyValue ([bool]$AllowedGroupCorrect)
157+
$ExpectedValue | Add-Member -NotePropertyName AllowedCreationGroupCorrect -NotePropertyValue $true
158+
}
110159

111160
Set-CIPPStandardsCompareField -FieldName 'standards.DisableM365GroupUsers' -CurrentValue $CurrentValue -ExpectedValue $ExpectedValue -TenantFilter $Tenant
112-
Add-CIPPBPAField -FieldName 'DisableM365GroupUsers' -FieldValue $CurrentState -StoreAs bool -Tenant $tenant
161+
Add-CIPPBPAField -FieldName 'DisableM365GroupUsers' -FieldValue $StateIsCorrect -StoreAs bool -Tenant $tenant
113162
}
114163

115164
}

0 commit comments

Comments
 (0)