Skip to content

Commit adf260d

Browse files
committed
feat: Add new Set Exchange Outbound Spam Limits standard
1 parent 316755d commit adf260d

File tree

1 file changed

+112
-0
lines changed

1 file changed

+112
-0
lines changed
Lines changed: 112 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,112 @@
1+
function Invoke-CIPPStandardEXOOutboundSpamLimits {
2+
<#
3+
.FUNCTIONALITY
4+
Internal
5+
.COMPONENT
6+
(APIName) EXOOutboundSpamLimits
7+
.SYNOPSIS
8+
(Label) Set Exchange Outbound Spam Limits
9+
.DESCRIPTION
10+
(Helptext) Configures the outbound spam recipient limits (external per hour, internal per hour, per day) and the action to take when a limit is reached. The 'Set Outbound Spam Alert e-mail' standard is recommended to configure together with this one.
11+
(DocsDescription) Configures the Exchange Online outbound spam recipient limits for external per hour, internal per hour, and per day, along with the action to take (e.g., BlockUser, Alert) when these limits are exceeded. This helps prevent abuse and manage email flow. Microsoft's recommendations can be found [here.](https://learn.microsoft.com/en-us/defender-office-365/recommended-settings-for-eop-and-office365#eop-outbound-spam-policy-settings) The 'Set Outbound Spam Alert e-mail' standard is recommended to configure together with this one.
12+
.NOTES
13+
CAT
14+
Exchange Standards
15+
TAG
16+
"CIS"
17+
ADDEDCOMPONENT
18+
{"type":"number","name":"standards.EXOOutboundSpamLimits.RecipientLimitExternalPerHour","label":"External Recipient Limit Per Hour","defaultValue":400}
19+
{"type":"number","name":"standards.EXOOutboundSpamLimits.RecipientLimitInternalPerHour","label":"Internal Recipient Limit Per Hour","defaultValue":800}
20+
{"type":"number","name":"standards.EXOOutboundSpamLimits.RecipientLimitPerDay","label":"Daily Recipient Limit","defaultValue":800}
21+
{"type":"autoComplete","multiple":false,"creatable":false,"name":"standards.EXOOutboundSpamLimits.ActionWhenThresholdReached","label":"Action When Threshold Reached","options":[{"label":"Alert","value":"Alert"},{"label":"Block User","value":"BlockUser"},{"label":"Block user from sending mail for the rest of the day","value":"BlockUserForToday"}]}
22+
IMPACT
23+
Low Impact
24+
ADDEDDATE
25+
2025-05-13
26+
POWERSHELLEQUIVALENT
27+
Set-HostedOutboundSpamFilterPolicy
28+
RECOMMENDEDBY
29+
"CIPP"
30+
"CIS"
31+
UPDATECOMMENTBLOCK
32+
Run the Tools\Update-StandardsComments.ps1 script to update this comment block
33+
.LINK
34+
https://docs.cipp.app/user-documentation/tenant/standards/list-standards/exchange-standards#low-impact
35+
#>
36+
37+
param($Tenant, $Settings)
38+
39+
# Make sure it handles the frontend being both autocomplete and a text field
40+
$ActionWhenThresholdReached = $Settings.ActionWhenThresholdReached.value ?? $Settings.ActionWhenThresholdReached
41+
42+
# Input validation
43+
if ([Int32]$Settings.RecipientLimitExternalPerHour -lt 0 -or [Int32]$Settings.RecipientLimitExternalPerHour -gt 10000) {
44+
Write-LogMessage -API 'Standards' -tenant $Tenant -message 'EXOOutboundSpamLimits: Invalid RecipientLimitExternalPerHour parameter set. Must be between 0 and 10000.' -sev Error
45+
return
46+
}
47+
48+
if ([Int32]$Settings.RecipientLimitInternalPerHour -lt 0 -or [Int32]$Settings.RecipientLimitInternalPerHour -gt 10000) {
49+
Write-LogMessage -API 'Standards' -tenant $Tenant -message 'EXOOutboundSpamLimits: Invalid RecipientLimitInternalPerHour parameter set. Must be between 0 and 10000.' -sev Error
50+
return
51+
}
52+
53+
if ([Int32]$Settings.RecipientLimitPerDay -lt 0 -or [Int32]$Settings.RecipientLimitPerDay -gt 10000) {
54+
Write-LogMessage -API 'Standards' -tenant $Tenant -message 'EXOOutboundSpamLimits: Invalid RecipientLimitPerDay parameter set. Must be between 0 and 10000.' -sev Error
55+
return
56+
}
57+
58+
$ValidActions = @('Alert', 'BlockUser', 'BlockUserForToday')
59+
if ($ActionWhenThresholdReached -notin $ValidActions) {
60+
Write-LogMessage -API 'Standards' -tenant $Tenant -message 'EXOOutboundSpamLimits: Invalid ActionWhenThresholdReached parameter set. Must be one of: Alert, BlockUser, BlockUserForToday.' -sev Error
61+
return
62+
}
63+
64+
# Get current settings
65+
$CurrentInfo = New-ExoRequest -tenantid $Tenant -cmdlet 'Get-HostedOutboundSpamFilterPolicy' -cmdParams @{Identity = 'Default' } -Select 'RecipientLimitExternalPerHour, RecipientLimitInternalPerHour, RecipientLimitPerDay, ActionWhenThresholdReached' -useSystemMailbox $true | Select-Object -ExcludeProperty *data.type*
66+
67+
# Check if settings are already correct
68+
$StateIsCorrect = ($CurrentInfo.RecipientLimitExternalPerHour -eq $Settings.RecipientLimitExternalPerHour) -and
69+
($CurrentInfo.RecipientLimitInternalPerHour -eq $Settings.RecipientLimitInternalPerHour) -and
70+
($CurrentInfo.RecipientLimitPerDay -eq $Settings.RecipientLimitPerDay) -and
71+
($CurrentInfo.ActionWhenThresholdReached -eq $ActionWhenThresholdReached)
72+
73+
# Remediation
74+
If ($Settings.remediate -eq $true) {
75+
Write-Host 'Time to remediate'
76+
if ($StateIsCorrect -eq $false) {
77+
try {
78+
$null = New-ExoRequest -tenantid $Tenant -cmdlet 'Set-HostedOutboundSpamFilterPolicy' -cmdParams @{
79+
Identity = 'Default'
80+
RecipientLimitExternalPerHour = $Settings.RecipientLimitExternalPerHour
81+
RecipientLimitInternalPerHour = $Settings.RecipientLimitInternalPerHour
82+
RecipientLimitPerDay = $Settings.RecipientLimitPerDay
83+
ActionWhenThresholdReached = $ActionWhenThresholdReached
84+
} -useSystemMailbox $true
85+
86+
Write-LogMessage -API 'Standards' -tenant $Tenant -message "Set outbound spam limits: External=$($Settings.RecipientLimitExternalPerHour), Internal=$($Settings.RecipientLimitInternalPerHour), Daily=$($Settings.RecipientLimitPerDay), Action=$($ActionWhenThresholdReached)" -sev Info
87+
} catch {
88+
$ErrorMessage = Get-CippException -Exception $_
89+
Write-LogMessage -API 'Standards' -tenant $Tenant -message "Could not set outbound spam limits. $($ErrorMessage.NormalizedError)" -sev Error -LogData $ErrorMessage
90+
}
91+
} else {
92+
Write-LogMessage -API 'Standards' -tenant $Tenant -message 'Outbound spam limits are already set correctly' -sev Info
93+
}
94+
}
95+
96+
# Alert
97+
if ($Settings.alert -eq $true) {
98+
if ($StateIsCorrect -eq $true) {
99+
Write-LogMessage -API 'Standards' -tenant $Tenant -message "Outbound spam limits are correctly configured: External=$($Settings.RecipientLimitExternalPerHour), Internal=$($Settings.RecipientLimitInternalPerHour), Daily=$($Settings.RecipientLimitPerDay), Action=$($ActionWhenThresholdReached)" -sev Info
100+
} else {
101+
Write-StandardsAlert -message 'Outbound spam limits are not configured correctly' -object $CurrentInfo -tenant $Tenant -standardName 'EXOOutboundSpamLimits' -standardId $Settings.standardId
102+
Write-LogMessage -API 'Standards' -tenant $Tenant -message 'Outbound spam limits are not configured correctly' -sev Info
103+
}
104+
}
105+
106+
# Report
107+
if ($Settings.report -eq $true) {
108+
$State = $StateIsCorrect ? $true : $CurrentInfo
109+
Set-CIPPStandardsCompareField -FieldName 'standards.EXOOutboundSpamLimits' -FieldValue $State -TenantFilter $Tenant
110+
Add-CIPPBPAField -FieldName 'OutboundSpamLimitsConfigured' -FieldValue $StateIsCorrect -StoreAs bool -Tenant $Tenant
111+
}
112+
}

0 commit comments

Comments
 (0)