Skip to content

Commit 8ea4175

Browse files
Merge pull request KelvinTegelaar#1458 from Jr7468/RecipientLimitStandard
Recipient limit standard
2 parents a602353 + 800d924 commit 8ea4175

2 files changed

Lines changed: 283 additions & 0 deletions

File tree

Lines changed: 103 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,103 @@
1+
function Invoke-CIPPStandardDeployMailContact {
2+
<#
3+
.FUNCTIONALITY
4+
Internal
5+
.COMPONENT
6+
(APIName) DeployMailContact
7+
.SYNOPSIS
8+
(Label) Deploy Mail Contact
9+
.DESCRIPTION
10+
(Helptext) Creates a new mail contact in Exchange Online across all selected tenants. The contact will be visible in the Global Address List.
11+
(DocsDescription) This standard creates a new mail contact in Exchange Online. Mail contacts are useful for adding external email addresses to your organization's address book. They can be used for distribution lists, shared mailboxes, and other collaboration scenarios.
12+
.NOTES
13+
CAT
14+
Exchange Standards
15+
TAG
16+
ADDEDCOMPONENT
17+
{"type":"textField","name":"standards.DeployMailContact.ExternalEmailAddress","label":"External Email Address","required":true}
18+
{"type":"textField","name":"standards.DeployMailContact.DisplayName","label":"Display Name","required":true}
19+
{"type":"textField","name":"standards.DeployMailContact.FirstName","label":"First Name","required":false}
20+
{"type":"textField","name":"standards.DeployMailContact.LastName","label":"Last Name","required":false}
21+
IMPACT
22+
Low Impact
23+
ADDEDDATE
24+
2025-05-28
25+
POWERSHELLEQUIVALENT
26+
New-MailContact
27+
RECOMMENDEDBY
28+
"CIPP"
29+
#>
30+
31+
param($Tenant, $Settings)
32+
33+
# Input validation
34+
if ([string]::IsNullOrWhiteSpace($Settings.DisplayName)) {
35+
Write-LogMessage -API 'Standards' -tenant $Tenant -message 'DeployMailContact: DisplayName cannot be empty or just whitespace.' -sev Error
36+
return
37+
}
38+
39+
try {
40+
$null = [System.Net.Mail.MailAddress]::new($Settings.ExternalEmailAddress)
41+
}
42+
catch {
43+
Write-LogMessage -API 'Standards' -tenant $Tenant -message "DeployMailContact: Invalid email address format: $($Settings.ExternalEmailAddress)" -sev Error
44+
return
45+
}
46+
47+
# Prepare contact data for reuse
48+
$ContactData = @{
49+
DisplayName = $Settings.DisplayName
50+
ExternalEmailAddress = $Settings.ExternalEmailAddress
51+
FirstName = $Settings.FirstName
52+
LastName = $Settings.LastName
53+
}
54+
55+
# Check if contact already exists
56+
try {
57+
$ExistingContact = New-ExoRequest -tenantid $Tenant -cmdlet 'Get-MailContact' -cmdParams @{
58+
Identity = $Settings.ExternalEmailAddress
59+
ErrorAction = 'Stop'
60+
}
61+
}
62+
catch {
63+
if ($_.Exception.Message -like "*couldn't be found*") {
64+
$ExistingContact = $null
65+
}
66+
else {
67+
Write-LogMessage -API 'Standards' -tenant $Tenant -message "Error checking for existing mail contact: $(Get-CippException -Exception $_).NormalizedError" -sev Error
68+
return
69+
}
70+
}
71+
72+
# Remediation
73+
if ($Settings.remediate -eq $true -and -not $ExistingContact) {
74+
try {
75+
$NewContactParams = $ContactData.Clone()
76+
$NewContactParams.Name = $Settings.DisplayName
77+
$null = New-ExoRequest -tenantid $Tenant -cmdlet 'New-MailContact' -cmdParams $NewContactParams
78+
Write-LogMessage -API 'Standards' -tenant $Tenant -message "Successfully created mail contact $($Settings.DisplayName) with email $($Settings.ExternalEmailAddress)" -sev Info
79+
}
80+
catch {
81+
Write-LogMessage -API 'Standards' -tenant $Tenant -message "Could not create mail contact. $(Get-CippException -Exception $_).NormalizedError" -sev Error
82+
}
83+
}
84+
85+
# Alert
86+
if ($Settings.alert -eq $true) {
87+
if ($ExistingContact) {
88+
Write-LogMessage -API 'Standards' -tenant $Tenant -message "Mail contact $($Settings.DisplayName) already exists" -sev Info
89+
}
90+
else {
91+
Write-StandardsAlert -message "Mail contact $($Settings.DisplayName) needs to be created" -object $ContactData -tenant $Tenant -standardName 'DeployMailContact' -standardId $Settings.standardId
92+
Write-LogMessage -API 'Standards' -tenant $Tenant -message "Mail contact $($Settings.DisplayName) needs to be created" -sev Info
93+
}
94+
}
95+
96+
# Report
97+
if ($Settings.report -eq $true) {
98+
$ReportData = $ContactData.Clone()
99+
$ReportData.Exists = [bool]$ExistingContact
100+
Add-CIPPBPAField -FieldName 'DeployMailContact' -FieldValue $ReportData -StoreAs json -Tenant $Tenant
101+
Set-CIPPStandardsCompareField -FieldName 'standards.DeployMailContact' -FieldValue $($ExistingContact ? $true : $ReportData) -Tenant $Tenant
102+
}
103+
}
Lines changed: 180 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,180 @@
1+
function Invoke-CIPPStandardMailboxRecipientLimits {
2+
<#
3+
.FUNCTIONALITY
4+
Internal
5+
.COMPONENT
6+
(APIName) MailboxRecipientLimits
7+
.SYNOPSIS
8+
(Label) Set Mailbox Recipient Limits
9+
.DESCRIPTION
10+
(Helptext) Sets the maximum number of recipients that can be specified in the To, Cc, and Bcc fields of a message for all mailboxes in the tenant.
11+
(DocsDescription) This standard configures the recipient limits for all mailboxes in the tenant. The recipient limit determines the maximum number of recipients that can be specified in the To, Cc, and Bcc fields of a message. This helps prevent spam and manage email flow.
12+
.NOTES
13+
CAT
14+
Exchange Standards
15+
TAG
16+
ADDEDCOMPONENT
17+
{"type":"number","name":"standards.MailboxRecipientLimits.RecipientLimit","label":"Recipient Limit","defaultValue":500}
18+
IMPACT
19+
Low Impact
20+
ADDEDDATE
21+
2025-05-28
22+
POWERSHELLEQUIVALENT
23+
Set-Mailbox -RecipientLimits
24+
RECOMMENDEDBY
25+
"CIPP"
26+
#>
27+
28+
param($Tenant, $Settings)
29+
30+
# Input validation
31+
if ([Int32]$Settings.RecipientLimit -lt 0 -or [Int32]$Settings.RecipientLimit -gt 10000) {
32+
Write-LogMessage -API 'Standards' -tenant $Tenant -message 'MailboxRecipientLimits: Invalid RecipientLimit parameter set. Must be between 0 and 10000.' -sev Error
33+
return
34+
}
35+
36+
# Get mailbox plans first
37+
$MailboxPlans = New-ExoRequest -tenantid $Tenant -cmdlet 'Get-MailboxPlan' -cmdParams @{ ResultSize = 'Unlimited' }
38+
39+
# Create a hashtable of mailbox plans for quick lookup
40+
$MailboxPlanLookup = @{}
41+
foreach ($Plan in $MailboxPlans) {
42+
$MailboxPlanLookup[$Plan.Guid] = $Plan
43+
}
44+
45+
# Get mailboxes that need updating (either different from target limit or have "Unlimited" set)
46+
$Requests = @(
47+
@{
48+
CmdletInput = @{
49+
CmdletName = 'Get-Mailbox'
50+
Parameters = @{
51+
ResultSize = 'Unlimited'
52+
Filter = "RecipientLimits -ne '$($Settings.RecipientLimit)' -or RecipientLimits -eq 'Unlimited'"
53+
}
54+
}
55+
}
56+
)
57+
58+
$Mailboxes = New-ExoBulkRequest -tenantid $Tenant -cmdletArray $Requests
59+
60+
# Process mailboxes and categorize them based on their plan limits
61+
$MailboxResults = $Mailboxes | ForEach-Object {
62+
$Mailbox = $_
63+
$Plan = $MailboxPlanLookup[$Mailbox.MailboxPlanId]
64+
65+
if ($Plan) {
66+
$PlanMaxRecipients = $Plan.MaxRecipientsPerMessage
67+
68+
# If mailbox has "Unlimited" set but has a plan, use the plan's limit as the current limit
69+
$CurrentLimit = if ($Mailbox.RecipientLimits -eq 'Unlimited') {
70+
$PlanMaxRecipients
71+
}
72+
else {
73+
$Mailbox.RecipientLimits
74+
}
75+
76+
if ($Settings.RecipientLimit -gt $PlanMaxRecipients) {
77+
[PSCustomObject]@{
78+
Type = 'PlanIssue'
79+
Mailbox = $Mailbox
80+
CurrentLimit = $CurrentLimit
81+
PlanLimit = $PlanMaxRecipients
82+
PlanName = $Plan.DisplayName
83+
}
84+
}
85+
elseif ($CurrentLimit -ne $Settings.RecipientLimit) {
86+
[PSCustomObject]@{
87+
Type = 'ToUpdate'
88+
Mailbox = $Mailbox
89+
}
90+
}
91+
}
92+
elseif ($Mailbox.RecipientLimits -ne $Settings.RecipientLimit) {
93+
[PSCustomObject]@{
94+
Type = 'ToUpdate'
95+
Mailbox = $Mailbox
96+
}
97+
}
98+
}
99+
100+
# Separate mailboxes into their respective categories
101+
$MailboxesToUpdate = $MailboxResults | Where-Object { $_.Type -eq 'ToUpdate' } | Select-Object -ExpandProperty Mailbox
102+
$MailboxesWithPlanIssues = $MailboxResults | Where-Object { $_.Type -eq 'PlanIssue' } | ForEach-Object {
103+
[PSCustomObject]@{
104+
Identity = $_.Mailbox.Identity
105+
CurrentLimit = $_.CurrentLimit
106+
PlanLimit = $_.PlanLimit
107+
PlanName = $_.PlanName
108+
}
109+
}
110+
111+
# Remediation
112+
if ($Settings.remediate -eq $true) {
113+
if ($MailboxesWithPlanIssues.Count -gt 0) {
114+
Write-LogMessage -API 'Standards' -tenant $Tenant -message "Found $($MailboxesWithPlanIssues.Count) mailboxes where the requested recipient limit ($($Settings.RecipientLimit)) exceeds their mailbox plan limit. These mailboxes will not be updated." -sev Info
115+
foreach ($Mailbox in $MailboxesWithPlanIssues) {
116+
Write-LogMessage -API 'Standards' -tenant $Tenant -message "Mailbox $($Mailbox.Identity) has plan $($Mailbox.PlanName) with maximum limit of $($Mailbox.PlanLimit)" -sev Info
117+
}
118+
}
119+
120+
if ($MailboxesToUpdate.Count -gt 0) {
121+
try {
122+
# Create batch requests for mailbox updates
123+
$UpdateRequests = $MailboxesToUpdate | ForEach-Object {
124+
@{
125+
CmdletInput = @{
126+
CmdletName = 'Set-Mailbox'
127+
Parameters = @{
128+
Identity = $_.Identity
129+
RecipientLimits = $Settings.RecipientLimit
130+
}
131+
}
132+
}
133+
}
134+
135+
# Execute batch update
136+
$null = New-ExoBulkRequest -tenantid $Tenant -cmdletArray $UpdateRequests
137+
Write-LogMessage -API 'Standards' -tenant $Tenant -message "Successfully set recipient limits to $($Settings.RecipientLimit) for $($MailboxesToUpdate.Count) mailboxes" -sev Info
138+
}
139+
catch {
140+
$ErrorMessage = Get-CippException -Exception $_
141+
Write-LogMessage -API 'Standards' -tenant $Tenant -message "Could not set recipient limits. $($ErrorMessage.NormalizedError)" -sev Error -LogData $ErrorMessage
142+
}
143+
}
144+
else {
145+
Write-LogMessage -API 'Standards' -tenant $Tenant -message "All mailboxes already have the correct recipient limit of $($Settings.RecipientLimit)" -sev Info
146+
}
147+
}
148+
149+
# Alert
150+
if ($Settings.alert -eq $true) {
151+
if ($MailboxesToUpdate.Count -eq 0 -and $MailboxesWithPlanIssues.Count -eq 0) {
152+
Write-LogMessage -API 'Standards' -tenant $Tenant -message "All mailboxes have the correct recipient limit of $($Settings.RecipientLimit)" -sev Info
153+
}
154+
else {
155+
$AlertMessage = "Found $($MailboxesToUpdate.Count) mailboxes with incorrect recipient limits"
156+
if ($MailboxesWithPlanIssues.Count -gt 0) {
157+
$AlertMessage += " and $($MailboxesWithPlanIssues.Count) mailboxes where the requested limit exceeds their mailbox plan limit"
158+
}
159+
Write-StandardsAlert -message $AlertMessage -object ($MailboxesToUpdate + $MailboxesWithPlanIssues) -tenant $Tenant -standardName 'MailboxRecipientLimits' -standardId $Settings.standardId
160+
Write-LogMessage -API 'Standards' -tenant $Tenant -message $AlertMessage -sev Info
161+
}
162+
}
163+
164+
# Report
165+
if ($Settings.report -eq $true) {
166+
$ReportData = @{
167+
MailboxesToUpdate = $MailboxesToUpdate
168+
MailboxesWithPlanIssues = $MailboxesWithPlanIssues
169+
}
170+
Add-CIPPBPAField -FieldName 'MailboxRecipientLimits' -FieldValue $ReportData -StoreAs json -Tenant $Tenant
171+
172+
if ($MailboxesToUpdate.Count -eq 0 -and $MailboxesWithPlanIssues.Count -eq 0) {
173+
$FieldValue = $true
174+
}
175+
else {
176+
$FieldValue = $ReportData
177+
}
178+
Set-CIPPStandardsCompareField -FieldName 'standards.MailboxRecipientLimits' -FieldValue $FieldValue -Tenant $Tenant
179+
}
180+
}

0 commit comments

Comments
 (0)