Skip to content

Commit 7e862f4

Browse files
Merge branch 'KelvinTegelaar:master' into master
2 parents 8554796 + f0e0d46 commit 7e862f4

File tree

135 files changed

+3155
-602
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

135 files changed

+3155
-602
lines changed

CIPP-Permissions.json

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -425,6 +425,11 @@
425425
"Name": "UserAuthenticationMethod.ReadWrite",
426426
"Description": "Allows the app to read and write your authentication methods, including phone numbers and Authenticator app settings.This does not allow the app to see secret information like your passwords, or to sign-in or otherwise use your authentication methods."
427427
},
428+
{
429+
"Id": "424b07a8-1209-4d17-9fe4-9018a93a1024",
430+
"Name": "TeamsTelephoneNumber.ReadWrite.All",
431+
"Description": "Allows the app to read and modify your tenant's acquired telephone number details on behalf of the signed-in admin user. Acquired telephone numbers may include attributes related to assigned object, emergency location, network site, etc."
432+
},
428433
{
429434
"Id": "b7887744-6746-4312-813d-72daeaee7e2d",
430435
"Name": "UserAuthenticationMethod.ReadWrite.All",
@@ -697,6 +702,11 @@
697702
"Name": "User.ReadWrite.All",
698703
"Description": "Allows the app to read and update user profiles without a signed in user."
699704
},
705+
{
706+
"Id": "0a42382f-155c-4eb1-9bdc-21548ccaa387",
707+
"Name": "TeamsTelephoneNumber.ReadWrite.All",
708+
"Description": "Allows the app to read your tenant's acquired telephone number details, without a signed-in user. Acquired telephone numbers may include attributes related to assigned object, emergency location, network site, etc."
709+
},
700710
{
701711
"Id": "50483e42-d915-4231-9639-7fdb7fd190e5",
702712
"Name": "UserAuthenticationMethod.ReadWrite.All",

CommunityRepos.json

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,22 @@
11
[
2+
{
3+
"Id": "1041442982",
4+
"Name": "CISTemplates",
5+
"Description": "CIPP CIS Templates",
6+
"URL": "https://github.com/CyberDrain/CyberDrain-CIS-Templates",
7+
"FullName": "CyberDrain/CyberDrain-CIS-Templates",
8+
"Owner": "CyberDrain",
9+
"Visibility": "public",
10+
"WriteAccess": false,
11+
"DefaultBranch": "main",
12+
"RepoPermissions": {
13+
"admin": false,
14+
"maintain": false,
15+
"push": false,
16+
"triage": false,
17+
"pull": true
18+
}
19+
},
220
{
321
"Id": "930523724",
422
"Name": "CIPP-Templates",
@@ -52,5 +70,23 @@
5270
"triage": false,
5371
"pull": true
5472
}
73+
},
74+
{
75+
"Id": "863076113",
76+
"Name": "IntuneBaseLines",
77+
"Description": "In this repo, you will find Intune profiles in JSON format, which can be used in setting up your Modern Workplace. All policies were created in Microsoft Intune and exported to share with the community.",
78+
"URL": "https://github.com/IntuneAdmin/IntuneBaselines",
79+
"FullName": "IntuneAdmin/IntuneBaselines",
80+
"Owner": "IntuneAdmin",
81+
"Visibility": "public",
82+
"WriteAccess": false,
83+
"DefaultBranch": "main",
84+
"RepoPermissions": {
85+
"admin": false,
86+
"maintain": false,
87+
"push": false,
88+
"triage": false,
89+
"pull": true
90+
}
5591
}
5692
]

