Skip to content

Commit 20facb3

Browse files
authored
Merge pull request #330 from KelvinTegelaar/dev
[pull] dev from KelvinTegelaar:dev
2 parents 346cd84 + be5620f commit 20facb3

File tree

13 files changed

+128
-95
lines changed

13 files changed

+128
-95
lines changed

Modules/CIPPCore/Public/AuditLogs/New-CippAuditLogSearch.ps1

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -147,7 +147,7 @@ function New-CippAuditLogSearch {
147147
if ($IPAddressFilters) {
148148
$SearchParams.ipAddressFilters = @($IPAddressFilters)
149149
}
150-
if ($ObjectIdFilterss) {
150+
if ($ObjectIdFilters) {
151151
$SearchParams.objectIdFilters = @($ObjectIdFilters)
152152
}
153153
if ($AdministrativeUnitFilters) {

Modules/CIPPCore/Public/Entrypoints/Activity Triggers/Domain Analyser/Push-DomainAnalyserDomain.ps1

Lines changed: 25 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -83,7 +83,7 @@ function Push-DomainAnalyserDomain {
8383
# Setup Score Explanation
8484
$ScoreExplanation = [System.Collections.Generic.List[string]]::new()
8585

86-
# Check MX Record
86+
#Region MX Check
8787
$MXRecord = Read-MXRecord -Domain $Domain -ErrorAction Stop
8888

8989
$Result.ExpectedSPFRecord = $MXRecord.ExpectedInclude
@@ -106,8 +106,9 @@ function Push-DomainAnalyserDomain {
106106
} else {
107107
$Result.MailProvider = $MXRecord.MailProvider.Name
108108
}
109+
#EndRegion MX Check
109110

110-
# Get SPF Record
111+
#Region SPF Check
111112
try {
112113
$SPFRecord = Read-SpfRecord -Domain $Domain -ErrorAction Stop
113114
if ($SPFRecord.RecordCount -gt 0) {
@@ -126,21 +127,21 @@ function Push-DomainAnalyserDomain {
126127
Write-LogMessage -API 'DomainAnalyser' -tenant $DomainObject.TenantId -message $Message -LogData (Get-CippException -Exception $_) -sev Error
127128
}
128129

129-
# Check SPF Record
130-
$Result.SPFPassAll = $false
131130

132131
# Check warning + fail counts to ensure all tests pass
133132
#$SPFWarnCount = $SPFRecord.ValidationWarns | Measure-Object | Select-Object -ExpandProperty Count
134133
$SPFFailCount = $SPFRecord.ValidationFails | Measure-Object | Select-Object -ExpandProperty Count
134+
$Result.SPFPassAll = $false
135135

136136
if ($SPFFailCount -eq 0) {
137137
$ScoreDomain += $Scores.SPFCorrectAll
138138
$Result.SPFPassAll = $true
139139
} else {
140140
$ScoreExplanation.Add('SPF record did not pass validation') | Out-Null
141141
}
142+
#EndRegion SPF Check
142143

143-
# Get DMARC Record
144+
#Region DMARC Check
144145
try {
145146
$DMARCPolicy = Read-DmarcPolicy -Domain $Domain -ErrorAction Stop
146147

@@ -188,8 +189,9 @@ function Push-DomainAnalyserDomain {
188189
Write-LogMessage -API 'DomainAnalyser' -tenant $DomainObject.TenantId -message $Message -LogData (Get-CippException -Exception $_) -sev Error
189190
#return $Message
190191
}
192+
#EndRegion DMARC Check
191193

192-
# DNS Sec Check
194+
#Region DNS Sec Check
193195
try {
194196
$DNSSECResult = Test-DNSSEC -Domain $Domain -ErrorAction Stop
195197
$DNSSECFailCount = $DNSSECResult.ValidationFails | Measure-Object | Select-Object -ExpandProperty Count
@@ -206,8 +208,9 @@ function Push-DomainAnalyserDomain {
206208
Write-LogMessage -API 'DomainAnalyser' -tenant $DomainObject.TenantId -message $Message -LogData (Get-CippException -Exception $_) -sev Error
207209
#return $Message
208210
}
211+
#EndRegion DNS Sec Check
209212

210-
# DKIM Check
213+
#Region DKIM Check
211214
try {
212215
$DkimParams = @{
213216
Domain = $Domain
@@ -241,7 +244,9 @@ function Push-DomainAnalyserDomain {
241244
Write-LogMessage -API 'DomainAnalyser' -tenant $DomainObject.TenantId -message $Message -LogData (Get-CippException -Exception $_) -sev Error
242245
#return $Message
243246
}
247+
#EndRegion DKIM Check
244248

249+
#Region MSCNAME DKIM Records
245250
# Get Microsoft DKIM CNAME selector Records
246251
# Ugly, but i needed to create a scope/loop i could break out of without breaking the rest of the function
247252
foreach ($d in $Domain) {
@@ -250,7 +255,7 @@ function Push-DomainAnalyserDomain {
250255
if ($Result.DKIMEnabled -eq $true) {
251256
continue
252257
}
253-
# Test if its a onmicrosft.com domain, skip domain if it is
258+
# Test if its a onmicrosoft.com domain, skip domain if it is
254259
if ($Domain -match 'onmicrosoft.com') {
255260
continue
256261
}
@@ -264,28 +269,21 @@ function Push-DomainAnalyserDomain {
264269
}
265270
}
266271

272+
# Get the DKIM record from EXO. This is the only way to get the correct values for the MSCNAME records since the new format was introduced in May 2025.
273+
$DKIM = (New-ExoRequest -tenantid $Tenant.Tenant -cmdlet 'Get-DkimSigningConfig' -Select 'Domain,Selector1CNAME,Selector2CNAME') | Where-Object { $_.Domain -eq $Domain }
267274

268-
# Compute the DKIM CNAME records from $Tenant.InitialDomainName according to this logic: https://learn.microsoft.com/en-us/defender-office-365/email-authentication-dkim-configure#syntax-for-dkim-cname-records
269-
# Test if it has a - in the domain name
270-
if ($Domain -like '*-*') {
271-
Write-Information 'Domain has a - in it. Got to query EXO for the right values'
272-
$DKIM = (New-ExoRequest -tenantid $Tenant.Tenant -cmdlet 'Get-DkimSigningConfig') | Where-Object { $_.Domain -eq $Domain } | Select-Object Domain, Selector1CNAME, Selector2CNAME
273-
274-
# If no DKIM signing record is found, create a new disabled one
275-
if ($null -eq $DKIM) {
276-
Write-Information 'No DKIM record found in EXO - Creating new signing'
277-
$NewDKIMSigningRequest = New-ExoRequest -tenantid $Tenant.Tenant -cmdlet 'New-DkimSigningConfig' -cmdParams @{ KeySize = 2048; DomainName = $Domain; Enabled = $false }
278-
$Selector1Value = $NewDKIMSigningRequest.Selector1CNAME
279-
$Selector2Value = $NewDKIMSigningRequest.Selector2CNAME
280-
} else {
281-
$Selector1Value = $DKIM.Selector1CNAME
282-
$Selector2Value = $DKIM.Selector2CNAME
283-
}
275+
# If no DKIM signing record is found, create a new disabled one
276+
if ($null -eq $DKIM) {
277+
Write-Information 'No DKIM record found in EXO - Creating new signing'
278+
$NewDKIMSigningRequest = New-ExoRequest -tenantid $Tenant.Tenant -cmdlet 'New-DkimSigningConfig' -cmdParams @{ KeySize = 2048; DomainName = $Domain; Enabled = $false }
279+
$Selector1Value = $NewDKIMSigningRequest.Selector1CNAME
280+
$Selector2Value = $NewDKIMSigningRequest.Selector2CNAME
284281
} else {
285-
$Selector1Value = "selector1-$($Domain -replace '\.', '-' )._domainkey.$($Tenant.InitialDomainName)"
286-
$Selector2Value = "selector2-$($Domain -replace '\.', '-' )._domainkey.$($Tenant.InitialDomainName)"
282+
$Selector1Value = $DKIM.Selector1CNAME
283+
$Selector2Value = $DKIM.Selector2CNAME
287284
}
288285

286+
289287
# Create the MSCNAME object
290288
$MSCNAMERecords = [PSCustomObject]@{
291289
Domain = $Domain
@@ -304,7 +302,7 @@ function Push-DomainAnalyserDomain {
304302
Write-LogMessage -API 'DomainAnalyser' -tenant $DomainObject.TenantId -message "MS CNAME DKIM error: $($ErrorMessage.NormalizedError)" -LogData $ErrorMessage -sev Error
305303
}
306304
}
307-
305+
#EndRegion MSCNAME DKIM Records
308306
# Final Score
309307
$Result.Score = $ScoreDomain
310308
$Result.ScorePercentage = [int](($Result.Score / $Result.MaximumScore) * 100)

Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Email-Exchange/Administration/Invoke-AddSharedMailbox.ps1

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@ Function Invoke-AddSharedMailbox {
2929
Shared = $true
3030
}
3131
$AddSharedRequest = New-ExoRequest -tenantid $Tenant -cmdlet 'New-Mailbox' -cmdParams $BodyToShip
32-
$Body = $Results.Add("Successfully created shared mailbox: $Email.")
32+
$Body = $Results.Add("Successfully created shared mailbox: $Email")
3333
Write-LogMessage -Headers $Headers -API $APIName -tenant $Tenant -message "Created shared mailbox $($MailboxObject.displayName) with email $Email" -Sev 'Info'
3434

3535
# Block sign-in for the mailbox
@@ -38,7 +38,7 @@ Function Invoke-AddSharedMailbox {
3838
$Body = $Results.Add("Blocked sign-in for shared mailbox $Email")
3939
} catch {
4040
$ErrorMessage = Get-CippException -Exception $_
41-
$Message = "Failed to block sign-in for shared mailbox $Email. Error: $($ErrorMessage.NormalizedError)"
41+
$Message = "Failed to block sign-in for shared mailbox $Email Error: $($ErrorMessage.NormalizedError)"
4242
Write-LogMessage -Headers $Headers -API $APIName -tenant $Tenant -message $Message -Sev 'Error' -LogData $ErrorMessage
4343
$Body = $Results.Add($Message)
4444
}

Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Email-Exchange/Administration/Invoke-ExecSetOoO.ps1

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -30,8 +30,8 @@ Function Invoke-ExecSetOoO {
3030
# User action uses input, edit exchange uses InternalMessage and ExternalMessage
3131
# User action disable OoO doesn't send any input
3232
if ($Request.Body.input) {
33-
$InternalMessage = $Request.Body.input
34-
$ExternalMessage = $Request.Body.input
33+
$SplatParams.InternalMessage = $Request.Body.input
34+
$SplatParams.ExternalMessage = $Request.Body.input
3535
} else {
3636
$InternalMessage = $Request.Body.InternalMessage
3737
$ExternalMessage = $Request.Body.ExternalMessage

Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Identity/Administration/Groups/Invoke-EditGroup.ps1

Lines changed: 54 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -55,7 +55,7 @@ function Invoke-EditGroup {
5555
Write-Host "body: $($PatchObj | ConvertTo-Json -Depth 10 -Compress)" -ForegroundColor Yellow
5656
if ($UserObj.membershipRules) { $PatchObj | Add-Member -MemberType NoteProperty -Name 'membershipRule' -Value $UserObj.membershipRules -Force }
5757
try {
58-
$patch = New-GraphPOSTRequest -type PATCH -uri "https://graph.microsoft.com/beta/groups/$($GroupId)" -tenantid $UserObj.tenantFilter -body ($PatchObj | ConvertTo-Json -Depth 10 -Compress)
58+
$null = New-GraphPOSTRequest -type PATCH -uri "https://graph.microsoft.com/beta/groups/$($GroupId)" -tenantid $UserObj.tenantFilter -body ($PatchObj | ConvertTo-Json -Depth 10 -Compress)
5959
$Results.Add("Success - Edited group properties for $($GroupName) group. It might take some time to reflect the changes.")
6060
Write-LogMessage -headers $Headers -API $APIName -tenant $UserObj.tenantFilter -message "Edited group properties for $($GroupName) group" -Sev 'Info'
6161
} catch {
@@ -134,7 +134,7 @@ function Invoke-EditGroup {
134134
})
135135
} else {
136136
Write-LogMessage -API $APIName -tenant $TenantId -headers $Headers -message 'You cannot add a Contact to a Security Group or a M365 Group' -Sev 'Error'
137-
$null = $Results.Add('Error - You cannot add a contact to a Security Group or a M365 Group')
137+
$Results.Add('Error - You cannot add a contact to a Security Group or a M365 Group')
138138
}
139139
} catch {
140140
Write-Warning "Error in AddContacts: $($_.Exception.Message)"
@@ -162,7 +162,7 @@ function Invoke-EditGroup {
162162
})
163163
} else {
164164
Write-LogMessage -API $APIName-tenant $TenantId -headers $Headers -message 'You cannot remove a contact from a Security Group' -Sev 'Error'
165-
$null = $Results.Add('You cannot remove a contact from a Security Group')
165+
$Results.Add('You cannot remove a contact from a Security Group')
166166
}
167167
}
168168
}
@@ -260,7 +260,7 @@ function Invoke-EditGroup {
260260
if ($GroupType -in @( 'Distribution List', 'Mail-Enabled Security') -and ($AddOwners -or $RemoveOwners)) {
261261
$CurrentOwners = New-ExoRequest -tenantid $TenantId -cmdlet 'Get-DistributionGroup' -cmdParams @{ Identity = $GroupId } -UseSystemMailbox $true | Select-Object -ExpandProperty ManagedBy
262262

263-
$NewManagedBy = [system.collections.generic.list[string]]::new()
263+
$NewManagedBy = [System.Collections.Generic.List[string]]::new()
264264
foreach ($CurrentOwner in $CurrentOwners) {
265265
if ($RemoveOwners -and $RemoveOwners.addedFields.id -contains $CurrentOwner) {
266266
$OwnerToRemove = $RemoveOwners | Where-Object { $_.addedFields.id -eq $CurrentOwner }
@@ -330,7 +330,7 @@ function Invoke-EditGroup {
330330
foreach ($ExoError in $LastError.error) {
331331
$Sev = 'Error'
332332
$Results.Add("Error - $ExoError")
333-
Write-LogMessage -headers $Headers -API $APIName -tenant $TenantId -message $Message -Sev $Sev
333+
Write-LogMessage -headers $Headers -API $APIName -tenant $TenantId -message $ExoError -Sev $Sev
334334
}
335335

336336
foreach ($ExoLog in $ExoLogs) {
@@ -344,39 +344,65 @@ function Invoke-EditGroup {
344344
}
345345
}
346346

347-
if ($UserObj.allowExternal -eq $true -and $GroupType -ne 'Security') {
347+
# Only process allowExternal if it was explicitly sent
348+
if ($null -ne $UserObj.allowExternal -and $GroupType -ne 'Security') {
348349
try {
349-
Set-CIPPGroupAuthentication -ID $UserObj.mail -OnlyAllowInternal (!$UserObj.allowExternal) -GroupType $GroupType -tenantFilter $TenantId -APIName $APIName -Headers $Headers
350-
$body = $Results.Add("Allowed external senders to send to $($UserObj.mail).")
350+
$OnlyAllowInternal = $UserObj.allowExternal -eq $true ? $false : $true
351+
Set-CIPPGroupAuthentication -ID $UserObj.mail -OnlyAllowInternal $OnlyAllowInternal -GroupType $GroupType -tenantFilter $TenantId -APIName $APIName -Headers $Headers
352+
if ($UserObj.allowExternal -eq $true) {
353+
$Results.Add("Allowed external senders to send to $($UserObj.mail).")
354+
} else {
355+
$Results.Add("Blocked external senders from sending to $($UserObj.mail).")
356+
}
351357
} catch {
352-
$body = $Results.Add("Failed to allow external senders to send to $($UserObj.mail).")
353-
Write-LogMessage -headers $Headers -API $APIName -tenant $TenantId -message "Failed to allow external senders for $($UserObj.mail). Error:$($_.Exception.Message)" -Sev 'Error'
358+
$action = if ($UserObj.allowExternal -eq $true) { 'allow' } else { 'block' }
359+
$Results.Add("Failed to $action external senders for $($UserObj.mail).")
354360
}
355-
356361
}
357362

358-
if ($UserObj.sendCopies -eq $true) {
363+
# Only process sendCopies if it was explicitly sent
364+
if ($null -ne $UserObj.sendCopies) {
359365
try {
360-
$Params = @{ Identity = $GroupId; subscriptionEnabled = $true; AutoSubscribeNewMembers = $true }
361-
New-ExoRequest -tenantid $TenantId -cmdlet 'Set-UnifiedGroup' -cmdParams $Params -useSystemMailbox $true
362-
363-
$MemberParams = @{ Identity = $GroupId; LinkType = 'members' }
364-
$Members = New-ExoRequest -tenantid $TenantId -cmdlet 'Get-UnifiedGroupLinks' -cmdParams $MemberParams
366+
if ($UserObj.sendCopies -eq $true) {
367+
$Params = @{ Identity = $GroupId; subscriptionEnabled = $true; AutoSubscribeNewMembers = $true }
368+
New-ExoRequest -tenantid $TenantId -cmdlet 'Set-UnifiedGroup' -cmdParams $Params -useSystemMailbox $true
369+
370+
$MemberParams = @{ Identity = $GroupId; LinkType = 'members' }
371+
$Members = New-ExoRequest -tenantid $TenantId -cmdlet 'Get-UnifiedGroupLinks' -cmdParams $MemberParams
372+
373+
$MembershipIds = $Members | ForEach-Object { $_.ExternalDirectoryObjectId }
374+
if ($MembershipIds) {
375+
$subscriberParams = @{ Identity = $GroupId; LinkType = 'subscribers'; Links = @($MembershipIds | Where-Object { $_ }) }
376+
377+
try {
378+
New-ExoRequest -tenantid $TenantId -cmdlet 'Add-UnifiedGroupLinks' -cmdParams $subscriberParams -Anchor $UserObj.mail
379+
} catch {
380+
$ErrorMessage = Get-CippException -Exception $_
381+
Write-Warning "Error in SendCopies: Add-UnifiedGroupLinks $($ErrorMessage.NormalizedError) - $($_.InvocationInfo.ScriptLineNumber)"
382+
throw "Error in SendCopies: Add-UnifiedGroupLinks $($ErrorMessage.NormalizedError)"
383+
}
365384

366-
$MemberSmtpAddresses = $Members | ForEach-Object { $_.PrimarySmtpAddress }
385+
}
367386

368-
if ($MemberSmtpAddresses) {
369-
$subscriberParams = @{ Identity = $GroupId; LinkType = 'subscribers'; Links = @($MemberSmtpAddresses | Where-Object { $_ }) }
370-
New-ExoRequest -tenantid $TenantId -cmdlet 'Add-UnifiedGroupLinks' -cmdParams $subscriberParams -Anchor $UserObj.mail
387+
$Results.Add("Send Copies of team emails and events to team members inboxes for $($UserObj.mail) enabled.")
388+
Write-LogMessage -headers $Headers -API $APIName -tenant $TenantId -message "Send Copies of team emails and events to team members inboxes for $($UserObj.mail) enabled." -Sev 'Info'
389+
} else {
390+
# Disable send copies. Has to be done in 2 calls, otherwise it fails saying AutoSubscribeNewMembers cannot be true when subscriptionEnabled is false.
391+
# Why this happens and can't be done in one call, only Bill Gates and the mystical gods of Exchange knows.
392+
$Params = @{ Identity = $GroupId; AutoSubscribeNewMembers = $false }
393+
$null = New-ExoRequest -tenantid $TenantId -cmdlet 'Set-UnifiedGroup' -cmdParams $Params -useSystemMailbox $true
394+
$Params = @{ Identity = $GroupId; subscriptionEnabled = $false }
395+
$null = New-ExoRequest -tenantid $TenantId -cmdlet 'Set-UnifiedGroup' -cmdParams $Params -useSystemMailbox $true
396+
397+
$Results.Add("Send Copies of team emails and events to team members inboxes for $($UserObj.mail) disabled.")
398+
Write-LogMessage -headers $Headers -API $APIName -tenant $TenantId -message "Send Copies of team emails and events to team members inboxes for $($UserObj.mail) disabled." -Sev 'Info'
371399
}
372-
373-
$body = $Results.Add("Send Copies of team emails and events to team members inboxes for $($UserObj.mail) enabled.")
374-
Write-LogMessage -headers $Headers -API $APIName -tenant $TenantId -message "Send Copies of team emails and events to team members inboxes for $($UserObj.mail) enabled." -Sev 'Info'
375400
} catch {
376-
Write-Warning "Error in SendCopies: $($_.Exception.Message) - $($_.InvocationInfo.ScriptLineNumber)"
377-
Write-Warning ($_.InvocationInfo.PositionMessage)
378-
$body = $Results.Add("Failed to Send Copies of team emails and events to team members inboxes for $($UserObj.mail).")
379-
Write-LogMessage -headers $Headers -API $APIName -tenant $TenantId -message "Failed to Send Copies of team emails and events to team members inboxes for $($UserObj.mail). Error:$($_.Exception.Message)" -Sev 'Error'
401+
$ErrorMessage = Get-CippException -Exception $_
402+
Write-Warning "Error in SendCopies: $($ErrorMessage.NormalizedError) - $($_.InvocationInfo.ScriptLineNumber)"
403+
$action = if ($UserObj.sendCopies -eq $true) { 'enable' } else { 'disable' }
404+
$Results.Add("Failed to $action Send Copies of team emails and events to team members inboxes for $($UserObj.mail).")
405+
Write-LogMessage -headers $Headers -API $APIName -tenant $TenantId -message "Failed to $action Send Copies of team emails and events to team members inboxes for $($UserObj.mail). Error:$($ErrorMessage.NormalizedError)" -Sev 'Error' -LogData $ErrorMessage
380406
}
381407
}
382408

0 commit comments

Comments
 (0)