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
smood922 authored Jul 11, 2024
2 parents ae73a0f + c82a76a commit b20b707
Show file tree
Hide file tree
Showing 25 changed files with 330 additions and 236 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,8 @@ function Get-CIPPAlertDepTokenExpiry {
$DepTokens = (New-GraphGetRequest -uri 'https://graph.microsoft.com/beta/deviceManagement/depOnboardingSettings' -tenantid $TenantFilter).value
$AlertData = foreach ($Dep in $DepTokens) {
if ($Dep.tokenExpirationDateTime -lt (Get-Date).AddDays(30) -and $Dep.tokenExpirationDateTime -gt (Get-Date).AddDays(-7)) {
'Apple Device Enrollment Program token expiring on {0}' -f $Dep.tokenExpirationDateTime
$Message = 'Apple Device Enrollment Program token expiring on {0}' -f $Dep.tokenExpirationDateTime
$Dep | Select-Object -Property tokenName, @{Name = 'Message'; Expression = { $Message } }
}
}
Write-AlertTrace -cmdletName $MyInvocation.MyCommand -tenantFilter $TenantFilter -data $AlertData
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,10 +15,12 @@ function Get-CIPPAlertVppTokenExpiry {
$VppTokens = (New-GraphGetRequest -uri 'https://graph.microsoft.com/beta/deviceAppManagement/vppTokens' -tenantid $TenantFilter).value
$AlertData = foreach ($Vpp in $VppTokens) {
if ($Vpp.state -ne 'valid') {
'Apple Volume Purchase Program Token is not valid, new token required'
$Message = 'Apple Volume Purchase Program Token is not valid, new token required'
$Vpp | Select-Object -Property organizationName, appleId, vppTokenAccountType, @{Name = 'Message'; Expression = { $Message } }
}
if ($Vpp.expirationDateTime -lt (Get-Date).AddDays(30) -and $Vpp.expirationDateTime -gt (Get-Date).AddDays(-7)) {
'Apple Volume Purchase Program token expiring on {0}' -f $Vpp.expirationDateTime
$Message = 'Apple Volume Purchase Program token expiring on {0}' -f $Vpp.expirationDateTime
$Vpp | Select-Object -Property organizationName, appleId, vppTokenAccountType, @{Name = 'Message'; Expression = { $Message } }
}
}
Write-AlertTrace -cmdletName $MyInvocation.MyCommand -tenantFilter $TenantFilter -data $AlertData
Expand All @@ -28,4 +30,4 @@ function Get-CIPPAlertVppTokenExpiry {
} catch {
# Error handling
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,6 @@ function Push-GetTenantDomains {
Param($Item)
$DomainTable = Get-CippTable -tablename 'Domains'
$Filter = "PartitionKey eq 'TenantDomains' and TenantGUID eq '{0}'" -f $Item.TenantGUID
$Domains = Get-CIPPAzDataTableEntity @DomainTable -Filter $Filter -Property RowKey | Select-Object RowKey, @{n = 'FunctionName'; exp = { 'DomainAnalyserDomain' } }
$Domains = Get-CIPPAzDataTableEntity @DomainTable -Filter $Filter -Property PartitionKey, RowKey | Select-Object RowKey, @{n = 'FunctionName'; exp = { 'DomainAnalyserDomain' } }
return @($Domains)
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,9 @@ function Push-GetPendingWebhooks {
#>
Param($Item)
$Table = Get-CIPPTable -TableName WebhookIncoming
$Webhooks = Get-CIPPAzDataTableEntity @Table -Property RowKey, FunctionName -First 10000
$Webhooks = Get-CIPPAzDataTableEntity @Table -Property PartitionKey, RowKey, FunctionName -First 10000
$WebhookCount = ($Webhooks | Measure-Object).Count
$Message = 'Processing {0} webhooks' -f $WebhookCount
Write-LogMessage -API 'Webhooks' -message $Message -sev Info
return $Webhooks
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@ function Invoke-ExecDurableFunctions {
if ($Request.Query.PartitionKey) {
$HistoryTable = Get-CippTable -TableName ('{0}History' -f $FunctionName)
$Filter = "PartitionKey eq '{0}'" -f $Request.Query.PartitionKey
$History = Get-CippAzDataTableEntity @HistoryTable -Filter $Filter -Property RowKey, Timestamp, EventType, Name, IsPlayed, OrchestrationStatus | Select-Object * -ExcludeProperty ETag
$History = Get-CippAzDataTableEntity @HistoryTable -Filter $Filter -Property PartitionKey, RowKey, Timestamp, EventType, Name, IsPlayed, OrchestrationStatus | Select-Object * -ExcludeProperty ETag

$Body = [PSCustomObject]@{
Results = @($History)
Expand Down Expand Up @@ -173,4 +173,4 @@ function Invoke-ExecDurableFunctions {
StatusCode = [HttpStatusCode]::OK
Body = $Body
})
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -49,8 +49,11 @@ Function Invoke-ExecExtensionTest {
'Hudu' {
Connect-HuduAPI -configuration $Configuration.Hudu
$Version = Get-HuduAppInfo
Write-Host ($Version | ConvertTo-Json)
$Results = [pscustomobject]@{'Results' = ('Successfully Connected to Hudu, version: {0}' -f $Version.version) }
if ($Version.version) {
$Results = [pscustomobject]@{'Results' = ('Successfully Connected to Hudu, version: {0}' -f $Version.version) }
} else {
$Results = [pscustomobject]@{'Results' = 'Failed to connect to Hudu' }
}
}
}
} catch {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,11 @@ Function Invoke-ExecExtensionsConfig {
$null = Set-AzKeyVaultSecret -VaultName $ENV:WEBSITE_DEPLOYMENT_ID -Name $APIKey -SecretValue (ConvertTo-SecureString -AsPlainText -Force -String $Request.Body.$APIKey.APIKey)
}
}
$Request.Body.$APIKey.APIKey = 'SentToKeyVault'
if ($Request.Body.$APIKey.PSObject.Properties -notcontains 'APIKey') {
$Request.Body.$APIKey | Add-Member -MemberType NoteProperty -Name APIKey -Value 'SentToKeyVault'
} else {
$Request.Body.$APIKey.APIKey = 'SentToKeyVault'
}
}
$Request.Body.$APIKey = $Request.Body.$APIKey | Select-Object * -ExcludeProperty ResetPassword
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
using namespace System.Net

Function Invoke-ListExtensionSync {
<#
.FUNCTIONALITY
Entrypoint
.ROLE
CIPP.Extension.Read
#>
[CmdletBinding()]
param($Request, $TriggerMetadata)

$APIName = $TriggerMetadata.FunctionName
Write-LogMessage -user $request.headers.'x-ms-client-principal' -API $APINAME -message 'Accessed this API' -Sev 'Debug'

# Write to the Azure Functions log stream.
Write-Host 'PowerShell HTTP trigger function processed a request.'
$ScheduledTasksTable = Get-CIPPTable -TableName 'ScheduledTasks'
$ScheduledTasks = Get-CIPPAzDataTableEntity @ScheduledTasksTable -Filter 'Hidden eq true' | Where-Object { $_.Command -match 'CippExtension' }

$AllowedTenants = Test-CIPPAccess -Request $Request -TenantList
$TenantList = Get-Tenants -IncludeErrors
$AllTasksArrayList = [system.collections.generic.list[object]]::new()

foreach ($Task in $ScheduledTasks) {
if ($Task.Results -and (Test-Json -Json $Task.Results -ErrorAction SilentlyContinue)) {
$Results = $Task.Results | ConvertFrom-Json
} else {
$Results = $Task.Results
}

$TaskEntry = [PSCustomObject]@{
RowKey = $Task.RowKey
PartitionKey = $Task.PartitionKey
Tenant = $Task.Tenant
Name = $Task.Name
SyncType = $Task.SyncType
ScheduledTime = $Task.ScheduledTime
ExecutedTime = $Task.ExecutedTime
RepeatsEvery = $Task.Recurrence
Results = $Results
}

if ($AllowedTenants -notcontains 'AllTenants') {
$Tenant = $TenantList | Where-Object -Property defaultDomainName -EQ $Task.Tenant
if ($AllowedTenants -contains $Tenant.customerId) {
$AllTasksArrayList.Add($TaskEntry)
}
} else {
$AllTasksArrayList.Add($TaskEntry)
}
}
Write-Host ($AllTasksArrayList | ConvertTo-Json -Depth 5 -Compress)
# Associate values to output bindings by calling 'Push-OutputBinding'.
Push-OutputBinding -Name Response -Value ([HttpResponseContext]@{
StatusCode = [HttpStatusCode]::OK
Body = ConvertTo-Json -Depth 5 -InputObject $($AllTasksArrayList)
})
}
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,6 @@ Function Invoke-AddGroupTemplate {
#>
[CmdletBinding()]
param($Request, $TriggerMetadata)

$APIName = $TriggerMetadata.FunctionName
Write-LogMessage -user $request.headers.'x-ms-client-principal' -API $APINAME -message 'Accessed this API' -Sev 'Debug'

Expand All @@ -36,8 +35,7 @@ Function Invoke-AddGroupTemplate {
Write-LogMessage -user $request.headers.'x-ms-client-principal' -API $APINAME -message "Created Group template named $($Request.body.displayname) with GUID $GUID" -Sev 'Debug'

$body = [pscustomobject]@{'Results' = 'Successfully added template' }
}
catch {
} catch {
Write-LogMessage -user $request.headers.'x-ms-client-principal' -API $APINAME -message "Group Template Creation failed: $($_.Exception.Message)" -Sev 'Error'
$body = [pscustomobject]@{'Results' = "Group Template Creation failed: $($_.Exception.Message)" }
}
Expand Down
54 changes: 31 additions & 23 deletions Modules/CIPPCore/Public/Get-CIPPAzDatatableEntity.ps1
Original file line number Diff line number Diff line change
Expand Up @@ -17,47 +17,55 @@ function Get-CIPPAzDataTableEntity {
foreach ($entity in $Results) {
if ($entity.OriginalEntityId) {
$entityId = $entity.OriginalEntityId
if (-not $mergedResults.ContainsKey($entityId)) {
$mergedResults[$entityId] = @{
$partitionKey = $entity.PartitionKey
if (-not $mergedResults.ContainsKey($partitionKey)) {
$mergedResults[$partitionKey] = @{}
}
if (-not $mergedResults[$partitionKey].ContainsKey($entityId)) {
$mergedResults[$partitionKey][$entityId] = @{
Parts = New-Object 'System.Collections.ArrayList'
}
}
$mergedResults[$entityId]['Parts'].Add($entity) > $null
$mergedResults[$partitionKey][$entityId]['Parts'].Add($entity) > $null
} else {
$mergedResults[$entity.RowKey] = @{
$partitionKey = $entity.PartitionKey
if (-not $mergedResults.ContainsKey($partitionKey)) {
$mergedResults[$partitionKey] = @{}
}
$mergedResults[$partitionKey][$entity.RowKey] = @{
Entity = $entity
Parts = New-Object 'System.Collections.ArrayList'
}
}
}

# Second pass: Reassemble entities from parts
$finalResults = @()
foreach ($entityId in $mergedResults.Keys) {
$entityData = $mergedResults[$entityId]
if ($entityData.Parts.Count -gt 0) {
$fullEntity = [PSCustomObject]@{}
$parts = $entityData.Parts | Sort-Object PartIndex
foreach ($part in $parts) {
foreach ($key in $part.PSObject.Properties.Name) {
if ($key -notin @('OriginalEntityId', 'PartIndex', 'PartitionKey', 'RowKey', 'Timestamp')) {
if ($fullEntity.PSObject.Properties[$key]) {
$fullEntity | Add-Member -MemberType NoteProperty -Name $key -Value ($fullEntity.$key + $part.$key) -Force
} else {
$fullEntity | Add-Member -MemberType NoteProperty -Name $key -Value $part.$key
foreach ($partitionKey in $mergedResults.Keys) {
foreach ($entityId in $mergedResults[$partitionKey].Keys) {
$entityData = $mergedResults[$partitionKey][$entityId]
if ($entityData.Parts.Count -gt 0) {
$fullEntity = [PSCustomObject]@{}
$parts = $entityData.Parts | Sort-Object PartIndex
foreach ($part in $parts) {
foreach ($key in $part.PSObject.Properties.Name) {
if ($key -notin @('OriginalEntityId', 'PartIndex', 'PartitionKey', 'RowKey', 'Timestamp')) {
if ($fullEntity.PSObject.Properties[$key]) {
$fullEntity | Add-Member -MemberType NoteProperty -Name $key -Value ($fullEntity.$key + $part.$key) -Force
} else {
$fullEntity | Add-Member -MemberType NoteProperty -Name $key -Value $part.$key
}
}
}
}
$fullEntity | Add-Member -MemberType NoteProperty -Name 'PartitionKey' -Value $parts[0].PartitionKey -Force
$fullEntity | Add-Member -MemberType NoteProperty -Name 'RowKey' -Value $entityId -Force
$finalResults = $finalResults + @($fullEntity)
} else {
$finalResults = $finalResults + @($entityData.Entity)
}
$fullEntity | Add-Member -MemberType NoteProperty -Name 'PartitionKey' -Value $parts[0].PartitionKey -Force
$fullEntity | Add-Member -MemberType NoteProperty -Name 'RowKey' -Value $entityId -Force
$finalResults = $finalResults + @($fullEntity)
} else {
$finalResults = $finalResults + @($entityData.Entity)
}
}

# Third pass: Process split properties and remerge them
foreach ($entity in $finalResults) {
if ($entity.SplitOverProps) {
$splitInfoList = $entity.SplitOverProps | ConvertFrom-Json
Expand Down
5 changes: 3 additions & 2 deletions Modules/CIPPCore/Public/GraphHelper/New-ExoRequest.ps1
Original file line number Diff line number Diff line change
Expand Up @@ -23,14 +23,15 @@ function New-ExoRequest ($tenantid, $cmdlet, $cmdParams, $useSystemMailbox, $Anc
if ($cmdparams.anr) { $Anchor = $cmdparams.anr }
if ($cmdparams.User) { $Anchor = $cmdparams.User }
if ($cmdparams.mailbox) { $Anchor = $cmdparams.mailbox }
if ($cmdlet -eq 'Set-AdminAuditLogConfig') { $anchor = "UPN:SystemMailbox{8cc370d3-822a-4ab8-a926-bb94bd0641a9}@$($OnMicrosoft)" }
if (!$Anchor -or $useSystemMailbox) {
if (!$Tenant.initialDomainName -or $Tenant.initialDomainName -notlike '*onmicrosoft.com*') {
$OnMicrosoft = (New-GraphGetRequest -uri 'https://graph.microsoft.com/beta/domains?$top=999' -tenantid $tenantid -NoAuthCheck $NoAuthCheck | Where-Object -Property isInitial -EQ $true).id
} else {
$OnMicrosoft = $Tenant.initialDomainName
}
$anchor = "UPN:SystemMailbox{bb558c35-97f1-4cb9-8ff7-d53741dc928c}@$($OnMicrosoft)"
if ($cmdlet -in 'Set-AdminAuditLogConfig', 'Get-AdminAuditLogConfig', 'Enable-OrganizationCustomization', 'Get-OrganizationConfig') { $anchor = "UPN:SystemMailbox{8cc370d3-822a-4ab8-a926-bb94bd0641a9}@$($OnMicrosoft)" }

}
#if the anchor is a GUID, try looking up the user.
if ($Anchor -match '^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$') {
Expand Down Expand Up @@ -78,4 +79,4 @@ function New-ExoRequest ($tenantid, $cmdlet, $cmdParams, $useSystemMailbox, $Anc
} else {
Write-Error 'Not allowed. You cannot manage your own tenant or tenants not under your scope'
}
}
}
22 changes: 18 additions & 4 deletions Modules/CIPPCore/Public/GraphHelper/Write-CippFunctionStats.ps1
Original file line number Diff line number Diff line change
Expand Up @@ -11,12 +11,23 @@ function Write-CippFunctionStats {
[string]$ErrorMsg = ''
)
try {
$Start = Get-Date $Start
$End = Get-Date $End

$Table = Get-CIPPTable -tablename CippFunctionStats
$RowKey = [string](New-Guid).Guid
$TimeSpan = New-TimeSpan -Start $Start -End $End
$Duration = [int]$TimeSpan.TotalSeconds
$DurationMS = [int]$TimeSpan.TotalMilliseconds

# if datetime is local, convert to UTC
if ($Start.Kind -eq 'Local') {
$Start = $Start.ToUniversalTime()
}
if ($End.Kind -eq 'Local') {
$End = $End.ToUniversalTime()
}

$StatEntity = @{}
# Flatten data to json string
$StatEntity.PartitionKey = $FunctionType
Expand All @@ -28,13 +39,16 @@ function Write-CippFunctionStats {
$StatEntity.ErrorMsg = $ErrorMsg
$Entity = [PSCustomObject]$Entity
foreach ($Property in $Entity.PSObject.Properties.Name) {
if ($Entity.$Property.GetType().Name -in ('Hashtable', 'PSCustomObject', 'OrderedHashtable')) {
$StatEntity.$Property = [string]($Entity.$Property | ConvertTo-Json -Compress)
} elseif ($Property -notin ('ETag', 'RowKey', 'PartitionKey', 'Timestamp', 'LastRefresh')) {
$StatEntity.$Property = $Entity.$Property
if ($Entity.$Property) {
if ($Entity.$Property.GetType().Name -in ('Hashtable', 'PSCustomObject', 'OrderedHashtable')) {
$StatEntity.$Property = [string]($Entity.$Property | ConvertTo-Json -Compress)
} elseif ($Property -notin ('ETag', 'RowKey', 'PartitionKey', 'Timestamp', 'LastRefresh')) {
$StatEntity.$Property = $Entity.$Property
}
}
}
$StatEntity = [PSCustomObject]$StatEntity

Add-CIPPAzDataTableEntity @Table -Entity $StatEntity -Force
} catch {
Write-Host "Exception logging stats $($_.Exception.Message)"
Expand Down
17 changes: 11 additions & 6 deletions Modules/CIPPCore/Public/GraphRequests/Get-GraphRequestList.ps1
Original file line number Diff line number Diff line change
Expand Up @@ -285,12 +285,17 @@ function Get-GraphRequestList {
if (!$QueueThresholdExceeded) {
$GraphRequestResults = New-GraphGetRequest @GraphRequest -ErrorAction Stop | Select-Object *, @{l = 'Tenant'; e = { $TenantFilter } }, @{l = 'CippStatus'; e = { 'Good' } }
if ($ReverseTenantLookup -and $GraphRequestResults) {
$TenantInfo = $GraphRequestResults.$ReverseTenantLookupProperty | Sort-Object -Unique | ForEach-Object {
New-GraphGetRequest -uri "https://graph.microsoft.com/beta/tenantRelationships/findTenantInformationByTenantId(tenantId='$_')" -noauthcheck $true -asApp:$true -tenant $env:TenantId
}
foreach ($Result in $GraphRequestResults) {
$Result | Select-Object @{n = 'TenantInfo'; e = { $TenantInfo | Where-Object { $Result.$ReverseTenantLookupProperty -eq $_.tenantId } } }, *
$ReverseLookupRequests = $GraphRequestResults.$ReverseTenantLookupProperty | Sort-Object -Unique | ForEach-Object {
@{
id = $_
url = "tenantRelationships/findTenantInformationByTenantId(tenantId='$_')"
method = 'GET'
}
}
$TenantInfo = New-GraphBulkRequest -Requests @($ReverseLookupRequests) -tenantid $env:TenantId -NoAuthCheck $true -asapp $true

$GraphRequestResults | Select-Object @{n = 'TenantInfo'; e = { Get-GraphBulkResultByID -Results @($TenantInfo) -ID $_.$ReverseTenantLookupProperty } }, *

} else {
$GraphRequestResults
}
Expand All @@ -306,4 +311,4 @@ function Get-GraphRequestList {
$_.Data | ConvertFrom-Json
}
}
}
}
Loading

0 comments on commit b20b707

Please sign in to comment.