Config/SchedulerRateLimits.json

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
[
2+
{
3+
"Command": "Sync-CIPPExtensionData",
4+
"MaxRequests": 50
5+
},
6+
{
7+
"Command": "Push-CIPPExtensionData",
8+
"MaxRequests": 30
9+
}
10+
]
Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
function Get-CIPPAlertLicensedUsersWithRoles {
2+
<#
3+
.FUNCTIONALITY
4+
Entrypoint
5+
#>
6+
[CmdletBinding()]
7+
param (
8+
[Parameter(Mandatory = $false)]
9+
[Alias('input')]
10+
$InputValue,
11+
$TenantFilter
12+
)
13+
14+
# Get all users with assigned licenses
15+
$LicensedUsers = New-GraphGetRequest -uri "https://graph.microsoft.com/beta/users?`$top=999&`$select=userPrincipalName,assignedLicenses,displayName" -tenantid $TenantFilter | Where-Object { $_.assignedLicenses -and $_.assignedLicenses.Count -gt 0 }
16+
if (-not $LicensedUsers -or $LicensedUsers.Count -eq 0) {
17+
Write-Information "No licensed users found for tenant $TenantFilter"
18+
return $true
19+
}
20+
# Get all directory roles with their members
21+
$DirectoryRoles = New-GraphGetRequest -uri "https://graph.microsoft.com/beta/directoryRoles?`$expand=members" -tenantid $TenantFilter
22+
if (-not $DirectoryRoles -or $DirectoryRoles.Count -eq 0) {
23+
Write-Information "No directory roles found for tenant $TenantFilter"
24+
return
25+
}
26+
$UsersToAlertOn = $LicensedUsers | Where-Object { $_.userPrincipalName -in $DirectoryRoles.members.userPrincipalName }
27+
28+
29+
if ($UsersToAlertOn.Count -gt 0) {
30+
Write-AlertTrace -cmdletName $MyInvocation.MyCommand -tenantFilter $TenantFilter -data $UsersToAlertOn
31+
} else {
32+
Write-Information "No licensed users with roles found for tenant $TenantFilter"
33+
}
34+
35+
36+
}

