Skip to content

Commit c0a9460

Browse files
authored
Merge pull request KelvinTegelaar#1918 from KelvinTegelaar/dev
Dev to hotfix
2 parents cdeaa6d + a30d281 commit c0a9460

File tree

16 files changed

+451
-129
lines changed

16 files changed

+451
-129
lines changed

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,3 +20,4 @@ yarn.lock
2020
# Ignore all root PowerShell files except profile.ps1
2121
/*.ps1
2222
!/profile.ps1
23+
.DS_Store

Modules/CIPPCore/Public/Add-CIPPScheduledTask.ps1

Lines changed: 21 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,29 +1,28 @@
11
function Add-CIPPScheduledTask {
2-
[CmdletBinding(DefaultParameterSetName = 'Default')]
2+
[CmdletBinding()]
33
param(
4-
[Parameter(Mandatory = $true, ParameterSetName = 'Default')]
4+
[Parameter(Mandatory = $false)]
55
[pscustomobject]$Task,
66

7-
[Parameter(Mandatory = $false, ParameterSetName = 'Default')]
7+
[Parameter(Mandatory = $false)]
88
[bool]$Hidden,
99

10-
[Parameter(Mandatory = $false, ParameterSetName = 'Default')]
10+
[Parameter(Mandatory = $false)]
1111
$DisallowDuplicateName = $false,
1212

13-
[Parameter(Mandatory = $false, ParameterSetName = 'Default')]
13+
[Parameter(Mandatory = $false)]
1414
[string]$SyncType = $null,
1515

16-
[Parameter(Mandatory = $false, ParameterSetName = 'RunNow')]
16+
[Parameter(Mandatory = $false)]
1717
[switch]$RunNow,
1818

19-
[Parameter(Mandatory = $true, ParameterSetName = 'RunNow')]
20-
[string]$RowKey,
19+
[Parameter(Mandatory = $false)]
20+
[string]$RowKey = $null,
2121

22-
[Parameter(Mandatory = $false, ParameterSetName = 'Default')]
22+
[Parameter(Mandatory = $false)]
2323
[string]$DesiredStartTime = $null,
2424

25-
[Parameter(Mandatory = $false, ParameterSetName = 'Default')]
26-
[Parameter(Mandatory = $false, ParameterSetName = 'RunNow')]
25+
[Parameter(Mandatory = $false)]
2726
$Headers
2827
)
2928

@@ -39,6 +38,9 @@ function Add-CIPPScheduledTask {
3938
$ExistingTask.TaskState = 'Planned'
4039
Add-CIPPAzDataTableEntity @Table -Entity $ExistingTask -Force
4140
Write-LogMessage -headers $Headers -API 'RunNow' -message "Task $($ExistingTask.Name) scheduled to run now" -Sev 'Info' -Tenant $ExistingTask.Tenant
41+
Add-CippQueueMessage -Cmdlet 'Start-UserTasksOrchestrator' -Parameters @{
42+
TaskId = $RowKey
43+
}
4244
return "Task $($ExistingTask.Name) scheduled to run now"
4345
} catch {
4446
$ErrorMessage = Get-NormalizedError -Message $_.Exception.Message
@@ -192,6 +194,7 @@ function Add-CIPPScheduledTask {
192194
Hidden = [bool]$Hidden
193195
Results = 'Planned'
194196
AlertComment = [string]$task.AlertComment
197+
CustomSubject = [string]$task.CustomSubject
195198
}
196199

197200

@@ -299,6 +302,13 @@ function Add-CIPPScheduledTask {
299302
default { 'less than a minute' }
300303
}
301304

305+
if ($RunNow.IsPresent) {
306+
Add-CippQueueMessage -Cmdlet 'Start-UserTasksOrchestrator' -Parameters @{
307+
TaskId = $RowKey
308+
}
309+
return "Task $($entity.Name) scheduled to run now"
310+
}
311+
302312
return "Successfully added task: $($entity.Name). It will run in $relativeTime."
303313
}
304314
} catch {

Modules/CIPPCore/Public/Entrypoints/Activity Triggers/Push-CIPPDBCacheData.ps1

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -141,7 +141,7 @@ function Push-CIPPDBCacheData {
141141
'ServicePrincipalRiskDetections'
142142
'RiskDetections'
143143
'RoleEligibilitySchedules'
144-
'RoleAssignmentSchedules'
144+
'RoleAssignmentScheduleInstances'
145145
'RoleManagementPolicies'
146146
)
147147
foreach ($CacheFunction in $P2CacheFunctions) {

Modules/CIPPCore/Public/Entrypoints/HTTP Functions/CIPP/Scheduler/Invoke-AddScheduledItem.ps1

Lines changed: 17 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -18,29 +18,22 @@ function Invoke-AddScheduledItem {
1818
$HeaderProperties = @('x-ms-client-principal', 'x-ms-client-principal-id', 'x-ms-client-principal-name', 'x-forwarded-for')
1919
$Headers = $Request.Headers | Select-Object -Property $HeaderProperties -ErrorAction SilentlyContinue
2020

21-
if ($Request.Body.RunNow -eq $true) {
22-
try {
23-
$Table = Get-CIPPTable -TableName 'ScheduledTasks'
24-
$Filter = "PartitionKey eq 'ScheduledTask' and RowKey eq '$($Request.Body.RowKey)'"
25-
$ExistingTask = (Get-CIPPAzDataTableEntity @Table -Filter $Filter)
21+
$Table = Get-CIPPTable -TableName 'ScheduledTasks'
2622

27-
if ($ExistingTask) {
28-
$RerunParams = @{
29-
TenantFilter = $ExistingTask.Tenant
30-
Type = 'ScheduledTask'
31-
API = $Request.Body.RowKey
32-
Clear = $true
33-
}
34-
$null = Test-CIPPRerun @RerunParams
35-
$Result = Add-CIPPScheduledTask -RowKey $Request.Body.RowKey -RunNow -Headers $Headers
36-
} else {
37-
$Result = "Task with id $($Request.Body.RowKey) does not exist"
38-
}
39-
} catch {
40-
Write-Warning "Error scheduling task: $($_.Exception.Message)"
41-
Write-Information $_.InvocationInfo.PositionMessage
42-
$Result = "Error scheduling task: $($_.Exception.Message)"
23+
if ($Request.Body.RowKey) {
24+
$Filter = "PartitionKey eq 'ScheduledTask' and RowKey eq '$($Request.Body.RowKey)'"
25+
$ExistingTask = (Get-CIPPAzDataTableEntity @Table -Filter $Filter)
26+
}
27+
28+
if ($ExistingTask -and $Request.Body.RunNow -eq $true) {
29+
$RerunParams = @{
30+
TenantFilter = $ExistingTask.Tenant
31+
Type = 'ScheduledTask'
32+
API = $Request.Body.RowKey
33+
Clear = $true
4334
}
35+
$null = Test-CIPPRerun @RerunParams
36+
$Result = Add-CIPPScheduledTask -RowKey $Request.Body.RowKey -RunNow -Headers $Headers
4437
} else {
4538
$ScheduledTask = @{
4639
Task = $Request.Body
@@ -49,6 +42,9 @@ function Invoke-AddScheduledItem {
4942
DisallowDuplicateName = $DisallowDuplicateName
5043
DesiredStartTime = $Request.Body.DesiredStartTime
5144
}
45+
if ($Request.Body.RunNow -eq $true) {
46+
$ScheduledTask.RunNow = $true
47+
}
5248
$Result = Add-CIPPScheduledTask @ScheduledTask
5349
}
5450
return ([HttpResponseContext]@{

Modules/CIPPCore/Public/Entrypoints/HTTP Functions/CIPP/Scheduler/Invoke-ListScheduledItems.ps1

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,8 @@ function Invoke-ListScheduledItems {
1111
$ScheduledItemFilter.Add("PartitionKey eq 'ScheduledTask'")
1212

1313
$Id = $Request.Query.Id ?? $Request.Body.Id
14+
$TenantFilter = $Request.Query.tenantFilter ?? $Request.Body.tenantFilter
15+
1416
if ($Id) {
1517
# Interact with query parameters.
1618
$ScheduledItemFilter.Add("RowKey eq '$($Id)'")
@@ -48,6 +50,10 @@ function Invoke-ListScheduledItems {
4850
$Tasks = $Tasks | Where-Object { $_.command -eq $Type }
4951
}
5052

53+
if ($TenantFilter) {
54+
$Tasks = $Tasks | Where-Object { $_.tenant -eq $TenantFilter -or $TenantFilter -eq 'AllTenants' }
55+
}
56+
5157
if ($SearchTitle) {
5258
$Tasks = $Tasks | Where-Object { $_.Name -like $SearchTitle }
5359
}

Modules/CIPPCore/Public/Entrypoints/HTTP Functions/CIPP/Settings/Invoke-ListTenantGroups.ps1

Lines changed: 150 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,157 @@ function Invoke-ListTenantGroups {
1111
param($Request, $TriggerMetadata)
1212

1313
$groupFilter = $Request.Query.groupId ?? $Request.Body.groupId
14+
$includeUsage = $Request.Query.includeUsage ?? $Request.Body.includeUsage
1415
$TenantGroups = (Get-TenantGroups -GroupId $groupFilter -SkipCache) ?? @()
16+
17+
if ($includeUsage -eq 'true') {
18+
$UsageByGroup = @{}
19+
foreach ($Group in $TenantGroups) {
20+
$UsageByGroup[$Group.Id] = [System.Collections.Generic.List[PSCustomObject]]::new()
21+
}
22+
23+
$AddGroupUsage = {
24+
param($FilterArray, $UsedIn, $Name, $Type)
25+
foreach ($Filter in $FilterArray) {
26+
if ($Filter.type -eq 'Group' -and $Filter.value -and $UsageByGroup.ContainsKey($Filter.value)) {
27+
$UsageByGroup[$Filter.value].Add([PSCustomObject]@{
28+
UsedIn = $UsedIn
29+
Name = $Name
30+
Type = $Type
31+
})
32+
}
33+
}
34+
}
35+
36+
# Standards Templates
37+
$TemplateTable = Get-CippTable -tablename 'templates'
38+
$TemplateFilter = "PartitionKey eq 'StandardsTemplateV2'"
39+
$Templates = Get-CIPPAzDataTableEntity @TemplateTable -Filter $TemplateFilter
40+
41+
foreach ($Template in $Templates) {
42+
try {
43+
$TemplateData = $Template.JSON | ConvertFrom-Json
44+
$TemplateName = $TemplateData.templateName ?? $Template.RowKey
45+
if ($TemplateData.tenantFilter) {
46+
& $AddGroupUsage $TemplateData.tenantFilter 'Standards Template' $TemplateName 'Tenant Filter'
47+
}
48+
if ($TemplateData.excludedTenants) {
49+
& $AddGroupUsage $TemplateData.excludedTenants 'Standards Template' $TemplateName 'Excluded Tenants'
50+
}
51+
} catch {
52+
Write-Warning "Failed to parse standards template $($Template.RowKey): $($_.Exception.Message)"
53+
}
54+
}
55+
56+
# Scheduled Tasks
57+
$TaskTable = Get-CippTable -tablename 'ScheduledTasks'
58+
$TaskFilter = "PartitionKey eq 'ScheduledTask'"
59+
$Tasks = Get-CIPPAzDataTableEntity @TaskTable -Filter $TaskFilter
60+
61+
foreach ($Task in $Tasks) {
62+
if ($Task.TenantGroup) {
63+
try {
64+
$TenantGroupObject = $Task.TenantGroup | ConvertFrom-Json -ErrorAction SilentlyContinue
65+
if ($TenantGroupObject.value -and $UsageByGroup.ContainsKey($TenantGroupObject.value)) {
66+
$UsageByGroup[$TenantGroupObject.value].Add([PSCustomObject]@{
67+
UsedIn = 'Scheduled Task'
68+
Name = $Task.Name ?? $Task.RowKey
69+
Type = 'Tenant Filter'
70+
})
71+
}
72+
} catch {
73+
Write-Warning "Failed to parse tenant group for task $($Task.RowKey): $($_.Exception.Message)"
74+
}
75+
}
76+
}
77+
78+
# Dynamic Group Rules referencing other groups
79+
foreach ($Group in $TenantGroups) {
80+
if ($Group.GroupType -eq 'dynamic' -and $Group.DynamicRules) {
81+
foreach ($Rule in $Group.DynamicRules) {
82+
if ($Rule.property -eq 'TenantGroup' -and $Rule.value -and $UsageByGroup.ContainsKey($Rule.value)) {
83+
$UsageByGroup[$Rule.value].Add([PSCustomObject]@{
84+
UsedIn = 'Dynamic Group Rule'
85+
Name = $Group.Name
86+
Type = 'Rule Reference'
87+
})
88+
}
89+
}
90+
}
91+
}
92+
93+
# Webhook Rules
94+
$WebhookTable = Get-CippTable -tablename 'WebhookRules'
95+
$WebhookRules = Get-CIPPAzDataTableEntity @WebhookTable
96+
97+
foreach ($Rule in $WebhookRules) {
98+
try {
99+
$RuleName = $Rule.Name ?? $Rule.RowKey
100+
if ($Rule.Tenants) {
101+
$Tenants = $Rule.Tenants | ConvertFrom-Json -ErrorAction SilentlyContinue
102+
if ($Tenants) {
103+
& $AddGroupUsage $Tenants 'Alert Rule' $RuleName 'Tenant Filter'
104+
}
105+
}
106+
if ($Rule.excludedTenants) {
107+
$ExclTenants = $Rule.excludedTenants | ConvertFrom-Json -ErrorAction SilentlyContinue
108+
if ($ExclTenants) {
109+
& $AddGroupUsage $ExclTenants 'Alert Rule' $RuleName 'Excluded Tenants'
110+
}
111+
}
112+
} catch {
113+
Write-Warning "Failed to parse webhook rule $($Rule.RowKey): $($_.Exception.Message)"
114+
}
115+
}
116+
117+
# Custom Roles
118+
$RolesTable = Get-CippTable -tablename 'CustomRoles'
119+
$CustomRoles = Get-CIPPAzDataTableEntity @RolesTable
120+
121+
foreach ($Role in $CustomRoles) {
122+
try {
123+
$RoleName = $Role.Name ?? $Role.RowKey
124+
if ($Role.AllowedTenants) {
125+
$AllowedTenants = $Role.AllowedTenants | ConvertFrom-Json -ErrorAction SilentlyContinue
126+
if ($AllowedTenants) {
127+
& $AddGroupUsage $AllowedTenants 'Custom Role' $RoleName 'Allowed Tenants'
128+
}
129+
}
130+
if ($Role.BlockedTenants) {
131+
$BlockedTenants = $Role.BlockedTenants | ConvertFrom-Json -ErrorAction SilentlyContinue
132+
if ($BlockedTenants) {
133+
& $AddGroupUsage $BlockedTenants 'Custom Role' $RoleName 'Blocked Tenants'
134+
}
135+
}
136+
} catch {
137+
Write-Warning "Failed to parse custom role $($Role.RowKey): $($_.Exception.Message)"
138+
}
139+
}
140+
141+
# Custom Data Mappings
142+
$MappingsTable = Get-CippTable -tablename 'CustomDataMappings'
143+
$Mappings = Get-CIPPAzDataTableEntity @MappingsTable
144+
145+
foreach ($Mapping in $Mappings) {
146+
try {
147+
$MappingName = $Mapping.Name ?? $Mapping.RowKey
148+
if ($Mapping.tenantFilter) {
149+
$TenantFilters = $Mapping.tenantFilter | ConvertFrom-Json -ErrorAction SilentlyContinue
150+
if ($TenantFilters) {
151+
if ($TenantFilters -isnot [System.Array]) { $TenantFilters = @($TenantFilters) }
152+
& $AddGroupUsage $TenantFilters 'Data Mapping' $MappingName 'Tenant Filter'
153+
}
154+
}
155+
} catch {
156+
Write-Warning "Failed to parse custom data mapping $($Mapping.RowKey): $($_.Exception.Message)"
157+
}
158+
}
159+
160+
foreach ($Group in $TenantGroups) {
161+
$Group | Add-Member -MemberType NoteProperty -Name 'Usage' -Value @($UsageByGroup[$Group.Id]) -Force
162+
}
163+
}
164+
15165
$Body = @{ Results = @($TenantGroups) }
16166

17167
return ([HttpResponseContext]@{

Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Identity/Administration/Users/Invoke-CIPPOffboardingJob.ps1

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -320,7 +320,7 @@ function Invoke-CIPPOffboardingJob {
320320
}
321321
}
322322

323-
$InstanceId = Start-CIPPOrchestrator -InputObject $InputObject -CallerIsQueueTrigger
323+
$InstanceId = Start-CIPPOrchestrator -InputObject $InputObject
324324
Write-Information "Started offboarding job for $Username with ID = '$InstanceId'"
325325
Write-LogMessage -API $APIName -tenant $TenantFilter -message "Started offboarding job for $Username with $($Batch.Count) tasks. Instance ID: $InstanceId" -sev Info
326326

Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Identity/Administration/Users/Invoke-ExecOffboardUser.ps1

Lines changed: 29 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -10,39 +10,41 @@ function Invoke-ExecOffboardUser {
1010
$AllUsers = $Request.Body.user.value
1111
$TenantFilter = $request.Body.tenantFilter.value ? $request.Body.tenantFilter.value : $request.Body.tenantFilter
1212
$OffboardingOptions = $Request.Body | Select-Object * -ExcludeProperty user, tenantFilter, Scheduled
13+
14+
$StatusCode = [HttpStatusCode]::OK
1315
$Results = foreach ($username in $AllUsers) {
1416
try {
15-
$APIName = 'ExecOffboardUser'
1617
$Headers = $Request.Headers
17-
18-
19-
if ($Request.Body.Scheduled.enabled) {
20-
$taskObject = [PSCustomObject]@{
21-
TenantFilter = $TenantFilter
22-
Name = "Offboarding: $Username"
23-
Command = @{
24-
value = 'Invoke-CIPPOffboardingJob'
25-
}
26-
Parameters = [pscustomobject]@{
27-
Username = $Username
28-
APIName = 'Scheduled Offboarding'
29-
options = $OffboardingOptions
30-
RunScheduled = $true
31-
}
32-
ScheduledTime = $Request.Body.Scheduled.date
33-
PostExecution = @{
34-
Webhook = [bool]$Request.Body.PostExecution.webhook
35-
Email = [bool]$Request.Body.PostExecution.email
36-
PSA = [bool]$Request.Body.PostExecution.psa
37-
}
38-
Reference = $Request.Body.reference
18+
$taskObject = [PSCustomObject]@{
19+
TenantFilter = $TenantFilter
20+
Name = "Offboarding: $Username"
21+
Command = @{
22+
value = 'Invoke-CIPPOffboardingJob'
23+
}
24+
Parameters = [pscustomobject]@{
25+
Username = $Username
26+
APIName = 'Scheduled Offboarding'
27+
options = $OffboardingOptions
28+
RunScheduled = $true
3929
}
40-
Add-CIPPScheduledTask -Task $taskObject -hidden $false -Headers $Headers
30+
PostExecution = @{
31+
Webhook = [bool]$Request.Body.PostExecution.webhook
32+
Email = [bool]$Request.Body.PostExecution.email
33+
PSA = [bool]$Request.Body.PostExecution.psa
34+
}
35+
Reference = $Request.Body.reference
36+
}
37+
$Params = @{
38+
Task = $taskObject
39+
hidden = $false
40+
Headers = $Headers
41+
}
42+
if ($Request.Body.Scheduled.enabled) {
43+
$taskObject.ScheduledTime = $Request.Body.Scheduled.date
4144
} else {
42-
Invoke-CIPPOffboardingJob -Username $Username -TenantFilter $TenantFilter -Options $OffboardingOptions -APIName $APIName -Headers $Headers
45+
$Params.RunNow = $true
4346
}
44-
$StatusCode = [HttpStatusCode]::OK
45-
47+
Add-CIPPScheduledTask @Params
4648
} catch {
4749
$StatusCode = [HttpStatusCode]::Forbidden
4850
$_.Exception.message

0 commit comments

Comments
 (0)