Skip to content

Commit

Permalink
Merge branch 'KelvinTegelaar:master' into master
Browse files Browse the repository at this point in the history
  • Loading branch information
MattDunn12 authored Jun 25, 2024
2 parents 8ad49f6 + 22c6031 commit fca9132
Show file tree
Hide file tree
Showing 115 changed files with 1,753 additions and 993 deletions.
39 changes: 39 additions & 0 deletions .github/workflows/dev_cippacnqv.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
# Docs for the Azure Web Apps Deploy action: https://github.com/azure/functions-action
# More GitHub Actions for Azure: https://github.com/Azure/actions

name: Build and deploy Powershell project to Azure Function App - cippacnqv

on:
push:
branches:
- dev
workflow_dispatch:

env:
AZURE_FUNCTIONAPP_PACKAGE_PATH: '.' # set this to the path to your web app project, defaults to the repository root

jobs:
deploy:
runs-on: windows-latest
permissions:
id-token: write #This is required for requesting the JWT

steps:
- name: 'Checkout GitHub Action'
uses: actions/checkout@v4

- name: Login to Azure
uses: azure/login@v1
with:
client-id: ${{ secrets.AZUREAPPSERVICE_CLIENTID_6085081ED1124B799258E9FF743FF4B9 }}
tenant-id: ${{ secrets.AZUREAPPSERVICE_TENANTID_9BDB2DDBFAFA4BC19C20A58B204BFAF3 }}
subscription-id: ${{ secrets.AZUREAPPSERVICE_SUBSCRIPTIONID_02B5224812794971B05EDD557AF2B867 }}

- name: 'Run Azure Functions Action'
uses: Azure/functions-action@v1
id: fa
with:
app-name: 'cippacnqv'
slot-name: 'Production'
package: ${{ env.AZURE_FUNCTIONAPP_PACKAGE_PATH }}

