Skip to content

Commit 1ece479

Browse files
authored
Merge pull request #111 from KelvinTegelaar/master
[pull] master from KelvinTegelaar:master
2 parents be3e05b + 567c049 commit 1ece479

File tree

128 files changed

+2904
-594
lines changed

Some content is hidden

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

128 files changed

+2904
-594
lines changed

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
}

Modules/CIPPCore/Public/Entrypoints/Activity Triggers/BEC/Push-BECRun.ps1

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -50,7 +50,7 @@ function Push-BECRun {
5050
$ExtractResult = 'Successfully extracted logs from auditlog'
5151
}
5252
Write-Information 'Getting last sign-in'
53-
Try {
53+
try {
5454
$URI = "https://graph.microsoft.com/beta/auditLogs/signIns?`$filter=(userId eq '$SuspectUser')&`$top=1&`$orderby=createdDateTime desc"
5555
$LastSignIn = New-GraphGetRequest -uri $URI -tenantid $TenantFilter -noPagination $true -verbose | Select-Object @{ Name = 'CreatedDateTime'; Expression = { $(($_.createdDateTime | Out-String) -replace '\r\n') } },
5656
id,
@@ -69,7 +69,7 @@ function Push-BECRun {
6969
#List all users devices
7070
$Bytes = [System.Text.Encoding]::UTF8.GetBytes($SuspectUser)
7171
$base64IdentityParam = [Convert]::ToBase64String($Bytes)
72-
Try {
72+
try {
7373
$Devices = New-GraphGetRequest -uri "https://outlook.office365.com:443/adminapi/beta/$($TenantFilter)/mailbox('$($base64IdentityParam)')/MobileDevice/Exchange.GetMobileDeviceStatistics()/?IsEncoded=True" -Tenantid $TenantFilter -scope ExchangeOnline
7474
} catch {
7575
$Devices = $null
@@ -143,10 +143,10 @@ function Push-BECRun {
143143
Write-Information 'Getting bulk requests'
144144
$GraphResults = New-GraphBulkRequest -Requests $Requests -tenantid $TenantFilter -asapp $true
145145

146-
$PasswordChanges = ($GraphResults | Where-Object { $_.id -eq 'Users' }).body.value | Where-Object { $_.lastPasswordChangeDateTime -ge $startDate }
147-
$NewUsers = ($GraphResults | Where-Object { $_.id -eq 'Users' }).body.value | Where-Object { $_.createdDateTime -ge $startDate }
148-
$MFADevices = ($GraphResults | Where-Object { $_.id -eq 'MFADevices' }).body.value
149-
$NewSPs = ($GraphResults | Where-Object { $_.id -eq 'NewSPs' }).body.value
146+
$PasswordChanges = ($GraphResults | Where-Object { $_.id -eq 'Users' }).body.value | Where-Object { $_.lastPasswordChangeDateTime -ge $startDate } ?? @()
147+
$NewUsers = ($GraphResults | Where-Object { $_.id -eq 'Users' }).body.value | Where-Object { $_.createdDateTime -ge $startDate } ?? @()
148+
$MFADevices = ($GraphResults | Where-Object { $_.id -eq 'MFADevices' }).body.value ?? @()
149+
$NewSPs = ($GraphResults | Where-Object { $_.id -eq 'NewSPs' }).body.value ?? @()
150150

151151

152152
$Results = [PSCustomObject]@{

0 commit comments

Comments
 (0)