Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
142 commits
Select commit Hold shift + click to select a range
358966a
Refactor BEC remediation process to use Set-CIPPMailboxRule for disab…
kris6673 Jun 20, 2025
1c4e9f4
Feat: Add add Room list function
kris6673 Jun 18, 2025
36ec6fc
Refactor Invoke-ListRoomLists to use EXO commands for immediate room …
kris6673 Jun 18, 2025
86ea72f
Remove redundant groupType property assignment in Invoke-ListRoomList…
kris6673 Jun 23, 2025
8c655d1
Set-CIPPMailboxType throw support
kris6673 Jun 24, 2025
7d6d9af
Support throw for Revoke-CIPPSessions
kris6673 Jun 24, 2025
140c595
Support throw for Set-CIPPResetPassword
kris6673 Jun 24, 2025
1f99858
Support throw in Set-CIPPHideFromGAL and fix message
kris6673 Jun 24, 2025
01cc78c
Support throw for Set-CIPPSignInState
kris6673 Jun 24, 2025
6ebc95b
Support throw in Set-CIPPSharePointPerms and Set-CIPPMailboxAccess
kris6673 Jun 24, 2025
8868dfd
Support throw for Set-CIPPForwarding and refactor function
kris6673 Jun 24, 2025
6cff746
Refactor into switch and add comments
kris6673 Jun 24, 2025
1a603ba
Support throw for Remove-CIPPUser
kris6673 Jun 24, 2025
a19beb0
Refactor to use Remove-CIPPUser
kris6673 Jun 24, 2025
1b13740
Support throw for Remove-CIPPMailboxRule
kris6673 Jun 24, 2025
d4dd3ca
Support throw for Remove-CIPPMobileDevice and modernize function
kris6673 Jun 24, 2025
cb7b0d3
Add .cursor/rules to .gitignore
kris6673 Jun 24, 2025
e831f0f
Support throw for Remove-CIPPCalendarInvites
kris6673 Jun 24, 2025
1e7ea9e
Support throw for Clear-CIPPImmutableID
kris6673 Jun 24, 2025
f15b13d
Support throw for Remove-CIPPUserMFA too
kris6673 Jun 24, 2025
1c34041
Enhance Invoke-EditGroup and Invoke-ListGroups functions to support h…
kris6673 Jun 26, 2025
578c880
Speed up some standards and fix alerting in DefaultSharingLink
kris6673 Jun 26, 2025
885da03
Speed up some standards and fix alerting in DefaultSharingLink
kris6673 Jun 26, 2025
3da186c
Remove debug warning for DesiredSharingLinkTypeValue in Invoke-CIPPSt…
kris6673 Jun 26, 2025
1ce871e
Deprecate SPDirectSharing
kris6673 Jun 26, 2025
1b0b5c6
Fix wrong alert type
kris6673 Jun 26, 2025
f95cfc5
Fix: Fix tablefilter
kris6673 Jun 28, 2025
b737c18
Enhance Invoke-ListAppConsentRequests: Add server-side filtering for …
kris6673 Jun 28, 2025
cf7d592
Add PATCH method used by Invoke-EditIntuneScript
ngms-psh Jun 29, 2025
3028825
Merge pull request #1541 from kris6673/app-consent
KelvinTegelaar Jun 29, 2025
ae4c826
Merge pull request #1538 from kris6673/feat-HiddenFromExchangeClients…
KelvinTegelaar Jun 29, 2025
5a87efc
Merge pull request #1527 from kris6673/room-lists
KelvinTegelaar Jun 29, 2025
57fec34
Revert "Deprecate SPDirectSharing"
kris6673 Jun 29, 2025
edda501
Add PATCH method used by Invoke-EditIntuneScript
ngms-psh Jun 29, 2025
9f05c96
Merge branch 'fix-scriptedit' of https://github.com/ngms-psh/CIPP-API…
ngms-psh Jun 29, 2025
3a96746
Changed method for EditIntuneScript to POST
ngms-psh Jun 29, 2025
2dcec44
Revert to only allowing GET and POST methods
ngms-psh Jun 29, 2025
25419ba
Merge pull request #1523 from kris6673/bec-mb-logging
KelvinTegelaar Jun 29, 2025
bc30160
new standard CustomBannedPasswordList
kris6673 Jun 29, 2025
af47716
whoops
kris6673 Jun 30, 2025
a67c910
Add defender exclusions page
kris6673 Jun 30, 2025
a8a64f8
Update to only run compliance part if the toggle was set in the frontend
kris6673 Jun 30, 2025
634e27d
catch invalid json parsing and provide initial values
JohnDuprey Jul 1, 2025
2968fd3
new permission output for menu limits
JohnDuprey Jul 1, 2025
643dfcb
Update Get-CippAllowedPermissions.ps1
JohnDuprey Jul 1, 2025
5da7856
Update role in Invoke-ExecCSPLicense to Tenant.Directory.ReadWrite
kris6673 Jul 1, 2025
c737482
fix graph presets
JohnDuprey Jul 1, 2025
603ec59
Merge pull request #1546 from kris6673/fix-permissions
KelvinTegelaar Jul 2, 2025
dbeacdf
Merge pull request #1543 from kris6673/CustomBannedPasswordList
KelvinTegelaar Jul 2, 2025
f0fa09c
Merge pull request #1542 from ngms-psh/fix-scriptedit
KelvinTegelaar Jul 2, 2025
189ccf0
Merge pull request #1539 from kris6673/fix-SP-standards-speed
KelvinTegelaar Jul 2, 2025
a998f55
update execedittemplate
KelvinTegelaar Jul 2, 2025
0e1cd79
add openapi specs
KelvinTegelaar Jul 2, 2025
4b7aa1e
Casing
kris6673 Jul 2, 2025
3286d83
update template editor
KelvinTegelaar Jul 2, 2025
9f9de42
Merge branch 'dev' into offboarding
kris6673 Jul 2, 2025
5eb8094
Merge pull request #1530 from kris6673/offboarding
JohnDuprey Jul 2, 2025
65f4597
Refactor Invoke-EditUser to streamline result handling and improve lo…
kris6673 Jul 2, 2025
113d98a
Merge pull request #1545 from kris6673/defender-exclusions
JohnDuprey Jul 2, 2025
9cc2fbe
fix tenant access check
JohnDuprey Jul 3, 2025
fb00fcd
be more explicit with principalId
JohnDuprey Jul 3, 2025
3b25067
Update Invoke-ExecExchangeRoleRepair.ps1
JohnDuprey Jul 3, 2025
84a5e46
Update Invoke-ExecExchangeRoleRepair.ps1
JohnDuprey Jul 3, 2025
1fd7eee
Update Invoke-ExecPermissionRepair.ps1
JohnDuprey Jul 3, 2025
e1b56f3
update logging
JohnDuprey Jul 3, 2025
2ad9663
Update Invoke-ExecExchangeRoleRepair.ps1
JohnDuprey Jul 3, 2025
dda5502
Update Invoke-ExecExchangeRoleRepair.ps1
JohnDuprey Jul 3, 2025
d40c2bc
Update Invoke-ExecExchangeRoleRepair.ps1
JohnDuprey Jul 3, 2025
360e058
Update Invoke-ExecExchangeRoleRepair.ps1
JohnDuprey Jul 3, 2025
5c84a00
Update Invoke-ExecExchangeRoleRepair.ps1
JohnDuprey Jul 3, 2025
665279b
Merge pull request #1549 from kris6673/gary-magical-branch
KelvinTegelaar Jul 4, 2025
3572adf
Improve error handling in BEC remediation and PwPush link creation
Zacgoose Jul 7, 2025
648ce36
teams testing
JohnDuprey Jul 7, 2025
4d8e670
Update New-TeamsAPIGetRequest.ps1
JohnDuprey Jul 7, 2025
801b106
Update New-TeamsAPIGetRequest.ps1
JohnDuprey Jul 7, 2025
f9d4d02
Update New-TeamsAPIGetRequest.ps1
JohnDuprey Jul 7, 2025
f239854
Update New-TeamsAPIGetRequest.ps1
JohnDuprey Jul 7, 2025
2d7ec43
testing
JohnDuprey Jul 7, 2025
d2ace52
Update New-TeamsAPIGetRequest.ps1
JohnDuprey Jul 7, 2025
8448418
fix teams voice
JohnDuprey Jul 7, 2025
bf273a8
tidy code
JohnDuprey Jul 8, 2025
dbd5265
fix ids in edit group
JohnDuprey Jul 8, 2025
7a106ff
fix properties and logging
JohnDuprey Jul 8, 2025
85a094b
Update Invoke-EditGroup.ps1
JohnDuprey Jul 8, 2025
ac5acaa
add migration sstandard for auth states
KelvinTegelaar Jul 8, 2025
d1d0d5c
fixes compares of specific intune objects
KelvinTegelaar Jul 8, 2025
ef6aa46
tenant group support in cipp roles
JohnDuprey Jul 8, 2025
53cdca4
fix sharepoint member endpoint
JohnDuprey Jul 8, 2025
ca5a8f3
Try disable delegate rules but ignore errors if it fails
Zacgoose Jul 9, 2025
058d307
Add service provider exception
Jul 9, 2025
34e75e4
add support for tenant groups
JohnDuprey Jul 10, 2025
e1cd451
tenant group support for scripted alerts
JohnDuprey Jul 10, 2025
359ea31
Update Invoke-ListScheduledItems.ps1
JohnDuprey Jul 10, 2025
1e300e4
tweak scheduled tasks
JohnDuprey Jul 10, 2025
b8c7320
local dev fix part 2
JohnDuprey Jul 10, 2025
89e068f
multiple user support for vacation mode
JohnDuprey Jul 11, 2025
5f63ec7
update sort for scheduled items
JohnDuprey Jul 11, 2025
6e53124
update logging
JohnDuprey Jul 11, 2025
84eb43a
Update Invoke-ExecCAExclusion.ps1
JohnDuprey Jul 11, 2025
8bdf57c
Update Invoke-ExecCAExclusion.ps1
JohnDuprey Jul 11, 2025
466cb6d
- fix returns and logging.
kris6673 Jul 11, 2025
be076b5
scheduler fixes
JohnDuprey Jul 11, 2025
74652dd
Update New-CIPPBackup.ps1
JohnDuprey Jul 11, 2025
551f5d4
scheduler/offboarding tweaks
JohnDuprey Jul 11, 2025
1837ec2
application gallery support
JohnDuprey Jul 11, 2025
4c71701
Update license files to newest from MS
kris6673 Jul 11, 2025
67162fe
fix sherweb license add from form
JohnDuprey Jul 11, 2025
fff1b07
app manifest support
JohnDuprey Jul 11, 2025
1871edc
new application actions
JohnDuprey Jul 12, 2025
fa50f5d
improve password cred removal
JohnDuprey Jul 12, 2025
4397a3c
add disable Ca
KelvinTegelaar Jul 12, 2025
fb9819c
updates for ca disablement
KelvinTegelaar Jul 12, 2025
aa46143
new allignment score api
KelvinTegelaar Jul 12, 2025
6b0de81
datetime fix
KelvinTegelaar Jul 12, 2025
d7914ea
updated standard
KelvinTegelaar Jul 12, 2025
fe773be
Revert as reporting no longer worked correctly.
KelvinTegelaar Jul 12, 2025
5702b8d
fix write hosts
KelvinTegelaar Jul 13, 2025
ef68f54
Fixes report
KelvinTegelaar Jul 13, 2025
5306ca1
added report
KelvinTegelaar Jul 13, 2025
5db6d40
fix state
KelvinTegelaar Jul 13, 2025
67ff06f
fix reporting
KelvinTegelaar Jul 13, 2025
7eba580
done
KelvinTegelaar Jul 13, 2025
b50118e
Fix reporting
KelvinTegelaar Jul 13, 2025
c3204ee
grouptemplate
KelvinTegelaar Jul 13, 2025
0b7def3
fix reporting
KelvinTegelaar Jul 13, 2025
f580978
add alignment alert
KelvinTegelaar Jul 13, 2025
361a68f
fixes
KelvinTegelaar Jul 13, 2025
2439438
license check changes
KelvinTegelaar Jul 14, 2025
e3b8e7a
Sharepoint license checks
KelvinTegelaar Jul 14, 2025
869b96f
Add License checks for intune
KelvinTegelaar Jul 14, 2025
cac0ef7
autopilot profiles
KelvinTegelaar Jul 14, 2025
682ff58
Teams update
KelvinTegelaar Jul 14, 2025
8d45ef1
combined alignment score
KelvinTegelaar Jul 14, 2025
a2fb3ca
Merge pull request #1551 from Zacgoose/BEC-actions-fixes
KelvinTegelaar Jul 14, 2025
be48b73
Merge pull request #1553 from kris6673/license-update
KelvinTegelaar Jul 14, 2025
fb00e7f
Merge pull request #1552 from kris6673/fix-SP-UTF8
KelvinTegelaar Jul 14, 2025
c8f257f
DKIM
KelvinTegelaar Jul 14, 2025
9a2a834
license update
KelvinTegelaar Jul 14, 2025
89b53e1
license update
KelvinTegelaar Jul 14, 2025
3073d32
delete scratch files and maintence
KelvinTegelaar Jul 14, 2025
f0e5936
up version
KelvinTegelaar Jul 14, 2025
b58324a
Merge pull request #1554 from KelvinTegelaar/dev
KelvinTegelaar Jul 14, 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
4 changes: 4 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -9,3 +9,7 @@ Logs
ExcludedTenants
SendNotifications/config.json
.env