Modules/CIPPCore/Public/Alerts/Get-CIPPAlertQuotaUsed.ps1

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ function Get-CIPPAlertQuotaUsed {
1717
return
1818
}
1919
$OverQuota = $AlertData | ForEach-Object {
20-
if ($_.StorageUsedInBytes -eq 0 -or $_.prohibitSendReceiveQuotaInBytes -eq 0) { return }
20+
if ([string]::IsNullOrEmpty($_.StorageUsedInBytes) -or [string]::IsNullOrEmpty($_.prohibitSendReceiveQuotaInBytes) -or $_.StorageUsedInBytes -eq 0 -or $_.prohibitSendReceiveQuotaInBytes -eq 0) { return }
2121
try {
2222
$PercentLeft = [math]::round(($_.storageUsedInBytes / $_.prohibitSendReceiveQuotaInBytes) * 100)
2323
} catch { $PercentLeft = 100 }

Modules/CIPPCore/Public/AuditLogs/Get-CippAuditLogSearches.ps1

Lines changed: 19 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -13,27 +13,31 @@ function Get-CippAuditLogSearches {
1313
[Parameter()]
1414
[switch]$ReadyToProcess
1515
)
16-
16+
$AuditLogSearchesTable = Get-CippTable -TableName 'AuditLogSearches'
1717
if ($ReadyToProcess.IsPresent) {
18-
$AuditLogSearchesTable = Get-CippTable -TableName 'AuditLogSearches'
1918
$15MinutesAgo = (Get-Date).AddMinutes(-15).ToUniversalTime().ToString('yyyy-MM-ddTHH:mm:ssZ')
2019
$1DayAgo = (Get-Date).AddDays(-1).ToUniversalTime().ToString('yyyy-MM-ddTHH:mm:ssZ')
21-
$PendingQueries = Get-CIPPAzDataTableEntity @AuditLogSearchesTable -Filter "Tenant eq '$TenantFilter' and (CippStatus eq 'Pending' or (CippStatus eq 'Processing' and Timestamp le datetime'$15MinutesAgo')) and Timestamp ge datetime'$1DayAgo'" | Sort-Object Timestamp
20+
$PendingQueries = Get-CIPPAzDataTableEntity @AuditLogSearchesTable -Filter "PartitionKey eq 'Search' and Tenant eq '$TenantFilter' and (CippStatus eq 'Pending' or (CippStatus eq 'Processing' and Timestamp le datetime'$15MinutesAgo')) and Timestamp ge datetime'$1DayAgo'" | Sort-Object Timestamp
21+
} else {
22+
$7DaysAgo = (Get-Date).AddDays(-7).ToUniversalTime().ToString('yyyy-MM-ddTHH:mm:ssZ')
23+
$PendingQueries = Get-CIPPAzDataTableEntity @AuditLogSearchesTable -Filter "Tenant eq '$TenantFilter' and Timestamp ge datetime'$7DaysAgo'"
24+
}
2225

23-
$BulkRequests = foreach ($PendingQuery in $PendingQueries) {
24-
@{
25-
id = $PendingQuery.RowKey
26-
url = 'security/auditLog/queries/' + $PendingQuery.RowKey
27-
method = 'GET'
28-
}
26+
$BulkRequests = foreach ($PendingQuery in $PendingQueries) {
27+
@{
28+
id = $PendingQuery.RowKey
29+
url = 'security/auditLog/queries/' + $PendingQuery.RowKey
30+
method = 'GET'
2931
}
30-
if ($BulkRequests.Count -eq 0) {
31-
return @()
32-
}
33-
$Queries = New-GraphBulkRequest -Requests @($BulkRequests) -AsApp $true -TenantId $TenantFilter | Select-Object -ExpandProperty body
32+
}
33+
if ($BulkRequests.Count -eq 0) {
34+
return @()
35+
}
36+
$Queries = New-GraphBulkRequest -Requests @($BulkRequests) -AsApp $true -TenantId $TenantFilter | Select-Object -ExpandProperty body
37+
38+
if ($ReadyToProcess.IsPresent) {
3439
$Queries = $Queries | Where-Object { $PendingQueries.RowKey -contains $_.id -and $_.status -eq 'succeeded' }
35-
} else {
36-
$Queries = New-GraphGetRequest -uri 'https://graph.microsoft.com/beta/security/auditLog/queries' -AsApp $true -tenantid $TenantFilter
3740
}
41+
3842
return $Queries
3943
}

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

Lines changed: 18 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -157,20 +157,26 @@ function New-CippAuditLogSearch {
157157
if ($PSCmdlet.ShouldProcess('Create a new audit log search for tenant ' + $TenantFilter)) {
158158
$Query = New-GraphPOSTRequest -uri 'https://graph.microsoft.com/beta/security/auditLog/queries' -body ($SearchParams | ConvertTo-Json -Compress) -tenantid $TenantFilter -AsApp $true
159159

160+
160161
if ($ProcessLogs.IsPresent -and $Query.id) {
161-
$Entity = [PSCustomObject]@{
162-
PartitionKey = [string]'Search'
163-
RowKey = [string]$Query.id
164-
Tenant = [string]$TenantFilter
165-
DisplayName = [string]$DisplayName
166-
StartTime = [datetime]$StartTime.ToUniversalTime()
167-
EndTime = [datetime]$EndTime.ToUniversalTime()
168-
Query = [string]($Query | ConvertTo-Json -Compress)
169-
CippStatus = [string]'Pending'
170-
}
171-
$Table = Get-CIPPTable -TableName 'AuditLogSearches'
172-
Add-CIPPAzDataTableEntity @Table -Entity $Entity -Force | Out-Null
162+
$CippStatus = 'Pending'
163+
} else {
164+
$CippStatus = 'N/A'
165+
}
166+
167+
$Entity = [PSCustomObject]@{
168+
PartitionKey = [string]'Search'
169+
RowKey = [string]$Query.id
170+
Tenant = [string]$TenantFilter
171+
DisplayName = [string]$DisplayName
172+
StartTime = [datetime]$StartTime.ToUniversalTime()
173+
EndTime = [datetime]$EndTime.ToUniversalTime()
174+
Query = [string]($Query | ConvertTo-Json -Compress)
175+
CippStatus = [string]$CippStatus
173176
}
177+
$Table = Get-CIPPTable -TableName 'AuditLogSearches'
178+
Add-CIPPAzDataTableEntity @Table -Entity $Entity -Force | Out-Null
179+
174180
return $Query
175181
}
176182
}

Modules/CIPPCore/Public/Authentication/Get-CIPPRolePermissions.ps1

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -20,11 +20,13 @@ function Get-CIPPRolePermissions {
2020
$Permissions = $Role.Permissions | ConvertFrom-Json
2121
$AllowedTenants = if ($Role.AllowedTenants) { $Role.AllowedTenants | ConvertFrom-Json } else { @() }
2222
$BlockedTenants = if ($Role.BlockedTenants) { $Role.BlockedTenants | ConvertFrom-Json } else { @() }
23+
$BlockedEndpoints = if ($Role.BlockedEndpoints) { $Role.BlockedEndpoints | ConvertFrom-Json } else { @() }
2324
[PSCustomObject]@{
24-
Role = $Role.RowKey
25-
Permissions = $Permissions.PSObject.Properties.Value
26-
AllowedTenants = @($AllowedTenants)
27-
BlockedTenants = @($BlockedTenants)
25+
Role = $Role.RowKey
26+
Permissions = $Permissions.PSObject.Properties.Value
27+
AllowedTenants = @($AllowedTenants)
28+
BlockedTenants = @($BlockedTenants)
29+
BlockedEndpoints = @($BlockedEndpoints)
2830
}
2931
} else {
3032
throw "Role $RoleName not found."

Modules/CIPPCore/Public/Authentication/Test-CIPPAccess.ps1

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -199,6 +199,7 @@ function Test-CIPPAccess {
199199
continue
200200
}
201201
}
202+
202203
if ($PermissionsFound) {
203204
if ($TenantList.IsPresent) {
204205
$LimitedTenantList = foreach ($Permission in $PermissionSet) {
@@ -248,6 +249,9 @@ function Test-CIPPAccess {
248249
foreach ($Role in $PermissionSet) {
249250
foreach ($Perm in $Role.Permissions) {
250251
if ($Perm -match $APIRole) {
252+
if ($Role.BlockedEndpoints -contains $Request.Params.CIPPEndpoint) {
253+
throw "Access to this CIPP API endpoint is not allowed, the custom role '$($Role.Role)' has blocked this endpoint: $($Request.Params.CIPPEndpoint)"
254+
}
251255
$APIAllowed = $true
252256
break
253257
}

Modules/CIPPCore/Public/CippQueue/Invoke-ListCippQueue.ps1

Lines changed: 17 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -5,20 +5,32 @@ function Invoke-ListCippQueue {
55
.ROLE
66
CIPP.Core.Read
77
#>
8-
param($Request = $null, $TriggerMetadata = $null)
8+
param($Request = $null, $TriggerMetadata = $null, $Reference = $null, $QueueId = $null)
99

1010
if ($Request) {
1111
$APIName = $Request.Params.CIPPEndpoint
1212
Write-LogMessage -headers $Request.Headers -API $APINAME -message 'Accessed this API' -Sev 'Debug'
1313
}
1414

15+
$QueueId = $Request.Query.QueueId ?? $QueueId
16+
$Reference = $Request.Query.Reference ?? $Reference
17+
1518
$CippQueue = Get-CippTable -TableName 'CippQueue'
1619
$CippQueueTasks = Get-CippTable -TableName 'CippQueueTasks'
1720
$3HoursAgo = (Get-Date).ToUniversalTime().AddHours(-3).ToString('yyyy-MM-ddTHH:mm:ssZ')
18-
$CippQueueData = Get-CIPPAzDataTableEntity @CippQueue -Filter "PartitionKey eq 'CippQueue' and Timestamp ge datetime'$3HoursAgo'" | Sort-Object -Property Timestamp -Descending
21+
22+
if ($QueueId) {
23+
$Filter = "PartitionKey eq 'CippQueue' and RowKey eq '$QueueId'"
24+
} elseif ($Reference) {
25+
$Filter = "PartitionKey eq 'CippQueue' and Reference eq '$Reference' and Timestamp ge datetime'$3HoursAgo'"
26+
} else {
27+
$Filter = "PartitionKey eq 'CippQueue' and Timestamp ge datetime'$3HoursAgo'"
28+
}
29+
30+
$CippQueueData = Get-CIPPAzDataTableEntity @CippQueue -Filter $Filter | Sort-Object -Property Timestamp -Descending
1931

2032
$QueueData = foreach ($Queue in $CippQueueData) {
21-
$Tasks = Get-CIPPAzDataTableEntity @CippQueueTasks -Filter "PartitionKey eq 'Task' and QueueId eq '$($Queue.RowKey)'" | Where-Object { $_.Name } | Select-Object @{n = 'Timestamp'; exp = { $_.Timestamp.DateTime.ToUniversalTime() } }, Name, Status
33+
$Tasks = Get-CIPPAzDataTableEntity @CippQueueTasks -Filter "PartitionKey eq 'Task' and QueueId eq '$($Queue.RowKey)'" | Where-Object { $_.Name } | Select-Object @{n = 'Timestamp'; exp = { $_.Timestamp } }, Name, Status
2234
$TaskStatus = @{}
2335
$Tasks | Group-Object -Property Status | ForEach-Object {
2436
$TaskStatus.$($_.Name) = $_.Count
@@ -54,9 +66,9 @@ function Invoke-ListCippQueue {
5466
PercentComplete = [math]::Round(((($TotalCompleted + $TotalFailed) / $Queue.TotalTasks) * 100), 1)
5567
PercentFailed = [math]::Round((($TotalFailed / $Queue.TotalTasks) * 100), 1)
5668
PercentRunning = [math]::Round((($TotalRunning / $Queue.TotalTasks) * 100), 1)
57-
Tasks = @($Tasks)
69+
Tasks = @($Tasks | Sort-Object -Descending Timestamp)
5870
Status = $Queue.Status
59-
Timestamp = $Queue.Timestamp.DateTime.ToUniversalTime()
71+
Timestamp = $Queue.Timestamp
6072
}
6173

6274
}

0 commit comments

Comments
 (0)