4 changes: 3 additions & 1 deletion Cache_SAMSetup/SAMManifest.json
Original file line number Diff line number Diff line change
Expand Up @@ -159,7 +159,9 @@
{ "id": "cb8f45a0-5c2e-4ea1-b803-84b870a7d7ec", "type": "Scope" },
{ "id": "4c06a06a-098a-4063-868e-5dfee3827264", "type": "Scope" },
{ "id": "1bfefb4e-e0b5-418b-a88f-73c46d2cc8e9", "type": "Role" },
{ "id": "e67e6727-c080-415e-b521-e3f35d5248e9", "type": "Scope" }
{ "id": "e67e6727-c080-415e-b521-e3f35d5248e9", "type": "Scope" },
{ "id": "b6890674-9dd5-4e42-bb15-5af07f541ae1", "type": "Role" }

]
},
{
Expand Down
12 changes: 10 additions & 2 deletions Modules/CIPPCore/Public/Alerts/Get-CIPPAlertQuotaUsed.ps1
Original file line number Diff line number Diff line change
Expand Up @@ -17,9 +17,17 @@ function Get-CIPPAlertQuotaUsed {
return
}
$AlertData | ForEach-Object {
if ($_.StorageUsedInBytes -eq 0) { return }
if ($_.StorageUsedInBytes -eq 0 -or $_.prohibitSendReceiveQuotaInBytes -eq 0) { return }
$PercentLeft = [math]::round(($_.storageUsedInBytes / $_.prohibitSendReceiveQuotaInBytes) * 100)
if ($InputValue) { $Value = [int]$InputValue } else { $Value = 90 }
try {
if ([int]$InputValue -gt 0) {
$Value = [int]$InputValue
} else {
$Value = 90
}
} catch {
$Value = 90
}
if ($PercentLeft -gt $Value) {
"$($_.userPrincipalName): Mailbox is more than $($value)% full. Mailbox is $PercentLeft% full"
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,15 +12,19 @@ function Get-CIPPAlertSharepointQuota {
$TenantFilter
)
Try {
$tenantName = (New-GraphGetRequest -uri 'https://graph.microsoft.com/beta/domains' -tenantid $TenantFilter | Where-Object { $_.isInitial -eq $true }).id.Split('.')[0]
$tenantName = (New-GraphGetRequest -uri 'https://graph.microsoft.com/beta/sites/root' -tenantid $TenantFilter).id.Split('.')[0]
$sharepointToken = (Get-GraphToken -scope "https://$($tenantName)-admin.sharepoint.com/.default" -tenantid $TenantFilter)
$sharepointToken.Add('accept', 'application/json')
$sharepointQuota = (Invoke-RestMethod -Method 'GET' -Headers $sharepointToken -Uri "https://$($tenantName)-admin.sharepoint.com/_api/StorageQuotas()?api-version=1.3.2" -ErrorAction Stop).value
} catch {
return
}
if ($sharepointQuota) {
if ($InputValue -Is [Boolean]) { $Value = 90 } else { $Value = $InputValue }
try {
if ([int]$InputValue -gt 0) { $Value = [int]$InputValue } else { $Value = 90 }
} catch {
$Value = 90
}
$UsedStoragePercentage = [int](($sharepointQuota.GeoUsedStorageMB / $sharepointQuota.TenantStorageMB) * 100)
if ($UsedStoragePercentage -gt $Value) {
$AlertData = "SharePoint Storage is at $($UsedStoragePercentage)%. Your alert threshold is $($Value)%"
Expand Down
1 change: 1 addition & 0 deletions Modules/CIPPCore/Public/CippQueue/Invoke-ListCippQueue.ps1
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@ function Invoke-ListCippQueue {
$TotalCompleted = $TaskStatus.Completed ?? 0
$TotalFailed = $TaskStatus.Failed ?? 0
$TotalRunning = $TaskStatus.Running ?? 0
if ($Queue.TotalTasks -eq 0) { $Queue.TotalTasks = 1 }

[PSCustomObject]@{
PartitionKey = $Queue.PartitionKey
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ function Push-DomainAnalyserDomain {
}
Set-DnsResolver -Resolver $Resolver

$Domain = $DomainObject.rowKey
$Domain = $DomainObject.RowKey

try {
$Tenant = $DomainObject.TenantDetails | ConvertFrom-Json -ErrorAction Stop
Expand Down Expand Up @@ -250,7 +250,7 @@ function Push-DomainAnalyserDomain {
# Final Write to Output
Write-LogMessage -API 'DomainAnalyser' -tenant $DomainObject.TenantId -message "DNS Analyser Finished For $Domain" -sev Info
} catch {
Write-LogMessage -API -API 'DomainAnalyser' -tenant $DomainObject.TenantId -message "Error saving domain $Domain to table " -sev Error -LogData (Get-CippException -Exception $_)
Write-LogMessage -API 'DomainAnalyser' -tenant $DomainObject.TenantId -message "Error saving domain $Domain to table " -sev Error -LogData (Get-CippException -Exception $_)
}
return $null
}
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ function Push-DomainAnalyserTenant {
return
} else {
try {
$Domains = New-GraphGetRequest -uri 'https://graph.microsoft.com/v1.0/domains' -tenantid $Tenant.customerId | Where-Object { ($_.id -notlike '*.microsoftonline.com' -and $_.id -NotLike '*.exclaimer.cloud' -and $_.id -Notlike '*.excl.cloud' -and $_.id -NotLike '*.codetwo.online' -and $_.id -NotLike '*.call2teams.com' -and $_.isVerified) }
$Domains = New-GraphGetRequest -uri 'https://graph.microsoft.com/beta/domains' -tenantid $Tenant.customerId | Where-Object { ($_.id -notlike '*.microsoftonline.com' -and $_.id -NotLike '*.exclaimer.cloud' -and $_.id -Notlike '*.excl.cloud' -and $_.id -NotLike '*.codetwo.online' -and $_.id -NotLike '*.call2teams.com' -and $_.isVerified) }

$TenantDomains = foreach ($d in $Domains) {
[PSCustomObject]@{
Expand All @@ -38,9 +38,11 @@ function Push-DomainAnalyserTenant {
}
}

Write-Information ($TenantDomains | ConvertTo-Json -Depth 10)

$DomainCount = ($TenantDomains | Measure-Object).Count
if ($DomainCount -gt 0) {
Write-Host "$DomainCount tenant Domains"
Write-Host "############# $DomainCount tenant Domains"
$TenantDomainObjects = [System.Collections.Generic.List[object]]::new()
try {
foreach ($TenantDomain in $TenantDomains) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -62,12 +62,12 @@ function Push-ExecScheduledCommand {
$TableDesign = '<style>table.blueTable{border:1px solid #1C6EA4;background-color:#EEE;width:100%;text-align:left;border-collapse:collapse}table.blueTable td,table.blueTable th{border:1px solid #AAA;padding:3px 2px}table.blueTable tbody td{font-size:13px}table.blueTable tr:nth-child(even){background:#D0E4F5}table.blueTable thead{background:#1C6EA4;background:-moz-linear-gradient(top,#5592bb 0,#327cad 66%,#1C6EA4 100%);background:-webkit-linear-gradient(top,#5592bb 0,#327cad 66%,#1C6EA4 100%);background:linear-gradient(to bottom,#5592bb 0,#327cad 66%,#1C6EA4 100%);border-bottom:2px solid #444}table.blueTable thead th{font-size:15px;font-weight:700;color:#FFF;border-left:2px solid #D0E4F5}table.blueTable thead th:first-child{border-left:none}table.blueTable tfoot{font-size:14px;font-weight:700;color:#FFF;background:#D0E4F5;background:-moz-linear-gradient(top,#dcebf7 0,#d4e6f6 66%,#D0E4F5 100%);background:-webkit-linear-gradient(top,#dcebf7 0,#d4e6f6 66%,#D0E4F5 100%);background:linear-gradient(to bottom,#dcebf7 0,#d4e6f6 66%,#D0E4F5 100%);border-top:2px solid #444}table.blueTable tfoot td{font-size:14px}table.blueTable tfoot .links{text-align:right}table.blueTable tfoot .links a{display:inline-block;background:#1C6EA4;color:#FFF;padding:2px 8px;border-radius:5px}</style>'
$FinalResults = if ($results -is [array] -and $results[0] -is [string]) { $Results | ConvertTo-Html -Fragment -Property @{ l = 'Text'; e = { $_ } } } else { $Results | ConvertTo-Html -Fragment }
$HTML = $FinalResults -replace '<table>', "This alert is for tenant $tenant. <br /><br /> $TableDesign<table class=blueTable>" | Out-String
$title = "$TaskType - $($task.Name) - $tenant"
$title = "$TaskType - $tenant - $($task.Name)"
Write-Host 'Scheduler: Sending the results to the target.'
Write-Host "The content of results is: $Results"
switch -wildcard ($task.PostExecution) {
'*psa*' { Send-CIPPAlert -Type 'psa' -Title $title -HTMLContent $HTML }
'*email*' { Send-CIPPAlert -Type 'email' -Title $title -HTMLContent $HTML }
'*psa*' { Send-CIPPAlert -Type 'psa' -Title $title -HTMLContent $HTML -TenantFilter $tenant }
'*email*' { Send-CIPPAlert -Type 'email' -Title $title -HTMLContent $HTML -TenantFilter $tenant }
'*webhook*' {
$Webhook = [PSCustomObject]@{
'Tenant' = $tenant
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
function Push-AuditLogBundleProcessing {
Param($Item)

try {
$AuditBundleTable = Get-CippTable -tablename 'AuditLogBundles'
$AuditLogBundle = Get-CIPPAzDataTableEntity @AuditBundleTable -Filter "PartitionKey eq '$($Item.TenantFilter)' and RowKey eq '$($Item.ContentId)'"
if ($AuditLogBundle.ProcessingStatus -ne 'Pending') {
Write-Information 'Audit log bundle already processed'
return
}
try {
$AuditLogTest = Test-CIPPAuditLogRules -TenantFilter $Item.TenantFilter -LogType $AuditLogBundle.ContentType -ContentUri $AuditLogBundle.ContentUri
$AuditLogBundle.ProcessingStatus = 'Completed'
$AuditLogBundle.MatchedRules = [string](ConvertTo-Json -Compress -Depth 10 -InputObject $AuditLogTest.MatchedRules)
$AuditLogBundle.MatchedLogs = $AuditLogTest.MatchedLogs
} catch {
$AuditLogBundle.ProcessingStatus = 'Failed'
$AuditLogBundle | Add-Member -NotePropertyName Error -NotePropertyValue $_.InvocationInfo.PositionMessage -TypeName string
}
try {
Add-CIPPAzDataTableEntity @AuditBundleTable -Entity $AuditLogBundle -Force
} catch {
Write-Host ( 'Error logging audit bundle: {0} line {1} - {2}' -f $_.InvocationInfo.ScriptName, $_.InvocationInfo.ScriptLineNumber, $_.Exception.Message)
}

$DataToProcess = ($AuditLogTest).DataToProcess
Write-Information "Webhook: Data to process found: $($DataToProcess.count) items"
foreach ($AuditLog in $DataToProcess) {
Write-Information "Processing $($AuditLog.operation)"
$Webhook = @{
Data = $AuditLog
CIPPURL = [string]$AuditLogBundle.CIPPURL
TenantFilter = $Item.TenantFilter
}
Invoke-CippWebhookProcessing @Webhook
}
} catch {
Write-Host ( 'Audit log error {0} line {1} - {2}' -f $_.InvocationInfo.ScriptName, $_.InvocationInfo.ScriptLineNumber, $_.Exception.Message)
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
function Push-AuditLogTenant {
Param($Item)

$AuditBundleTable = Get-CippTable -tablename 'AuditLogBundles'
$SchedulerConfig = Get-CIPPTable -TableName 'SchedulerConfig'
$CIPPURL = Get-CIPPAzDataTableEntity @SchedulerConfig -Filter "PartitionKey eq 'webhookcreation'" | Select-Object -First 1 -ExpandProperty CIPPURL
$WebhookTable = Get-CippTable -tablename 'webhookTable'
$Webhooks = Get-CIPPAzDataTableEntity @WebhookTable -Filter "PartitionKey eq '$($Item.TenantFilter)' and Version eq '3'" | Where-Object { $_.Resource -match '^Audit' }
$ExistingBundles = Get-CIPPAzDataTableEntity @AuditBundleTable -Filter "PartitionKey eq '$($Item.TenantFilter)' and ContentType eq '$ContentType'"

$NewBundles = [System.Collections.Generic.List[object]]::new()
foreach ($Webhook in $Webhooks) {
$TenantFilter = $Webhook.PartitionKey
$LogType = $Webhook.Resource
Write-Information "Querying for $LogType on $TenantFilter"
$ContentBundleQuery = @{
TenantFilter = $TenantFilter
ContentType = $LogType
StartTime = $Item.StartTime
EndTime = $Item.EndTime
}
$LogBundles = Get-CIPPAuditLogContentBundles @ContentBundleQuery

foreach ($Bundle in $LogBundles) {
if ($ExistingBundles.RowKey -notcontains $Bundle.contentId) {
$NewBundles.Add([PSCustomObject]@{
PartitionKey = $TenantFilter
RowKey = $Bundle.contentId
DefaultDomainName = $TenantFilter
ContentType = $Bundle.contentType
ContentUri = $Bundle.contentUri
ContentCreated = $Bundle.contentCreated
ContentExpiration = $Bundle.contentExpiration
CIPPURL = [string]$CIPPURL
ProcessingStatus = 'Pending'
MatchedRules = ''
MatchedLogs = 0
})
}
}
}

if (($NewBundles | Measure-Object).Count -gt 0) {
Add-CIPPAzDataTableEntity @AuditBundleTable -Entity $NewBundles
Write-Information ($NewBundles | ConvertTo-Json -Depth 5 -Compress)

$Batch = $NewBundles | Select-Object @{Name = 'ContentId'; Expression = { $_.RowKey } }, @{Name = 'TenantFilter'; Expression = { $_.PartitionKey } }, @{Name = 'FunctionName'; Expression = { 'AuditLogBundleProcessing' } }
$InputObject = [PSCustomObject]@{
OrchestratorName = 'AuditLogs'
Batch = @($Batch)
SkipLog = $true
}
$InstanceId = Start-NewOrchestration -FunctionName 'CIPPOrchestrator' -InputObject ($InputObject | ConvertTo-Json -Depth 5 -Compress)
Write-Host "Started orchestration with ID = '$InstanceId'"
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ function Push-Schedulerwebhookcreation {
foreach ($Tenant in $Tenants) {
Write-Host "Working on $Tenant - $($Row.tenantid)"
#use the queueitem to see if we already have a webhook for this tenant + webhooktype. If we do, delete this row from SchedulerConfig.
$Webhook = Get-CIPPAzDataTableEntity @WebhookTable -Filter "PartitionKey eq '$Tenant' and Version eq '2' and Resource eq '$($Row.webhookType)'"
$Webhook = Get-CIPPAzDataTableEntity @WebhookTable -Filter "PartitionKey eq '$Tenant' and Version eq '3' and Resource eq '$($Row.webhookType)'"
if ($Webhook) {
Write-Host "Found existing webhook for $Tenant - $($Row.webhookType)"
if ($Row.tenantid -ne 'AllTenants') {
Expand All @@ -32,17 +32,14 @@ function Push-Schedulerwebhookcreation {
} else {
Write-Host "No existing webhook for $Tenant - $($Row.webhookType) - Time to create."
try {
$NewSub = New-CIPPGraphSubscription -TenantFilter $Tenant -EventType $Row.webhookType -BaseURL $Row.CIPPURL -auditLogAPI $true
$NewSub = New-CIPPGraphSubscription -TenantFilter $Tenant -EventType $Row.webhookType -auditLogAPI $true
if ($NewSub.Success -and $Row.tenantid -ne 'AllTenants') {
Remove-AzDataTableEntity @Table -Entity $Row
} else {
Write-Host "Failed to create webhook for $Tenant - $($Row.webhookType) - $($_.Exception.Message)"
Write-LogMessage -message "Failed to create webhook for $Tenant - $($Row.webhookType)" -Sev 'Error' -LogData $_.Exception
}
} catch {
Write-Host "Failed to create webhook for $Tenant - $($Row.webhookType): $($_.Exception.Message)"
Write-LogMessage -message "Failed to create webhook for $Tenant - $($Row.webhookType)" -Sev 'Error' -LogData $_.Exception

}

}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ function Invoke-ExecCustomRole {
Write-LogMessage -user $Request.Headers.'x-ms-client-principal' -API 'ExecCustomRole' -message "Saved custom role $($Request.Body.RoleName)" -Sev 'Info'
$Role = @{
'PartitionKey' = 'CustomRoles'
'RowKey' = "$($Request.Body.RoleName)"
'RowKey' = "$($Request.Body.RoleName.ToLower())"
'Permissions' = "$($Request.Body.Permissions | ConvertTo-Json -Compress)"
'AllowedTenants' = "$($Request.Body.AllowedTenants | ConvertTo-Json -Compress)"
'BlockedTenants' = "$($Request.Body.BlockedTenants | ConvertTo-Json -Compress)"
Expand Down
Loading

0 comments on commit fca9132

Please sign in to comment.