# Cursor IDE
.cursor/rules
255 changes: 157 additions & 98 deletions ConversionTable.csv

Large diffs are not rendered by default.

250 changes: 161 additions & 89 deletions Modules/CIPPCore/Public/Add-CIPPScheduledTask.ps1
Original file line number Diff line number Diff line change
Expand Up @@ -24,106 +24,178 @@ function Add-CIPPScheduledTask {
$Headers
)

$Table = Get-CIPPTable -TableName 'ScheduledTasks'

if ($RunNow.IsPresent -and $RowKey) {
try {
$Filter = "PartitionKey eq 'ScheduledTask' and RowKey eq '$($RowKey)'"
$ExistingTask = (Get-CIPPAzDataTableEntity @Table -Filter $Filter)
$ExistingTask.ScheduledTime = [int64](([datetime]::UtcNow) - (Get-Date '1/1/1970')).TotalSeconds
$ExistingTask.TaskState = 'Planned'
Add-CIPPAzDataTableEntity @Table -Entity $ExistingTask -Force
Write-LogMessage -headers $Headers -API 'RunNow' -message "Task $($ExistingTask.Name) scheduled to run now" -Sev 'Info' -Tenant $ExistingTask.Tenant
return "Task $($ExistingTask.Name) scheduled to run now"
} catch {
$ErrorMessage = Get-NormalizedError -Message $_.Exception.Message
Write-LogMessage -headers $Headers -API 'RunNow' -message "Could not run task: $ErrorMessage" -Sev 'Error'
return "Could not run task: $ErrorMessage"
}
} else {
if ($DisallowDuplicateName) {
$Filter = "PartitionKey eq 'ScheduledTask' and Name eq '$($Task.Name)'"
$ExistingTask = (Get-CIPPAzDataTableEntity @Table -Filter $Filter)
if ($ExistingTask) {
return "Task with name $($Task.Name) already exists"
try {

$Table = Get-CIPPTable -TableName 'ScheduledTasks'

if ($RunNow.IsPresent -and $RowKey) {
try {
$Filter = "PartitionKey eq 'ScheduledTask' and RowKey eq '$($RowKey)'"
$ExistingTask = (Get-CIPPAzDataTableEntity @Table -Filter $Filter)
$ExistingTask.ScheduledTime = [int64](([datetime]::UtcNow) - (Get-Date '1/1/1970')).TotalSeconds
$ExistingTask.TaskState = 'Planned'
Add-CIPPAzDataTableEntity @Table -Entity $ExistingTask -Force
Write-LogMessage -headers $Headers -API 'RunNow' -message "Task $($ExistingTask.Name) scheduled to run now" -Sev 'Info' -Tenant $ExistingTask.Tenant
return "Task $($ExistingTask.Name) scheduled to run now"
} catch {
$ErrorMessage = Get-NormalizedError -Message $_.Exception.Message
Write-LogMessage -headers $Headers -API 'RunNow' -message "Could not run task: $ErrorMessage" -Sev 'Error'
return "Could not run task: $ErrorMessage"
}
}
} else {
if ($DisallowDuplicateName) {
$Filter = "PartitionKey eq 'ScheduledTask' and Name eq '$($Task.Name)'"
$ExistingTask = (Get-CIPPAzDataTableEntity @Table -Filter $Filter)
if ($ExistingTask) {
return "Task with name $($Task.Name) already exists"
}
}

$propertiesToCheck = @('Webhook', 'Email', 'PSA')
$PostExecutionObject = ($propertiesToCheck | Where-Object { $task.PostExecution.$_ -eq $true })
$PostExecution = $PostExecutionObject ? ($PostExecutionObject -join ',') : ($Task.PostExecution.value -join ',')
$Parameters = [System.Collections.Hashtable]@{}
foreach ($Key in $task.Parameters.PSObject.Properties.Name) {
$Param = $task.Parameters.$Key

if ($null -eq $Param -or $Param -eq '' -or ($Param | Measure-Object).Count -eq 0) {
continue
}

$propertiesToCheck = @('Webhook', 'Email', 'PSA')
$PostExecutionObject = ($propertiesToCheck | Where-Object { $task.PostExecution.$_ -eq $true })
$PostExecution = $PostExecutionObject ? ($PostExecutionObject -join ',') : ($Task.PostExecution.value -join ',')
$Parameters = [System.Collections.Hashtable]@{}
foreach ($Key in $task.Parameters.PSObject.Properties.Name) {
$Param = $task.Parameters.$Key
# handle different object types in params
if ($Param -is [System.Collections.IDictionary] -or $Param[0].Key) {
Write-Information "Parameter $Key is a hashtable"
$ht = @{}
foreach ($p in $Param.GetEnumerator()) {
$ht[$p.Key] = $p.Value
}
$Parameters[$Key] = [PSCustomObject]$ht
Write-Information "Converted $Key to PSObject $($Parameters[$Key] | ConvertTo-Json -Compress)"
} elseif ($Param -is [System.Object[]] -and -not ($Param -is [string])) {
Write-Information "Parameter $Key is an enumerable object"
$Param = $Param | ForEach-Object {
if ($null -eq $_) {
# Skip null entries
return
}
if ($_ -is [System.Collections.IDictionary]) {
[PSCustomObject]$_
} elseif ($_ -is [PSCustomObject]) {
$_
} else {
$_
}
} | Where-Object { $null -ne $_ }
$Parameters[$Key] = $Param
} else {
Write-Information "Parameter $Key is a simple value"
$Parameters[$Key] = $Param
}
}

if ($null -eq $Param -or $Param -eq '' -or ($Param | Measure-Object).Count -eq 0) {
continue
if ($Headers) {
$Parameters.Headers = $Headers | Select-Object -Property 'x-forwarded-for', 'x-ms-client-principal', 'x-ms-client-principal-idp', 'x-ms-client-principal-name'
}
if ($Param -is [System.Collections.IDictionary] -or $Param.Key) {
$ht = @{}
foreach ($p in $Param.GetEnumerator()) {
$ht[$p.Key] = $p.Value

$Parameters = ($Parameters | ConvertTo-Json -Depth 10 -Compress)
$AdditionalProperties = [System.Collections.Hashtable]@{}
foreach ($Prop in $task.AdditionalProperties) {
if ($null -eq $Prop.Value -or $Prop.Value -eq '' -or ($Prop.Value | Measure-Object).Count -eq 0) {
continue
}
$Parameters[$Key] = [PSCustomObject]$ht
$AdditionalProperties[$Prop.Key] = $Prop.Value
}
$AdditionalProperties = ([PSCustomObject]$AdditionalProperties | ConvertTo-Json -Compress)
if ($Parameters -eq 'null') { $Parameters = '' }
if (!$Task.RowKey) {
$RowKey = (New-Guid).Guid
} else {
$Parameters[$Key] = $Param
$RowKey = $Task.RowKey
}
}

if ($Headers) {
$Parameters.Headers = $Headers | Select-Object -Property 'x-forwarded-for', 'x-ms-client-principal', 'x-ms-client-principal-idp', 'x-ms-client-principal-name'
}
$Recurrence = if ([string]::IsNullOrEmpty($task.Recurrence.value)) {
$task.Recurrence
} else {
$task.Recurrence.value
}

$Parameters = ($Parameters | ConvertTo-Json -Depth 10 -Compress)
$AdditionalProperties = [System.Collections.Hashtable]@{}
foreach ($Prop in $task.AdditionalProperties) {
$AdditionalProperties[$Prop.Key] = $Prop.Value
}
$AdditionalProperties = ([PSCustomObject]$AdditionalProperties | ConvertTo-Json -Compress)
if ($Parameters -eq 'null') { $Parameters = '' }
if (!$Task.RowKey) {
$RowKey = (New-Guid).Guid
} else {
$RowKey = $Task.RowKey
}
if ([int64]$task.ScheduledTime -eq 0 -or [string]::IsNullOrEmpty($task.ScheduledTime)) {
$task.ScheduledTime = [int64](([datetime]::UtcNow) - (Get-Date '1/1/1970')).TotalSeconds
}
$excludedTenants = if ($task.excludedTenants.value) {
$task.excludedTenants.value -join ','
}

$Recurrence = if ([string]::IsNullOrEmpty($task.Recurrence.value)) {
$task.Recurrence
} else {
$task.Recurrence.value
}
# Handle tenant filter - support both single tenant and tenant groups
$tenantFilter = $task.TenantFilter.value ? $task.TenantFilter.value : $task.TenantFilter
$originalTenantFilter = $task.TenantFilter

if ([int64]$task.ScheduledTime -eq 0 -or [string]::IsNullOrEmpty($task.ScheduledTime)) {
$task.ScheduledTime = [int64](([datetime]::UtcNow) - (Get-Date '1/1/1970')).TotalSeconds
}
$excludedTenants = if ($task.excludedTenants.value) {
$task.excludedTenants.value -join ','
}
$entity = @{
PartitionKey = [string]'ScheduledTask'
TaskState = [string]'Planned'
RowKey = [string]$RowKey
Tenant = $task.TenantFilter.value ? "$($task.TenantFilter.value)" : "$($task.TenantFilter)"
excludedTenants = [string]$excludedTenants
Name = [string]$task.Name
Command = [string]$task.Command.value
Parameters = [string]$Parameters
ScheduledTime = [string]$task.ScheduledTime
Recurrence = [string]$Recurrence
PostExecution = [string]$PostExecution
AdditionalProperties = [string]$AdditionalProperties
Hidden = [bool]$Hidden
Results = 'Planned'
}
if ($SyncType) {
$entity.SyncType = $SyncType
}
try {
Add-CIPPAzDataTableEntity @Table -Entity $entity -Force
} catch {
$ErrorMessage = Get-NormalizedError -Message $_.Exception.Message
return "Could not add task: $ErrorMessage"
# If tenant filter is a complex object (from form), extract the value
if ($tenantFilter -is [PSCustomObject] -and $tenantFilter.value) {
$originalTenantFilter = $tenantFilter
$tenantFilter = $tenantFilter.value
}

# If tenant filter is a string but still seems to be JSON, try to parse it
if ($tenantFilter -is [string] -and $tenantFilter.StartsWith('{')) {
try {
$parsedTenantFilter = $tenantFilter | ConvertFrom-Json
if ($parsedTenantFilter.value) {
$originalTenantFilter = $parsedTenantFilter
$tenantFilter = $parsedTenantFilter.value
}
} catch {
# If parsing fails, use the string as is
Write-Warning "Could not parse tenant filter JSON: $tenantFilter"
}
}

$entity = @{
PartitionKey = [string]'ScheduledTask'
TaskState = [string]'Planned'
RowKey = [string]$RowKey
Tenant = [string]$tenantFilter
excludedTenants = [string]$excludedTenants
Name = [string]$task.Name
Command = [string]$task.Command.value
Parameters = [string]$Parameters
ScheduledTime = [string]$task.ScheduledTime
Recurrence = [string]$Recurrence
PostExecution = [string]$PostExecution
AdditionalProperties = [string]$AdditionalProperties
Hidden = [bool]$Hidden
Results = 'Planned'
}

# Store the original tenant filter for group expansion during execution
if ($originalTenantFilter -is [PSCustomObject] -and $originalTenantFilter.type -eq 'Group') {
$entity['TenantGroup'] = [string]($originalTenantFilter | ConvertTo-Json -Compress)
} elseif ($originalTenantFilter -is [string] -and $originalTenantFilter.StartsWith('{')) {
# Check if it's a serialized group object
try {
$parsedOriginal = $originalTenantFilter | ConvertFrom-Json
if ($parsedOriginal.type -eq 'Group') {
$entity['TenantGroup'] = [string]$originalTenantFilter
}
} catch {
# Not a JSON object, ignore
}
}
if ($SyncType) {
$entity.SyncType = $SyncType
}
try {
Add-CIPPAzDataTableEntity @Table -Entity $entity -Force
} catch {
$ErrorMessage = Get-NormalizedError -Message $_.Exception.Message
return "Could not add task: $ErrorMessage"
}
return "Successfully added task: $($entity.Name)"
}
return "Successfully added task: $($entity.Name)"
} catch {
Write-Warning "Failed to add scheduled task: $($_.Exception.Message)"
Write-Information $_.InvocationInfo.PositionMessage
$ErrorMessage = Get-NormalizedError -Message $_.Exception.Message
throw "Could not add task: $ErrorMessage"
}
}
52 changes: 52 additions & 0 deletions Modules/CIPPCore/Public/Alerts/Get-CIPPAlertLowTenantAlignment.ps1
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
function Get-CIPPAlertLowTenantAlignment {
<#
.SYNOPSIS
Alert for low tenant alignment percentage
.DESCRIPTION
This alert checks tenant alignment scores against standards templates and alerts when the alignment percentage falls below the specified threshold.
.PARAMETER TenantFilter
The tenant to check alignment for
.PARAMETER InputValue
The minimum alignment percentage threshold (0-100). Default is 80.
.FUNCTIONALITY
Entrypoint
.EXAMPLE
Get-CIPPAlertLowTenantAlignment -TenantFilter "contoso.onmicrosoft.com" -InputValue 75
#>
[CmdletBinding()]
param (
[Parameter(Mandatory)]
$TenantFilter,
[Alias('input')]
[ValidateRange(0, 100)]
[int]$InputValue = 99
)

try {
# Get tenant alignment data using the new function
$AlignmentData = Get-CIPPTenantAlignment -TenantFilter $TenantFilter

if (-not $AlignmentData) {
Write-AlertMessage -tenant $TenantFilter -message "No alignment data found for tenant $TenantFilter. This may indicate no standards templates are configured or applied to this tenant."
return
}

$LowAlignmentAlerts = $AlignmentData | Where-Object { $_.AlignmentScore -lt $InputValue } | ForEach-Object {
[PSCustomObject]@{
TenantFilter = $_.TenantFilter
StandardName = $_.StandardName
StandardId = $_.StandardId
AlignmentScore = $_.AlignmentScore
LicenseMissingPercentage = $_.LicenseMissingPercentage
LatestDataCollection = $_.LatestDataCollection
}
}

if ($LowAlignmentAlerts.Count -gt 0) {
Write-AlertTrace -cmdletName $MyInvocation.MyCommand -tenantFilter $TenantFilter -data $LowAlignmentAlerts
}

} catch {
Write-AlertMessage -tenant $TenantFilter -message "Could not get tenant alignment data for $TenantFilter`: $(Get-NormalizedError -message $_.Exception.message)"
}
}
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
function Get-CIPPHttpFunctions {
Param(
param(
[switch]$ByRole,
[switch]$ByRoleGroup
)
Expand All @@ -8,7 +8,7 @@ function Get-CIPPHttpFunctions {
$Functions = Get-Command -Module CIPPCore | Where-Object { $_.Visibility -eq 'Public' -and $_.Name -match 'Invoke-*' }
$Results = foreach ($Function in $Functions) {
$Help = Get-Help $Function
if ($Help.Functionality -ne 'Entrypoint') { continue }
if ($Help.Functionality -notmatch 'Entrypoint') { continue }
if ($Help.Role -eq 'Public') { continue }
[PSCustomObject]@{
Function = $Function.Name
Expand Down
Loading