Skip to content

Commit c307491

Browse files
authored
Merge pull request #150 from KelvinTegelaar/dev
[pull] dev from KelvinTegelaar:dev
2 parents f0297f5 + d029fa4 commit c307491

File tree

8 files changed

+110
-107
lines changed

8 files changed

+110
-107
lines changed

Modules/CIPPCore/Public/CustomData/Invoke-CustomDataSync.ps1

Lines changed: 65 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -37,21 +37,29 @@ function Invoke-CustomDataSync {
3737
'user' {
3838
$Query = @{
3939
id = 'user'
40-
url = 'users?$select=id,userPrincipalName,displayName&$count=true&$top=999'
40+
url = 'users?$select=id,userPrincipalName,displayName,mailNickname&$count=true&$top=999'
4141
method = 'GET'
4242
}
4343
}
4444
}
45-
$DirectoryObjectQueries.Add($Query)
4645
$SyncConfig
46+
if ($DirectoryObjectQueries | Where-Object { $_.id -eq $Query.id }) {
47+
continue
48+
} else {
49+
$DirectoryObjectQueries.Add($Query)
50+
}
4751
}
4852

4953
Write-Information "Getting directory objects for tenant $TenantFilter"
5054
#Write-Information ($DirectoryObjectQueries | ConvertTo-Json -Depth 10)
5155
$AllDirectoryObjects = New-GraphBulkRequest -tenantid $TenantFilter -Requests @($DirectoryObjectQueries)
56+
Write-Information "Retrieved $($AllDirectoryObjects.Count) result sets"
57+
#Write-Information ($AllDirectoryObjects | ConvertTo-Json -Depth 10)
58+
59+
$PatchObjects = @{}
5260

