Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
45 commits
Select commit Hold shift + click to select a range
a1adc3b
Merge pull request #96 from KelvinTegelaar/dev
BNWEIN Nov 15, 2024
0771e53
Merge pull request #101 from KelvinTegelaar/dev
BNWEIN Dec 7, 2024
df2de73
Merge pull request #104 from KelvinTegelaar/dev
BNWEIN Jan 17, 2025
84177ba
Merge pull request #109 from KelvinTegelaar/dev
BNWEIN Jan 21, 2025
bb703d2
Merge pull request #111 from KelvinTegelaar/dev
BNWEIN Feb 3, 2025
5a8a239
Merge pull request #116 from KelvinTegelaar/dev
BNWEIN Feb 4, 2025
c72aef9
Update CIPP-Permissions.json
JohnDuprey Jun 20, 2025
8e4a8a3
Create SP if missing to remediate correctly
ngms-psh Jun 21, 2025
cddca7d
Fix this dammed alert
Zacgoose Jun 23, 2025
daf1a22
add accept header
JohnDuprey Jun 23, 2025
ab5bca9
Merge pull request #1526 from Zacgoose/alert-fix
JohnDuprey Jun 23, 2025
c3a386c
Merge pull request #118 from KelvinTegelaar/dev
BNWEIN Jun 24, 2025
58ee300
Update Invoke-ListGroups.ps1 to include 'onPremisesSyncEnabled' in th…
BNWEIN Jun 24, 2025
0d111e8
throw it
kris6673 Jun 24, 2025
19a7060
only set the sendCopies and allowExternal when explicitly sent from t…
kris6673 Jun 24, 2025
05fb792
Apparently PrimarySmtpAddress can be null?
kris6673 Jun 24, 2025
bff6b98
Fix allowExternal and sendCopies and add select for more SPEEEEEEEED
kris6673 Jun 24, 2025
a15c829
Update Invoke-CIPPStandardSendReceiveLimitTenant.ps1
StoricU Jun 25, 2025
c3d65eb
Add 'Prefer' header to make request upsert method
ngms-psh Jun 25, 2025
14b60a5
skip top level null in locationinfo
JohnDuprey Jun 25, 2025
3968a30
Update New-CippAuditLogSearch.ps1
OwenIbarra Jun 25, 2025
ebfdec5
Create test
OwenIbarra Jun 25, 2025
04d7339
fix casing issue
kris6673 Jun 25, 2025
c16993d
Remove extra periods...
Zacgoose Jun 26, 2025
d0be894
award for dumbest bug goes to
kris6673 Jun 26, 2025
72fe319
Enhance domain analysis script with structured region comments.
kris6673 Jun 26, 2025
aa681fd
casing
JohnDuprey Jun 26, 2025
a997fe9
Merge pull request #1534 from kris6673/dumb-fix-from-a-dumb-man
JohnDuprey Jun 26, 2025
443adc7
Merge pull request #1535 from Zacgoose/period
JohnDuprey Jun 26, 2025
198ba8a
Merge pull request #1536 from kris6673/fix-set-ooo
JohnDuprey Jun 26, 2025
2e740ac
Merge pull request #1529 from kris6673/edit-group
JohnDuprey Jun 26, 2025
8557480
Merge branch 'dev' into dev
JohnDuprey Jun 26, 2025
e2983e5
Merge pull request #1528 from BNWEIN/dev
JohnDuprey Jun 26, 2025
e61c57d
Merge pull request #1537 from kris6673/fix-MsCnameDkim
JohnDuprey Jun 26, 2025
84d023a
Merge pull request #1533 from OwenIbarra/dev
JohnDuprey Jun 26, 2025
e5770af
Delete .github/workflows/test
JohnDuprey Jun 26, 2025
4f88eda
Merge pull request #1531 from StoricU/dev
JohnDuprey Jun 26, 2025
be5620f
Merge pull request #1524 from ngms-psh/createmissing-sp-tpss
JohnDuprey Jun 26, 2025
ce2a784
remove where object
JohnDuprey Jun 27, 2025
90f00c7
remove extra slash
JohnDuprey Jun 27, 2025
3eddb4c
fix phishing protection url
JohnDuprey Jun 27, 2025
aee9e99
Cleanup broken CSS
Jun 27, 2025
702c74d
fix casing for set-cippuserlicense
JohnDuprey Jun 27, 2025
17c489e
up version
JohnDuprey Jun 27, 2025
7e0cf43
Merge pull request #1540 from KelvinTegelaar/dev
JohnDuprey Jun 27, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
15 changes: 15 additions & 0 deletions CIPP-Permissions.json
Original file line number Diff line number Diff line change
Expand Up @@ -225,6 +225,11 @@
"Name": "Organization.ReadWrite.All",
"Description": "Allows the app to read and write the organization and related resources, on your behalf. Related resources include things like subscribed skus and tenant branding information."
},
{
"Id": "346c19ff-3fb2-4e81-87a0-bac9e33990c1",
"Name": "OrgSettings-Forms.ReadWrite.All",
"Description": "Allows the app to read and write organization-wide Microsoft Forms settings on your behalf."
},
{
"Id": "e67e6727-c080-415e-b521-e3f35d5248e9",
"Name": "PeopleSettings.ReadWrite.All",
Expand Down Expand Up @@ -577,6 +582,11 @@
"Name": "Organization.ReadWrite.All",
"Description": "Allows the app to read and write the organization and related resources, without a signed-in user. Related resources include things like subscribed skus and tenant branding information."
},
{
"Id": "2cb92fee-97a3-4034-8702-24a6f5d0d1e9",
"Name": "OrgSettings-Forms.ReadWrite.All",
"Description": "Allows the app to read and write organization-wide Microsoft Forms settings, without a signed-in user."
},
{
"Id": "b6890674-9dd5-4e42-bb15-5af07f541ae1",
"Name": "PeopleSettings.ReadWrite.All",
Expand Down Expand Up @@ -637,6 +647,11 @@
"Name": "ReportSettings.ReadWrite.All",
"Description": "Allows the app to read and update all admin report settings, such as whether to display concealed information in reports, without a signed-in user."
},
{
"Id": "025d3225-3f02-4882-b4c0-cd5b541a4e80",
"Name": "RoleManagement.ReadWrite.Exchange",
"Description": "Allows the app to read and manage the role-based access control (RBAC) settings for your organization's Exchange Online service, without a signed-in user. This includes reading, creating, updating, and deleting Exchange management role definitions, role groups, role group membership, role assignments, management scopes, and role assignment policies."
},
{
"Id": "04c55753-2244-4c25-87fc-704ab82a4f69",
"Name": "SecurityAnalyzedMessage.ReadWrite.All",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ function Get-CIPPAlertHuntressRogueApps {
Param (
[Parameter(Mandatory = $false)]
[Alias('input')]
[bool]$InputValue = $false,
$InputValue,
$TenantFilter
)

Expand All @@ -22,7 +22,7 @@ function Get-CIPPAlertHuntressRogueApps {
$RogueAppFilter = $RogueApps.appId -join "','"
$ServicePrincipals = New-GraphGetRequest -uri "https://graph.microsoft.com/beta/servicePrincipals?`$filter=appId in ('$RogueAppFilter')" -tenantid $TenantFilter
# If IgnoreDisabledApps is true, filter out disabled service principals
if ($InputValue) {
if ($InputValue -eq $true) {
$ServicePrincipals = $ServicePrincipals | Where-Object { $_.accountEnabled -eq $true }
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -147,7 +147,7 @@ function New-CippAuditLogSearch {
if ($IPAddressFilters) {
$SearchParams.ipAddressFilters = @($IPAddressFilters)
}
if ($ObjectIdFilterss) {
if ($ObjectIdFilters) {
$SearchParams.objectIdFilters = @($ObjectIdFilters)
}
if ($AdministrativeUnitFilters) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -83,7 +83,7 @@ function Push-DomainAnalyserDomain {
# Setup Score Explanation
$ScoreExplanation = [System.Collections.Generic.List[string]]::new()

# Check MX Record
#Region MX Check
$MXRecord = Read-MXRecord -Domain $Domain -ErrorAction Stop

$Result.ExpectedSPFRecord = $MXRecord.ExpectedInclude
Expand All @@ -106,8 +106,9 @@ function Push-DomainAnalyserDomain {
} else {
$Result.MailProvider = $MXRecord.MailProvider.Name
}
#EndRegion MX Check

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

# Check SPF Record
$Result.SPFPassAll = $false

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

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

# Get DMARC Record
#Region DMARC Check
try {
$DMARCPolicy = Read-DmarcPolicy -Domain $Domain -ErrorAction Stop

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

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

# DKIM Check
#Region DKIM Check
try {
$DkimParams = @{
Domain = $Domain
Expand Down Expand Up @@ -241,7 +244,9 @@ function Push-DomainAnalyserDomain {
Write-LogMessage -API 'DomainAnalyser' -tenant $DomainObject.TenantId -message $Message -LogData (Get-CippException -Exception $_) -sev Error
#return $Message
}
#EndRegion DKIM Check

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

# 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.
$DKIM = (New-ExoRequest -tenantid $Tenant.Tenant -cmdlet 'Get-DkimSigningConfig' -Select 'Domain,Selector1CNAME,Selector2CNAME') | Where-Object { $_.Domain -eq $Domain }

# 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
# Test if it has a - in the domain name
if ($Domain -like '*-*') {
Write-Information 'Domain has a - in it. Got to query EXO for the right values'
$DKIM = (New-ExoRequest -tenantid $Tenant.Tenant -cmdlet 'Get-DkimSigningConfig') | Where-Object { $_.Domain -eq $Domain } | Select-Object Domain, Selector1CNAME, Selector2CNAME

# If no DKIM signing record is found, create a new disabled one
if ($null -eq $DKIM) {
Write-Information 'No DKIM record found in EXO - Creating new signing'
$NewDKIMSigningRequest = New-ExoRequest -tenantid $Tenant.Tenant -cmdlet 'New-DkimSigningConfig' -cmdParams @{ KeySize = 2048; DomainName = $Domain; Enabled = $false }
$Selector1Value = $NewDKIMSigningRequest.Selector1CNAME
$Selector2Value = $NewDKIMSigningRequest.Selector2CNAME
} else {
$Selector1Value = $DKIM.Selector1CNAME
$Selector2Value = $DKIM.Selector2CNAME
}
# If no DKIM signing record is found, create a new disabled one
if ($null -eq $DKIM) {
Write-Information 'No DKIM record found in EXO - Creating new signing'
$NewDKIMSigningRequest = New-ExoRequest -tenantid $Tenant.Tenant -cmdlet 'New-DkimSigningConfig' -cmdParams @{ KeySize = 2048; DomainName = $Domain; Enabled = $false }
$Selector1Value = $NewDKIMSigningRequest.Selector1CNAME
$Selector2Value = $NewDKIMSigningRequest.Selector2CNAME
} else {
$Selector1Value = "selector1-$($Domain -replace '\.', '-' )._domainkey.$($Tenant.InitialDomainName)"
$Selector2Value = "selector2-$($Domain -replace '\.', '-' )._domainkey.$($Tenant.InitialDomainName)"
$Selector1Value = $DKIM.Selector1CNAME
$Selector2Value = $DKIM.Selector2CNAME
}


# Create the MSCNAME object
$MSCNAMERecords = [PSCustomObject]@{
Domain = $Domain
Expand All @@ -304,7 +302,7 @@ function Push-DomainAnalyserDomain {
Write-LogMessage -API 'DomainAnalyser' -tenant $DomainObject.TenantId -message "MS CNAME DKIM error: $($ErrorMessage.NormalizedError)" -LogData $ErrorMessage -sev Error
}
}

#EndRegion MSCNAME DKIM Records
# Final Score
$Result.Score = $ScoreDomain
$Result.ScorePercentage = [int](($Result.Score / $Result.MaximumScore) * 100)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,23 +14,29 @@ function Invoke-ListScheduledItems {
$Headers = $Request.Headers
Write-LogMessage -headers $Headers -API $APIName -message 'Accessed this API' -Sev 'Debug'


# Interact with query parameters or the body of the request.
$ShowHidden = $Request.Query.ShowHidden ?? $Request.Body.ShowHidden
$Name = $Request.Query.Name ?? $Request.Body.Name
$Type = $Request.Query.Type ?? $Request.Body.Type

$ScheduledItemFilter = [System.Collections.Generic.List[string]]::new()
$ScheduledItemFilter.Add("PartitionKey eq 'ScheduledTask'")

if ($ShowHidden -eq $true) {
$ScheduledItemFilter.Add('Hidden eq true')
$Id = $Request.Query.Id ?? $Request.Body.Id
if ($Id) {
# Interact with query parameters.
$ScheduledItemFilter.Add("RowKey eq '$($Id)'")
} else {
$ScheduledItemFilter.Add('Hidden eq false')
}
# Interact with query parameters or the body of the request.
$ShowHidden = $Request.Query.ShowHidden ?? $Request.Body.ShowHidden
$Name = $Request.Query.Name ?? $Request.Body.Name
$Type = $Request.Query.Type ?? $Request.Body.Type

if ($ShowHidden -eq $true) {
$ScheduledItemFilter.Add('Hidden eq true')
} else {
$ScheduledItemFilter.Add('Hidden eq false')
}

if ($Name) {
$ScheduledItemFilter.Add("Name eq '$($Name)'")
}

if ($Name) {
$ScheduledItemFilter.Add("Name eq '$($Name)'")
}

$Filter = $ScheduledItemFilter -join ' and '
Expand All @@ -42,7 +48,7 @@ function Invoke-ListScheduledItems {
} else {
$HiddenTasks = $true
}
$Tasks = Get-CIPPAzDataTableEntity @Table -Filter $Filter | Where-Object { $_.Hidden -ne $HiddenTasks }
$Tasks = Get-CIPPAzDataTableEntity @Table -Filter $Filter
if ($Type) {
$Tasks = $Tasks | Where-Object { $_.command -eq $Type }
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ Function Invoke-AddSharedMailbox {
Shared = $true
}
$AddSharedRequest = New-ExoRequest -tenantid $Tenant -cmdlet 'New-Mailbox' -cmdParams $BodyToShip
$Body = $Results.Add("Successfully created shared mailbox: $Email.")
$Body = $Results.Add("Successfully created shared mailbox: $Email")
Write-LogMessage -Headers $Headers -API $APIName -tenant $Tenant -message "Created shared mailbox $($MailboxObject.displayName) with email $Email" -Sev 'Info'

# Block sign-in for the mailbox
Expand All @@ -38,7 +38,7 @@ Function Invoke-AddSharedMailbox {
$Body = $Results.Add("Blocked sign-in for shared mailbox $Email")
} catch {
$ErrorMessage = Get-CippException -Exception $_
$Message = "Failed to block sign-in for shared mailbox $Email. Error: $($ErrorMessage.NormalizedError)"
$Message = "Failed to block sign-in for shared mailbox $Email Error: $($ErrorMessage.NormalizedError)"
Write-LogMessage -Headers $Headers -API $APIName -tenant $Tenant -message $Message -Sev 'Error' -LogData $ErrorMessage
$Body = $Results.Add($Message)
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -30,8 +30,8 @@ Function Invoke-ExecSetOoO {
# User action uses input, edit exchange uses InternalMessage and ExternalMessage
# User action disable OoO doesn't send any input
if ($Request.Body.input) {
$InternalMessage = $Request.Body.input
$ExternalMessage = $Request.Body.input
$SplatParams.InternalMessage = $Request.Body.input
$SplatParams.ExternalMessage = $Request.Body.input
} else {
$InternalMessage = $Request.Body.InternalMessage
$ExternalMessage = $Request.Body.ExternalMessage
Expand Down
Loading