Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
83 commits
Select commit Hold shift + click to select a range
7b26b11
fix(compare): handle non-catalog null results
kris6673 Apr 30, 2026
ece775b
feat(intune): extend ListIntunePolicy for admin templates
kris6673 Apr 30, 2026
80f6df7
Redirect url helper scripts
Zacgoose May 2, 2026
50789ce
queue tweaks
Zacgoose May 2, 2026
8594b3d
Update Start-CIPPOrchestrator.ps1
Zacgoose May 2, 2026
7504083
rename
JohnDuprey May 2, 2026
4484ec2
Add queueing functions to blocked commands list
JohnDuprey May 3, 2026
bb3db33
Correct list alerts accounting for tenant allowed tenant groups
Zacgoose May 4, 2026
f9928ae
CIS Microsoft 365 Foundations Benchmark v6.0.1
KelvinTegelaar May 4, 2026
16c03a1
add to scheduler
KelvinTegelaar May 4, 2026
cb51886
fix: MOERA standard reporting
JohnDuprey May 4, 2026
f50d8a1
feat: add Get-CIPPGroupsReport function and integrate with Invoke-Lis…
JohnDuprey May 4, 2026
3702c85
feat: PR check on fork
JohnDuprey May 4, 2026
8856340
dead code
Zacgoose May 5, 2026
8e12d10
Correct CIPP SAM addition repeated alerts
Zacgoose May 5, 2026
b230c7f
Fix drift tag resolution using stale rawData instead of live lookup
Zacgoose May 5, 2026
7a7c70d
fix: remove +1hr buffer to end time
JohnDuprey May 5, 2026
61b891c
Fix image upload
Zacgoose May 5, 2026
364da37
Merge branch 'dev' of https://github.com/KelvinTegelaar/CIPP-API into…
Zacgoose May 5, 2026
7787f18
Improve drift alignment data
Zacgoose May 5, 2026
08d2bcb
Add self-service email stuff
KelvinTegelaar May 5, 2026
733da22
updated
KelvinTegelaar May 5, 2026
e2382b4
fix: exclude expired user consent requests
JohnDuprey May 5, 2026
5087f26
Merge branch 'dev' of https://github.com/KelvinTegelaar/CIPP-API into…
JohnDuprey May 5, 2026
45c8f59
Fix TeamsMeetingRecordingExpiration drift report showing Current=true
bmsimp May 3, 2026
512d87c
Fix SPFileRequests drift report showing pre-remediation values
bmsimp May 3, 2026
2be775b
Fix DisableSelfServiceLicenses autoclaim reading wrong property
bmsimp May 3, 2026
7aeeffc
Fix TeamsFederationConfiguration drift report ordering mismatch
bmsimp May 3, 2026
27c08ab
Fix SafeLinksPolicy and MalwareFilterPolicy drift report ordering
bmsimp May 3, 2026
212c6f1
improve drift page loading speed
Zacgoose May 6, 2026
0e537b1
fix: Guard against missing GeoIP.Data
JohnDuprey May 6, 2026
21528ea
parse timezone value for nice response message
Zacgoose May 6, 2026
23505c3
Correct backup object retuned
Zacgoose May 6, 2026
cc07ca5
public group standard
KelvinTegelaar May 6, 2026
9a84438
Empty AllowList Standard for CIS
KelvinTegelaar May 6, 2026
7962aab
add teasm ZAP standard
KelvinTegelaar May 6, 2026
94a291c
Ensure that collaboration invitations are sent to allowed domains only
KelvinTegelaar May 6, 2026
498d03f
fix: duplicate group ID retrieval in Invoke-ExecAddGDAPRole function
JohnDuprey May 6, 2026
9ae7562
Update Standard AutoAddProxy
Zacgoose May 7, 2026
adbbb53
Update CIPPTimers.json
Zacgoose May 7, 2026
3beb622
Better queue tracking
Zacgoose May 7, 2026
b9e193e
Add usageLocation support to JIT Admin creation and templates (#5910)
joaadvi May 7, 2026
b02970f
Fix drift report inaccuracies for TeamsMeeting, SPFileRequests, and p…
KelvinTegelaar May 7, 2026
0bc436b
Fix handling of non-catalog null results in comparison function (#2034)
KelvinTegelaar May 7, 2026
02fdcbe
Feat: Extend ListIntunePolicy for admin templates (#2035)
KelvinTegelaar May 7, 2026
8e7392d
fix: scripted alert optimization
JohnDuprey May 7, 2026
731a41e
fix: ensure unique and non-null email addresses in report generation
JohnDuprey May 7, 2026
bc4e643
add purview section
KelvinTegelaar May 7, 2026
c0098fd
remove old file
KelvinTegelaar May 7, 2026
26cb9ae
feat: Add AutoDiscover check to domain analysis
kris6673 May 7, 2026
94158f4
Add Investigate status to custom tests
Zacgoose May 8, 2026
f20c60a
Revert escaping
Zacgoose May 8, 2026
318d826
fix: correct assignment syntax for FieldValue in Add-CIPPBPAField fun…
JohnDuprey May 8, 2026
51b2281
fix: add SharingCapability to current state retrieval in Invoke-CIPPS…
JohnDuprey May 8, 2026
7804aaf
Try infer template type from content if missing, else fail early
Zacgoose May 8, 2026
1a304e1
feat: Add AutoDiscover check to domain analysis (#2042)
KelvinTegelaar May 8, 2026
3f44d22
Add usageLocation support to JIT Admin creation and templates (#5910)…
KelvinTegelaar May 8, 2026
8d454b9
fixed unmapped issue sherweb
KelvinTegelaar May 8, 2026
85d9a6c
concept
rvdwegen May 8, 2026
5644578
fixed #5930
KelvinTegelaar May 8, 2026
67ea958
fixes #5973
KelvinTegelaar May 8, 2026
b7773c6
pushing new compliance menus
KelvinTegelaar May 8, 2026
0475f95
Merge branch 'dev' of https://github.com/KelvinTegelaar/CIPP-API into…
KelvinTegelaar May 8, 2026
584a6fe
feat: support bulk manager and sponsor updates
kris6673 May 8, 2026
b872a8b
Merge branch 'dev' of https://github.com/KelvinTegelaar/CIPP-API into…
rvdwegen May 8, 2026
a8a0c9d
fixes #5967
KelvinTegelaar May 8, 2026
68a83d3
Merge branch 'dev' of https://github.com/KelvinTegelaar/CIPP-API into…
KelvinTegelaar May 8, 2026
6c440c0
Fix usageLocation autocomplete object in JIT Admin (#5910)
joaadvi May 8, 2026
3b60964
fix(jit-admin): honor TAP lifetime policy bounds
kris6673 May 8, 2026
2529b6a
fixes #5925
KelvinTegelaar May 8, 2026
0e00b46
Feat: Add configurable TAP lifetime for JIT Admin creation (#2045)
KelvinTegelaar May 8, 2026
d7bd907
Fix usageLocation value extraction in JIT Admin (#5910) (#2044)
KelvinTegelaar May 8, 2026
b9a8249
feat: Support bulk updates for managers and sponsors (#2043)
KelvinTegelaar May 8, 2026
74124f4
chore: update DNSHealth to 1.1.7
JohnDuprey May 8, 2026
176aa96
fix: sharing capability based on desired state for file requests
JohnDuprey May 8, 2026
f105398
chore: update dnshealth to 1.1.8
JohnDuprey May 8, 2026
d9c6203
fix: update expiration days logic for SharePoint and OneDrive file re…
JohnDuprey May 8, 2026
933a6dc
Fix for 5979
rvdwegen May 8, 2026
0bc4f50
Merge branch 'dev' of https://github.com/KelvinTegelaar/CIPP-API into…
rvdwegen May 8, 2026
4a466be
fix: prevent stale template list from skewing applied standards report
JohnDuprey May 8, 2026
bf8a33a
feat: add Invoke-ListResellerRelationshipLink function for retrieving…
JohnDuprey May 8, 2026
e99b4aa
chore: bump version to 10.4.4
JohnDuprey May 8, 2026
6871d26
Dev to hotfix (#2047)
JohnDuprey May 8, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
The table of contents is too big for display.
Diff view
Diff view
  •  
  •  
  •  
40 changes: 32 additions & 8 deletions .github/workflows/PR_Branch_Check.yml
Original file line number Diff line number Diff line change
Expand Up @@ -16,22 +16,46 @@ permissions:

jobs:
check-branch:
runs-on: ubuntu-latest
runs-on: ubuntu-slim
steps:
- name: Check and Comment on PR
# Only process fork PRs with specific branch conditions
# Must be a fork AND (source is main/master OR target is main/master)
if: |
github.event.pull_request.head.repo.fork == true &&
github.event.pull_request.head.repo.fork == true &&
((github.event.pull_request.head.ref == 'main' || github.event.pull_request.head.ref == 'master') ||
(github.event.pull_request.base.ref == 'main' || github.event.pull_request.base.ref == 'master'))
uses: actions/github-script@v7
uses: actions/github-script@v9
with:
github-token: ${{ secrets.GITHUB_TOKEN }}
script: |
let message = '';

message += '🔄 If you are attempting to update your CIPP repo please follow the instructions at: https://docs.cipp.app/setup/self-hosting-guide/updating ';
// Check if the fork has open PRs (indicates pull bot or similar is active)
const forkOwner = context.payload.pull_request.head.repo.owner.login;
const forkRepo = context.payload.pull_request.head.repo.name;
const forkPullsUrl = context.payload.pull_request.head.repo.html_url + '/pulls';

let openPRs = [];
try {
const { data: prs } = await github.rest.pulls.list({
owner: forkOwner,
repo: forkRepo,
state: 'open',
per_page: 5
});
openPRs = prs;
} catch (e) {
// Can't read fork PRs — skip
}

message += '🔄 If you are attempting to update your CIPP-API repo please follow the instructions at: https://docs.cipp.app/setup/self-hosting-guide/updating. Are you a sponsor? Contact the helpdesk for direct assistance with updating to the latest version.';

if (openPRs.length > 0) {
message += ` It looks like you may already have a pending update PR on your fork — check your [open pull requests](${forkPullsUrl}) to accept it.`;
} else {
message += ` You can enable [Pull Bot](https://github.com/apps/pull) or [Repo Sync](https://github.com/apps/repo-sync) to automatically keep your fork up to date.`;
}
message += '\n\n';

// Check if PR is targeting main/master
Expand All @@ -40,20 +64,20 @@ jobs:
}

// Check if PR is from a fork's main/master branch
if (context.payload.pull_request.head.repo.fork &&
if (context.payload.pull_request.head.repo.fork &&
(context.payload.pull_request.head.ref === 'main' || context.payload.pull_request.head.ref === 'master')) {
message += '⚠️ This PR cannot be merged because it originates from your fork\'s main/master branch. If you are attempting to contribute code please PR from your dev branch or another non-main/master branch.\n\n';
}

message += '🔒 This PR will now be automatically closed due to the above violation(s).';
message += '🔒 This PR will now be automatically closed due to the above rules.';

// Post the comment
await github.rest.issues.createComment({
...context.repo,
issue_number: context.issue.number,
body: message
});

// Close the PR
await github.rest.pulls.update({
...context.repo,
Expand Down
15 changes: 15 additions & 0 deletions Config/CIPPTimers.json
Original file line number Diff line number Diff line change
Expand Up @@ -78,6 +78,7 @@
"Cron": "0 0 */12 * * *",
"Priority": 4,
"RunOnProcessor": true,
"TZOffset": true,
"PreferredProcessor": "standards"
},
{
Expand All @@ -87,6 +88,7 @@
"Cron": "0 15 */12 * * *",
"Priority": 5,
"RunOnProcessor": true,
"TZOffset": true,
"PreferredProcessor": "standards"
},
{
Expand Down Expand Up @@ -120,6 +122,7 @@
"Cron": "0 0 0 * * 0",
"Priority": 7,
"RunOnProcessor": true,
"TZOffset": true,
"IsSystem": true
},
{
Expand All @@ -137,6 +140,7 @@
"Description": "Orchestrator to process domains",
"Cron": "0 30 5 * * *",
"Priority": 22,
"TZOffset": true,
"RunOnProcessor": true
},
{
Expand All @@ -149,6 +153,7 @@
"Cron": "0 0 23 * * *",
"Priority": 10,
"RunOnProcessor": true,
"TZOffset": true,
"IsSystem": true
},
{
Expand All @@ -158,6 +163,7 @@
"Cron": "0 0 0 * * *",
"Priority": 10,
"RunOnProcessor": true,
"TZOffset": true,
"IsSystem": true
},
{
Expand All @@ -166,6 +172,7 @@
"Description": "Timer to process billing",
"Cron": "0 0 0 * * *",
"Priority": 12,
"TZOffset": true,
"RunOnProcessor": true
},
{
Expand All @@ -174,6 +181,7 @@
"Description": "Orchestrator to process BPA reports",
"Cron": "0 0 3 * * *",
"Priority": 10,
"TZOffset": true,
"RunOnProcessor": true
},
{
Expand All @@ -191,6 +199,7 @@
"Cron": "0 0 0 * * *",
"Priority": 15,
"RunOnProcessor": true,
"TZOffset": true,
"IsSystem": true
},
{
Expand All @@ -200,6 +209,7 @@
"Cron": "0 0 23 * * *",
"Priority": 20,
"RunOnProcessor": true,
"TZOffset": true,
"IsSystem": true
},
{
Expand All @@ -212,6 +222,7 @@
"Cron": "0 0 0 * * *",
"Priority": 20,
"RunOnProcessor": true,
"TZOffset": true,
"IsSystem": true
},
{
Expand All @@ -221,6 +232,7 @@
"Cron": "0 0 2 * * *",
"Priority": 21,
"RunOnProcessor": true,
"TZOffset": true,
"IsSystem": true
},
{
Expand All @@ -230,6 +242,7 @@
"Cron": "0 30 2 * * *",
"Priority": 22,
"RunOnProcessor": true,
"TZOffset": true,
"IsSystem": true
},
{
Expand All @@ -239,6 +252,7 @@
"Cron": "0 0 3 * * *",
"Priority": 23,
"RunOnProcessor": true,
"TZOffset": true,
"IsSystem": true
},
{
Expand All @@ -248,6 +262,7 @@
"Cron": "0 0 4 * * *",
"Priority": 24,
"RunOnProcessor": true,
"TZOffset": true,
"IsSystem": true
}
]
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,7 @@ function Push-DomainAnalyserDomain {
MSCNAMEDKIMSelectors = ''
EnterpriseEnrollment = ''
EnterpriseRegistration = ''
AutoDiscover = ''
Score = ''
MaximumScore = 160
ScorePercentage = ''
Expand Down Expand Up @@ -293,6 +294,26 @@ function Push-DomainAnalyserDomain {
}
#EndRegion Intune Enrollment CNAME Check

#Region AutoDiscover Check
try {
$AutoDiscoverRecord = Read-AutoDiscoverRecord -Domain $Domain
$AutoDiscoverFailCount = $AutoDiscoverRecord.ValidationFails | Measure-Object | Select-Object -ExpandProperty Count
$AutoDiscoverWarnCount = $AutoDiscoverRecord.ValidationWarns | Measure-Object | Select-Object -ExpandProperty Count
if ($AutoDiscoverFailCount -eq 0 -and $AutoDiscoverWarnCount -eq 0) {
$Result.AutoDiscover = 'Correct'
} elseif ($AutoDiscoverFailCount -eq 0) {
$Result.AutoDiscover = "$($AutoDiscoverRecord.RecordType): $($AutoDiscoverRecord.Record)"
$ScoreExplanation.Add("AutoDiscover $($AutoDiscoverRecord.RecordType) record points to unexpected target") | Out-Null
} else {
$Result.AutoDiscover = 'No Record'
$ScoreExplanation.Add('No AutoDiscover DNS record found') | Out-Null
}
} catch {
$Result.AutoDiscover = 'Error'
Write-LogMessage -API 'DomainAnalyser' -tenant $DomainObject.TenantId -message "AutoDiscover check error for $Domain" -LogData (Get-CippException -Exception $_) -sev Error
}
#EndRegion AutoDiscover 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
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,15 @@ function Push-ListGraphRequestQueue {
Data = [string]$Json
}
Add-CIPPAzDataTableEntity @Table -Entity $GraphResults -Force | Out-Null

if ($env:CIPPNG -eq 'true') {
try {
[Craft.Services.CacheBridge]::InvalidateByScope('AllTenants')
} catch {
Write-Information "CacheBridge invalidation skipped: $($_.Exception.Message)"
}
}

return $true
} catch {
Write-Warning "Queue Error: $($_.Exception.Message)"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,23 @@ function Push-CIPPDBCacheData {
Write-LogMessage -API 'CIPPDBCache' -tenant $TenantFilter -message "Compliance license check failed: $($_.Exception.Message)" -sev Warning -LogData $ErrorMessage
}

Write-Information "License capabilities for $TenantFilter - Intune: $IntuneCapable, CA: $ConditionalAccessCapable, P2: $AzureADPremiumP2Capable, Exchange: $ExchangeCapable, Compliance: $ComplianceCapable"
$SharePointCapable = $false
try {
$SharePointCapable = Test-CIPPStandardLicense -StandardName 'SharePointLicenseCheck' -TenantFilter $TenantFilter -RequiredCapabilities @('SHAREPOINTWAC', 'SHAREPOINTSTANDARD', 'SHAREPOINTENTERPRISE', 'SHAREPOINTENTERPRISE_EDU', 'ONEDRIVE_BASIC', 'ONEDRIVE_ENTERPRISE') -SkipLog
} catch {
$ErrorMessage = Get-CippException -Exception $_
Write-LogMessage -API 'CIPPDBCache' -tenant $TenantFilter -message "SharePoint license check failed: $($_.Exception.Message)" -sev Warning -LogData $ErrorMessage
}

$TeamsCapable = $false
try {
$TeamsCapable = Test-CIPPStandardLicense -StandardName 'TeamsLicenseCheck' -TenantFilter $TenantFilter -RequiredCapabilities @('MCOSTANDARD', 'MCOEV', 'MCOIMP', 'TEAMS1', 'Teams_Room_Standard') -SkipLog
} catch {
$ErrorMessage = Get-CippException -Exception $_
Write-LogMessage -API 'CIPPDBCache' -tenant $TenantFilter -message "Teams license check failed: $($_.Exception.Message)" -sev Warning -LogData $ErrorMessage
}

Write-Information "License capabilities for $TenantFilter - Intune: $IntuneCapable, CA: $ConditionalAccessCapable, P2: $AzureADPremiumP2Capable, Exchange: $ExchangeCapable, Compliance: $ComplianceCapable, SharePoint: $SharePointCapable, Teams: $TeamsCapable"

# Build grouped collection tasks — one activity per license category instead of one per cache type
$Tasks = [System.Collections.Generic.List[object]]::new()
Expand Down Expand Up @@ -174,6 +190,30 @@ function Push-CIPPDBCacheData {
Write-Host "Skipping Compliance data collection for $TenantFilter - no required license"
}

if ($SharePointCapable) {
$Tasks.Add(@{
FunctionName = 'ExecCIPPDBCache'
CollectionType = 'SharePoint'
TenantFilter = $TenantFilter
QueueId = $QueueId
QueueName = "DB Cache SharePoint - $TenantFilter"
})
} else {
Write-Host "Skipping SharePoint data collection for $TenantFilter - no required license"
}

if ($TeamsCapable) {
$Tasks.Add(@{
FunctionName = 'ExecCIPPDBCache'
CollectionType = 'Teams'
TenantFilter = $TenantFilter
QueueId = $QueueId
QueueName = "DB Cache Teams - $TenantFilter"
})
} else {
Write-Host "Skipping Teams data collection for $TenantFilter - no required license"
}

Write-Information "Built $($Tasks.Count) grouped cache tasks for tenant $TenantFilter (down from individual per-type tasks)"

# Return the task list — the PostExecution function will aggregate and start a flat orchestrator
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,11 @@ function Push-UpdatePermissionsQueue {
#>
param($Item)

try {
$DomainRefreshRequired = $false
$Status = 'Failed'
$FailureMessage = $null
$DomainRefreshRequired = $false

try {
if (!$Item.defaultDomainName) {
$DomainRefreshRequired = $true
}
Expand Down Expand Up @@ -46,33 +48,55 @@ function Push-UpdatePermissionsQueue {

if ($Item.defaultDomainName -ne 'PartnerTenant') {
Write-Information 'Pushing CIPP-SAM admin roles'
Set-CIPPSAMAdminRoles -TenantFilter $Item.customerId
try {
Set-CIPPSAMAdminRoles -TenantFilter $Item.customerId
} catch {
$SamRoleError = Get-CippException -Exception $_
Write-Information "Failed to set CIPP-SAM admin roles for $($Item.displayName): $($_.Exception.Message)"
Write-LogMessage -tenant $Item.defaultDomainName -tenantId $Item.customerId -message "Failed to set CIPP-SAM admin roles for $($Item.displayName) - $($_.Exception.Message)" -Sev 'Warning' -API 'UpdatePermissionsQueue' -LogData $SamRoleError
if ($Status -eq 'Success') {
$Status = 'Failed'
$FailureMessage = "Set-CIPPSAMAdminRoles: $($_.Exception.Message)"
}
}
}

$Table = Get-CIPPTable -TableName cpvtenants
$unixtime = [int64](([datetime]::UtcNow) - (Get-Date '1/1/1970')).TotalSeconds
$GraphRequest = @{
LastApply = "$unixtime"
LastStatus = "$Status"
applicationId = "$($env:ApplicationID)"
Tenant = "$($Item.customerId)"
PartitionKey = 'Tenant'
RowKey = "$($Item.customerId)"
} catch {
Write-Information "Error updating permissions for $($Item.displayName): $($_.Exception.Message)"
Write-Information $_.InvocationInfo.PositionMessage
Write-LogMessage -tenant $Item.defaultDomainName -tenantId $Item.customerId -message "Error updating permissions for $($Item.displayName) - $($_.Exception.Message)" -Sev 'Error' -API 'UpdatePermissionsQueue' -LogData (Get-CippException -Exception $_)
$Status = 'Failed'
if (-not $FailureMessage) {
$FailureMessage = $_.Exception.Message
}
if ($PermissionFailures) {
$GraphRequest.LastError = $FailureMessage
} finally {
try {
$CpvTable = Get-CIPPTable -TableName cpvtenants
$unixtime = [int64](([datetime]::UtcNow) - (Get-Date '1/1/1970')).TotalSeconds
$GraphRequest = @{
LastApply = "$unixtime"
LastStatus = "$Status"
applicationId = "$($env:ApplicationID)"
Tenant = "$($Item.customerId)"
PartitionKey = 'Tenant'
RowKey = "$($Item.customerId)"
}
if ($FailureMessage) {
$GraphRequest.LastError = "$FailureMessage"
}
Add-CIPPAzDataTableEntity @CpvTable -Entity $GraphRequest -Force
} catch {
Write-Information "Failed to persist cpvtenants row for $($Item.displayName): $($_.Exception.Message)"
}
Add-CIPPAzDataTableEntity @Table -Entity $GraphRequest -Force

if ($DomainRefreshRequired) {
$UpdatedTenant = Get-Tenants -TenantFilter $Item.customerId -TriggerRefresh
if ($UpdatedTenant.defaultDomainName) {
Write-Information "Updated tenant domains $($UpdatedTenant.defaultDomainName)"
try {
$UpdatedTenant = Get-Tenants -TenantFilter $Item.customerId -TriggerRefresh
if ($UpdatedTenant.defaultDomainName) {
Write-Information "Updated tenant domains $($UpdatedTenant.defaultDomainName)"
}
} catch {
Write-Information "Failed to refresh tenant domains for $($Item.displayName): $($_.Exception.Message)"
}
}
} catch {
Write-Information "Error updating permissions for $($Item.displayName): $($_.Exception.Message)"
Write-Information $_.InvocationInfo.PositionMessage
Write-LogMessage -tenant $Item.defaultDomainName -tenantId $Item.customerId -message "Error updating permissions for $($Item.displayName) - $($_.Exception.Message)" -Sev 'Error' -API 'UpdatePermissionsQueue' -LogData (Get-CippException -Exception $_)
}
}
Loading