5361
foreach ($SyncConfig in $SyncConfigs) {
54-
Write-Warning "Processing Custom Data mapping for $($Mapping.customDataAttribute.value)"
62+
Write-Warning "Processing Custom Data mapping for $($SyncConfig.Dataset)"
5563
Write-Information ($SyncConfig | ConvertTo-Json -Depth 10)
5664
$Rows = $Cache.$($SyncConfig.Dataset)
5765
if (!$Rows) {
@@ -75,62 +83,87 @@ function Invoke-CustomDataSync {
7583
foreach ($Row in $Rows) {
7684
#Write-Warning 'Processing row'
7785
#Write-Information ($Row | ConvertTo-Json -Depth 10)
78-
#Write-Host "Comparing $SourceMatchProperty $($Row.$SourceMatchProperty) to $($DirectoryObjects.Count) directory objects on $DestinationMatchProperty"
79-
$DirectoryObject = $DirectoryObjects | Where-Object { $_.$DestinationMatchProperty -eq $Row.$SourceMatchProperty }
86+
Write-Host "Comparing $SourceMatchProperty $($Row.$SourceMatchProperty) to $($DirectoryObjects.Count) directory objects on $DestinationMatchProperty"
87+
if ($DestinationMatchProperty.Count -gt 1) {
88+
foreach ($Prop in $DestinationMatchProperty) {
89+
$DirectoryObject = $DirectoryObjects | Where-Object { $_.$Prop -eq $Row.$SourceMatchProperty }
90+
if ($DirectoryObject) {
91+
break
92+
}
93+
}
94+
} else {
95+
$DirectoryObject = $DirectoryObjects | Where-Object { $_.$DestinationMatchProperty -eq $Row.$SourceMatchProperty }
96+
}
97+
8098
if (!$DirectoryObject) {
8199
Write-Warning "No directory object found for $($Row.$SourceMatchProperty)"
82100
}
83101
if ($DirectoryObject) {
84102
$ObjectUrl = "$($url)/$($DirectoryObject.id)"
85103

104+
# check if key in patch objects already exists otherwise create one with object url
105+
if (!$PatchObjects.ContainsKey($ObjectUrl)) {
106+
Write-Host "Creating new object for $($ObjectUrl)"
107+
$PatchObjects[$ObjectUrl] = @{}
108+
}
109+
86110
if ($DatasetConfig.type -eq 'object') {
87111
if ($CustomDataAttribute -match '\.') {
88112
$Props = @($CustomDataAttribute -split '\.')
89-
$Body = [PSCustomObject]@{
90-
$Props[0] = [PSCustomObject]@{
91-
$Props[1] = $Row.$ExtensionSyncProperty
92-
}
113+
if (!$PatchObjects[$ObjectUrl].ContainsKey($Props[0])) {
114+
Write-Host "Creating new object for $($Props[0])"
115+
$PatchObjects[$ObjectUrl][$Props[0]] = @{}
93116
}
94-
} else {
95-
$Body = [PSCustomObject]@{
96-
$CustomDataAttribute = @($Row.$ExtensionSyncProperty)
117+
if (!$PatchObjects[$ObjectUrl][$Props[0]].ContainsKey($Props[1])) {
118+
Write-Host "Creating new object for $($Props[1])"
119+
$PatchObjects[$ObjectUrl][$Props[0]][$Props[1]] = $Row.$ExtensionSyncProperty
97120
}
121+
} else {
122+
$PatchObjects[$ObjectUrl][$CustomDataAttribute] = $Row.$ExtensionSyncProperty
98123
}
99124
} elseif ($DatasetConfig.type -eq 'array') {
125+
Write-Warning "Processing array data for $($CustomDataAttribute) on $($DirectoryObject.id) - found $($Row.Count) entries"
126+
#Write-Information ($Row | ConvertTo-Json -Depth 10)
127+
if ($DatasetConfig.select) {
128+
$Row = $Row | Select-Object -Property ($DatasetConfig.select -split ',')
129+
}
100130

101-
$Data = foreach ($Entry in $Row.$ExtensionSyncProperty) {
102-
if ($DatasetConfig.storeAs -eq 'json') {
103-
$Entry | ConvertTo-Json -Depth 5 -Compress
104-
} else {
105-
$Entry
106-
}
131+
if (!$PatchObjects[$ObjectUrl].ContainsKey($CustomDataAttribute)) {
132+
$PatchObjects[$ObjectUrl][$CustomDataAttribute] = [System.Collections.Generic.List[string]]::new()
107133
}
108134

109-
$Body = [PSCustomObject]@{
110-
$CustomDataAttribute = @($Data)
135+
$Data = if ($DatasetConfig.storeAs -eq 'json') {
136+
$Row | ConvertTo-Json -Depth 5 -Compress
137+
} else {
138+
$Row
111139
}
112-
}
113140

114-
$BulkRequests.Add([PSCustomObject]@{
115-
id = $DirectoryObject.$DestinationMatchProperty
116-
url = $ObjectUrl
117-
method = 'PATCH'
118-
headers = @{
119-
'Content-Type' = 'application/json'
120-
}
121-
body = $Body.PSObject.Copy()
122-
})
141+
$PatchObjects[$ObjectUrl][$CustomDataAttribute].Add($Data)
142+
}
123143
}
124144
}
125145
}
126146

127-
#Write-Host ($BulkRequests | ConvertTo-Json -Depth 10)
147+
foreach ($ObjectUrl in $PatchObjects.Keys) {
148+
$PatchObject = $PatchObjects[$ObjectUrl]
149+
$BulkRequests.Add([PSCustomObject]@{
150+
id = ($ObjectUrl -split '/' | Select-Object -Last 1)
151+
url = $ObjectUrl
152+
method = 'PATCH'
153+
body = $PatchObject
154+
headers = @{
155+
'Content-Type' = 'application/json'
156+
}
157+
})
158+
}
159+
160+
Write-Host ($BulkRequests | ConvertTo-Json -Depth 10)
128161
if ($BulkRequests.Count -gt 0) {
129162
Write-Information "Sending $($BulkRequests.Count) requests to Graph API"
130163
$Responses = New-GraphBulkRequest -tenantid $TenantFilter -Requests @($BulkRequests)
131164
if ($Responses | Where-Object { $_.statusCode -ne 204 }) {
132165
Write-Warning 'Some requests failed'
133-
Write-Information ($Responses | Where-Object { $_.statusCode -ne 204 } | Select-Object -Property id, statusCode | ConvertTo-Json)
166+
Write-Information ($Responses | Where-Object { $_.status -ne 204 } | ConvertTo-Json -Depth 10)
134167
}
135168
}
136169
}

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

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
using namespace System.Net
22

3-
Function Invoke-ListUserMailboxDetails {
3+
function Invoke-ListUserMailboxDetails {
44
<#
55
.FUNCTIONALITY
66
Entrypoint
@@ -67,6 +67,7 @@ Function Invoke-ListUserMailboxDetails {
6767
$usernames = New-GraphGetRequest -tenantid $TenantFilter -uri 'https://graph.microsoft.com/beta/users?$select=id,userPrincipalName&$top=999'
6868
$Results = New-ExoBulkRequest -TenantId $TenantFilter -CmdletArray $Requests -returnWithCommand $true -Anchor $username
6969
Write-Host "First line of usernames is $($usernames[0] | ConvertTo-Json)"
70+
7071
# Assign variables from $Results
7172
$MailboxDetailedRequest = $Results.'Get-Mailbox'
7273
$PermsRequest = $Results.'Get-MailboxPermission'
@@ -75,7 +76,8 @@ Function Invoke-ListUserMailboxDetails {
7576
$ArchiveSizeRequest = $Results.'Get-MailboxStatistics'
7677
$BlockedSender = $Results.'Get-BlockedSenderAddress'
7778
$PermsRequest2 = $Results.'Get-RecipientPermission'
78-
$StatsRequest = New-GraphGetRequest -uri "https://outlook.office365.com/adminapi/beta/$($TenantFilter)/Mailbox('$($MailboxDetailedRequest.UserPrincipalName)')/Exchange.GetMailboxStatistics()" -Tenantid $TenantFilter -scope ExchangeOnline -noPagination $true
79+
80+
$StatsRequest = New-GraphGetRequest -uri "https://outlook.office365.com/adminapi/beta/$($TenantFilter)/Mailbox('$($UserID)')/Exchange.GetMailboxStatistics()" -Tenantid $TenantFilter -scope ExchangeOnline -noPagination $true
7981

8082

8183
# Handle ArchiveEnabled and AutoExpandingArchiveEnabled

Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Tenant/Standards/Invoke-ListStandardsCompare.ps1

Lines changed: 15 additions & 52 deletions
Original file line numberDiff line numberDiff line change
@@ -10,62 +10,25 @@ Function Invoke-ListStandardsCompare {
1010
[CmdletBinding()]
1111
param($Request, $TriggerMetadata)
1212

13-
# Create mock data for testing with the correct API structure
14-
# Only tenant data with values, no compliance information or standard values
15-
$Results = @(
16-
@{
17-
tenantFilter = 'TenantOne'
18-
standardsResults = @(
19-
@{
20-
standardId = 'standards.MailContacts'
21-
standardName = 'Mail Contacts'
22-
value = @{
23-
GeneralContact = '[email protected]'
24-
SecurityContact = '[email protected]'
25-
MarketingContact = '[email protected]'
26-
TechContact = '[email protected]'
27-
}
28-
},
29-
@{
30-
standardId = 'standards.AuditLog'
31-
standardName = 'Audit Log'
32-
value = $true
33-
},
34-
@{
35-
standardId = 'standards.ProfilePhotos'
36-
standardName = 'Profile Photos'
37-
value = @{
38-
state = @{
39-
label = 'Enabled'
40-
value = 'enabled'
41-
}
42-
}
43-
}
44-
)
45-
},
46-
@{
47-
tenantFilter = 'dev.johnwduprey.com'
48-
standardsResults = @(
49-
@{
50-
standardId = 'standards.MailContacts'
51-
standardName = 'Mail Contacts'
52-
value = @{
53-
GeneralContact = '[email protected]'
54-
SecurityContact = '[email protected]'
55-
}
56-
},
57-
@{
58-
standardId = 'standards.AuditLog'
59-
standardName = 'Audit Log'
60-
value = $false
13+
$Table = Get-CIPPTable -TableName 'CippStandardsReports'
14+
$Results = Get-CIPPAzDataTableEntity @Table
15+
16+
#in the results we have objects starting with "standards." All these have to be converted from JSON. Do not do this is its a boolean
17+
$Results | ForEach-Object {
18+
$Object = $_
19+
$Object.PSObject.Properties | ForEach-Object {
20+
if ($_.Name -like 'standards.*') {
21+
if ($_.Value -isnot [System.Boolean]) {
22+
$_.Value = ConvertFrom-Json -InputObject $_.Value -ErrorAction SilentlyContinue
6123
}
62-
)
24+
}
6325
}
64-
)
65-
26+
}
27+
28+
6629
Push-OutputBinding -Name Response -Value ([HttpResponseContext]@{
6730
StatusCode = [HttpStatusCode]::OK
68-
Body = (ConvertTo-Json -Depth 15 -InputObject $Results)
31+
Body = @($Results)
6932
})
7033

7134
}

Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Tenant/Tools/Invoke-ExecGraphExplorerPreset.ps1

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -12,12 +12,12 @@ Function Invoke-ExecGraphExplorerPreset {
1212

1313
$APIName = $Request.Params.CIPPEndpoint
1414
Write-LogMessage -headers $Request.Headers -API $APINAME -message 'Accessed this API' -Sev 'Debug'
15-
#UNDOREPLACE
16-
$Username = ([System.Text.Encoding]::UTF8.GetString([System.Convert]::FromBase64String($request.headers.'x-ms-client-principal')) | ConvertFrom-Json).userDetails
17-
# Write to the Azure Functions log stream.
18-
Write-Host 'PowerShell HTTP trigger function processed a request.'
15+
$Username = $request.headers.'x-ms-client-principal-name'
16+
1917
$Action = $Request.Body.Action ?? ''
2018

19+
Write-Information ($Request.Body | ConvertTo-Json -Depth 10)
20+
2121
switch ($Action) {
2222
'Copy' {
2323
$Id = $Request.Body.preset.id ? $Request.Body.preset.id: (New-Guid).Guid

Modules/CIPPCore/Public/GraphHelper/New-ExoBulkRequest.ps1

Lines changed: 6 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -85,7 +85,7 @@ function New-ExoBulkRequest {
8585
}
8686
$BatchBodyJson = ConvertTo-Json -InputObject $BatchBodyObj -Depth 10
8787
$Results = Invoke-RestMethod $BatchURL -ResponseHeadersVariable responseHeaders -Method POST -Body $BatchBodyJson -Headers $Headers -ContentType 'application/json; charset=utf-8'
88-
$ReturnedData.Add($Results.responses)
88+
$ReturnedData.AddRange(@($Results.responses))
8989

9090
Write-Host "Batch #$($batches.IndexOf($batch) + 1) of $($batches.Count) processed"
9191
}
@@ -101,7 +101,7 @@ function New-ExoBulkRequest {
101101
foreach ($item in $ReturnedData) {
102102
$itemId = $item.id
103103
$CmdletName = $IdToCmdletName[$itemId]
104-
$body = $item.body
104+
$body = $item.body.PSObject.Copy()
105105

106106
if ($body.'@adminapi.warnings') {
107107
Write-Warning ($body.'@adminapi.warnings' | Out-String)
@@ -116,16 +116,16 @@ function New-ExoBulkRequest {
116116
}
117117
$resultValue = $body.value
118118

119-
# Assign results without using += or ArrayList
120119
if (-not $FinalData.ContainsKey($CmdletName)) {
121-
$FinalData[$CmdletName] = @($resultValue)
120+
$FinalData[$CmdletName] = [System.Collections.Generic.List[object]]::new()
121+
$FinalData.$CmdletName.Add($resultValue)
122122
} else {
123-
$FinalData[$CmdletName] = $FinalData[$CmdletName] + $resultValue
123+
$FinalData.$CmdletName.Add($resultValue)
124124
}
125125
}
126126
} else {
127127
$FinalData = foreach ($item in $ReturnedData) {
128-
$body = $item.body
128+
$body = $item.body.PSObject.Copy()
129129

130130
if ($body.'@adminapi.warnings') {
131131
Write-Warning ($body.'@adminapi.warnings' | Out-String)
@@ -141,7 +141,6 @@ function New-ExoBulkRequest {
141141
$body.value
142142
}
143143
}
144-
145144
return $FinalData
146145

147146
} else {

Modules/CIPPCore/Public/Set-StandardCompareField.ps1

Lines changed: 13 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -6,13 +6,20 @@ function Set-CIPPStandardsCompareField {
66
)
77
$Table = Get-CippTable -tablename 'CippStandardsReports'
88
$TenantName = Get-Tenants | Where-Object -Property defaultDomainName -EQ $Tenant
9-
$FieldValue = ConvertTo-Json -Compress -InputObject $FieldValue | Out-String
9+
if ($FieldValue -is [System.Boolean]) {
10+
$fieldValue = [bool]$FieldValue
11+
} elseif ($FieldValue -is [string]) {
12+
$FieldValue = [string]$FieldValue
13+
} else {
14+
$FieldValue = ConvertTo-Json -Compress -InputObject @($FieldValue) -Depth 10 | Out-String
15+
$FieldValue = [string]$FieldValue
16+
}
1017

1118
$Existing = Get-CIPPAzDataTableEntity @Table -Filter "PartitionKey eq 'StandardReport' and RowKey eq '$($TenantName.defaultDomainName)'"
1219
if ($Existing) {
13-
$Existing = $Existing | Select-Object * -ExcludeProperty ETag, TimeStamp | ConvertTo-Json -Compress | ConvertFrom-Json -AsHashtable
14-
$Existing[$FieldName] = "$FieldValue"
15-
$Existing['LastRefresh'] = [string]$(Get-Date (Get-Date).ToUniversalTime() -UFormat '+%Y-%m-%dT%H:%M:%S.000Z')
20+
$Existing = $Existing | Select-Object * -ExcludeProperty ETag, TimeStamp | ConvertTo-Json -Depth 10 -Compress | ConvertFrom-Json -AsHashtable
21+
$Existing[$FieldName] = $FieldValue
22+
$Existing['LastRefresh'] = [string]$(Get-Date (Get-Date).ToUniversalTime() -UFormat '+%Y-%m-%dT%H:%M:%S.000Z')
1623
$Existing = [PSCustomObject]$Existing
1724

1825
Add-CIPPAzDataTableEntity @Table -Entity $Existing -Force
@@ -23,8 +30,8 @@ function Set-CIPPStandardsCompareField {
2330
RowKey = "$($TenantName.defaultDomainName)"
2431
PartitionKey = 'StandardReport'
2532
LastRefresh = [string]$(Get-Date (Get-Date).ToUniversalTime() -UFormat '+%Y-%m-%dT%H:%M:%S.000Z')
26-
}
27-
$Result[$FieldName] = "$FieldValue"
33+
}
34+
$Result[$FieldName] = $FieldValue
2835
Add-CIPPAzDataTableEntity @Table -Entity $Result -Force
2936

3037
}

Modules/CIPPCore/Public/Standards/Invoke-CIPPStandardEnableMailTips.ps1

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -58,13 +58,12 @@ function Invoke-CIPPStandardEnableMailTips {
5858
if ($StateIsCorrect -eq $true) {
5959
Write-LogMessage -API 'Standards' -tenant $Tenant -message 'All MailTips are enabled' -sev Info
6060
} else {
61-
Write-StandardsAlert -message "Not all MailTips are enabled" -object $MailTipsState -tenant $Tenant -standardName 'EnableMailTips' -standardId $Settings.standardId
61+
Write-StandardsAlert -message 'Not all MailTips are enabled' -object $MailTipsState -tenant $Tenant -standardName 'EnableMailTips' -standardId $Settings.standardId
6262
Write-LogMessage -API 'Standards' -tenant $Tenant -message 'Not all MailTips are enabled' -sev Info
6363
}
6464
}
6565

6666
if ($Settings.report -eq $true) {
67-
6867
Add-CIPPBPAField -FieldName 'MailTipsEnabled' -FieldValue $StateIsCorrect -StoreAs bool -Tenant $tenant
6968
}
7069

Modules/CIPPCore/Public/Standards/Invoke-CIPPStandardEnablePronouns.ps1

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -63,13 +63,13 @@ function Invoke-CIPPStandardEnablePronouns {
6363
if ($CurrentState.isEnabledInOrganization -eq $true) {
6464
Write-LogMessage -API 'Standards' -tenant $tenant -message 'Pronouns are enabled.' -sev Info
6565
} else {
66-
Write-StandardsAlert -message "Pronouns are not enabled" -object $CurrentState -tenant $tenant -standardName 'EnablePronouns' -standardId $Settings.standardId
66+
Write-StandardsAlert -message 'Pronouns are not enabled' -object $CurrentState -tenant $tenant -standardName 'EnablePronouns' -standardId $Settings.standardId
6767
Write-LogMessage -API 'Standards' -tenant $tenant -message 'Pronouns are not enabled.' -sev Info
6868
}
6969
}
7070

7171
if ($Settings.report -eq $true) {
72-
72+
Set-CIPPStandardsCompareField -FieldName 'standards.EnablePronouns' -FieldValue $CurrentState.isEnabledInOrganization -Tenant $tenant
7373
Add-CIPPBPAField -FieldName 'PronounsEnabled' -FieldValue $CurrentState.isEnabledInOrganization -StoreAs bool -Tenant $tenant
7474
}
7575
}

0 commit comments

Comments
 (0)