Skip to content

Commit c369f5a

Browse files
Performance tweaks
1 parent 97b1170 commit c369f5a

File tree

1 file changed

+109
-124
lines changed

1 file changed

+109
-124
lines changed

Modules/CIPPCore/Public/Functions/Get-CIPPTenantAlignment.ps1

Lines changed: 109 additions & 124 deletions
Original file line numberDiff line numberDiff line change
@@ -226,8 +226,13 @@ function Get-CIPPTenantAlignment {
226226
}
227227

228228
$AllStandards = $StandardsData.StandardId
229+
$AllStandardsArray = @($AllStandards)
229230
$ReportingEnabledStandards = ($StandardsData | Where-Object { $_.ReportingEnabled }).StandardId
230231
$ReportingDisabledStandards = ($StandardsData | Where-Object { -not $_.ReportingEnabled }).StandardId
232+
$ReportingDisabledSet = [System.Collections.Generic.HashSet[string]]::new($ReportingDisabledStandards)
233+
$TemplateAssignedTenantsSet = if ($TemplateAssignedTenants.Count -gt 0) {
234+
[System.Collections.Generic.HashSet[string]]::new($TemplateAssignedTenants)
235+
} else { $null }
231236

232237
foreach ($TenantName in $TenantStandards.Keys) {
233238
Measure-CippTask -TaskName 'Template.ProcessTenant' -EventName 'CIPP.TenantAlignment.Profile' -Metadata @{
@@ -236,146 +241,126 @@ function Get-CIPPTenantAlignment {
236241
StandardsCount = $AllStandards.Count
237242
AppliesToAll = $AppliestoAllTenants
238243
} -Script {
239-
Measure-CippTask -TaskName 'Template.CheckTenantScope' -EventName 'CIPP.TenantAlignment.Profile' -Metadata @{
240-
TenantName = $TenantName
241-
} -Script {
242-
if (-not $AppliestoAllTenants -and $TenantName -notin $TemplateAssignedTenants) {
244+
# Step 2 & 3: Check tenant scope with HashSet and cache tenant data
245+
if (-not $AppliestoAllTenants) {
246+
if ($TemplateAssignedTenantsSet -and -not $TemplateAssignedTenantsSet.Contains($TenantName)) {
243247
return
244248
}
245249
}
246250

247251
$AllCount = $AllStandards.Count
248-
$script:LatestDataCollection = $null
249-
250-
$ComparisonTable = Measure-CippTask -TaskName 'Template.BuildComparisonTable' -EventName 'CIPP.TenantAlignment.Profile' -Metadata @{
251-
TemplateGUID = $Template.GUID
252-
TenantName = $TenantName
253-
StandardsCount = $AllStandards.Count
254-
} -Script {
255-
$ComparisonResults = [System.Collections.Generic.List[object]]::new()
256-
257-
Measure-CippTask -TaskName 'Template.IterateStandards' -EventName 'CIPP.TenantAlignment.Profile' -Metadata @{
258-
StandardsCount = $AllStandards.Count
259-
} -Script {
260-
foreach ($StandardKey in $AllStandards) {
261-
Measure-CippTask -TaskName 'Template.ProcessStandard' -EventName 'CIPP.TenantAlignment.Profile' -Metadata @{
262-
StandardKey = $StandardKey
263-
} -Script {
264-
$IsReportingDisabled = Measure-CippTask -TaskName 'Template.CheckReportingDisabled' -EventName 'CIPP.TenantAlignment.Profile' -Script {
265-
$ReportingDisabledStandards -contains $StandardKey
266-
}
267-
268-
$HasStandard = Measure-CippTask -TaskName 'Template.CheckHasStandard' -EventName 'CIPP.TenantAlignment.Profile' -Script {
269-
$TenantStandards[$TenantName].ContainsKey($StandardKey)
270-
}
271-
272-
if ($HasStandard) {
273-
$StandardObject = Measure-CippTask -TaskName 'Template.GetStandardObject' -EventName 'CIPP.TenantAlignment.Profile' -Script {
274-
$TenantStandards[$TenantName][$StandardKey]
275-
}
276-
277-
$Value = $StandardObject.Value
278-
279-
Measure-CippTask -TaskName 'Template.UpdateLatestRefresh' -EventName 'CIPP.TenantAlignment.Profile' -Script {
280-
if ($StandardObject.LastRefresh) {
281-
$RefreshTime = [DateTime]::Parse($StandardObject.LastRefresh)
282-
if (-not $script:LatestDataCollection -or $RefreshTime -gt $script:LatestDataCollection) {
283-
$script:LatestDataCollection = $RefreshTime
284-
}
285-
}
286-
}
287-
288-
$IsCompliant = ($Value -eq $true)
289-
$IsLicenseMissing = ($Value -is [string] -and $Value -like 'License Missing:*')
290-
291-
$ComplianceStatus = Measure-CippTask -TaskName 'Template.DetermineStatus' -EventName 'CIPP.TenantAlignment.Profile' -Script {
292-
if ($IsReportingDisabled) {
293-
'Reporting Disabled'
294-
} elseif ($IsCompliant) {
295-
'Compliant'
296-
} elseif ($IsLicenseMissing) {
297-
'License Missing'
298-
} else {
299-
'Non-Compliant'
300-
}
301-
}
252+
$LatestDataCollection = $null
253+
# Step 3: Cache hashtable lookup
254+
$CurrentTenantStandards = $TenantStandards[$TenantName]
255+
256+
# Step 6: Pre-allocate list with capacity
257+
$ComparisonResults = [System.Collections.Generic.List[object]]::new($AllStandardsArray.Count)
258+
259+
# Step 4: Use for loop instead of foreach
260+
for ($i = 0; $i -lt $AllStandardsArray.Count; $i++) {
261+
$StandardKey = $AllStandardsArray[$i]
262+
263+
# Step 2: Use HashSet for Contains
264+
$IsReportingDisabled = $ReportingDisabledSet.Contains($StandardKey)
265+
# Step 3: Use cached tenant data
266+
$HasStandard = $CurrentTenantStandards.ContainsKey($StandardKey)
267+
268+
if ($HasStandard) {
269+
$StandardObject = $CurrentTenantStandards[$StandardKey]
270+
$Value = $StandardObject.Value
271+
272+
if ($StandardObject.LastRefresh) {
273+
$RefreshTime = [DateTime]::Parse($StandardObject.LastRefresh)
274+
if (-not $LatestDataCollection -or $RefreshTime -gt $LatestDataCollection) {
275+
$LatestDataCollection = $RefreshTime
276+
}
277+
}
302278

303-
$StandardValueJson = Measure-CippTask -TaskName 'Template.ConvertToJson' -EventName 'CIPP.TenantAlignment.Profile' -Script {
304-
$Value | ConvertTo-Json -Depth 5 -Compress
305-
}
279+
$IsCompliant = ($Value -eq $true)
280+
$IsLicenseMissing = ($Value -is [string] -and $Value -like 'License Missing:*')
281+
282+
$ComplianceStatus = if ($IsReportingDisabled) {
283+
'Reporting Disabled'
284+
} elseif ($IsCompliant) {
285+
'Compliant'
286+
} elseif ($IsLicenseMissing) {
287+
'License Missing'
288+
} else {
289+
'Non-Compliant'
290+
}
306291

307-
$ComparisonResults.Add([PSCustomObject]@{
308-
StandardName = $StandardKey
309-
Compliant = $IsCompliant
310-
StandardValue = $StandardValueJson
311-
ComplianceStatus = $ComplianceStatus
312-
ReportingDisabled = $IsReportingDisabled
313-
})
314-
} else {
315-
$ComplianceStatus = if ($IsReportingDisabled) {
316-
'Reporting Disabled'
317-
} else {
318-
'Non-Compliant'
319-
}
292+
$StandardValueJson = $Value | ConvertTo-Json -Depth 5 -Compress
320293

321-
$ComparisonResults.Add([PSCustomObject]@{
322-
StandardName = $StandardKey
323-
Compliant = $false
324-
StandardValue = 'NOT FOUND'
325-
ComplianceStatus = $ComplianceStatus
326-
ReportingDisabled = $IsReportingDisabled
327-
})
328-
}
329-
}
294+
$ComparisonResults.Add([PSCustomObject]@{
295+
StandardName = $StandardKey
296+
Compliant = $IsCompliant
297+
StandardValue = $StandardValueJson
298+
ComplianceStatus = $ComplianceStatus
299+
ReportingDisabled = $IsReportingDisabled
300+
})
301+
} else {
302+
$ComplianceStatus = if ($IsReportingDisabled) {
303+
'Reporting Disabled'
304+
} else {
305+
'Non-Compliant'
330306
}
331-
}
332307

333-
$ComparisonResults
308+
$ComparisonResults.Add([PSCustomObject]@{
309+
StandardName = $StandardKey
310+
Compliant = $false
311+
StandardValue = 'NOT FOUND'
312+
ComplianceStatus = $ComplianceStatus
313+
ReportingDisabled = $IsReportingDisabled
314+
})
315+
}
334316
}
335317

336-
Measure-CippTask -TaskName 'Template.CalculateScores' -EventName 'CIPP.TenantAlignment.Profile' -Metadata @{
337-
TemplateGUID = $Template.GUID
338-
TenantName = $TenantName
339-
} -Script {
340-
$CompliantStandards = ($ComparisonTable | Where-Object { $_.ComplianceStatus -eq 'Compliant' }).Count
341-
$NonCompliantStandards = ($ComparisonTable | Where-Object { $_.ComplianceStatus -eq 'Non-Compliant' }).Count
342-
$LicenseMissingStandards = ($ComparisonTable | Where-Object { $_.ComplianceStatus -eq 'License Missing' }).Count
343-
$ReportingDisabledStandardsCount = ($ComparisonTable | Where-Object { $_.ReportingDisabled }).Count
344-
345-
$AlignmentPercentage = if (($AllCount - $ReportingDisabledStandardsCount) -gt 0) {
346-
[Math]::Round(($CompliantStandards / ($AllCount - $ReportingDisabledStandardsCount)) * 100)
347-
} else {
348-
0
349-
}
318+
# Step 5: Replace Where-Object with direct counting
319+
$CompliantStandards = 0
320+
$NonCompliantStandards = 0
321+
$LicenseMissingStandards = 0
322+
$ReportingDisabledStandardsCount = 0
323+
324+
foreach ($item in $ComparisonResults) {
325+
if ($item.ComplianceStatus -eq 'Compliant') { $CompliantStandards++ }
326+
elseif ($item.ComplianceStatus -eq 'Non-Compliant') { $NonCompliantStandards++ }
327+
elseif ($item.ComplianceStatus -eq 'License Missing') { $LicenseMissingStandards++ }
328+
if ($item.ReportingDisabled) { $ReportingDisabledStandardsCount++ }
329+
}
350330

351-
$LicenseMissingPercentage = if ($AllCount -gt 0) {
352-
[Math]::Round(($LicenseMissingStandards / $AllCount) * 100)
353-
} else {
354-
0
355-
}
331+
$AlignmentPercentage = if (($AllCount - $ReportingDisabledStandardsCount) -gt 0) {
332+
[Math]::Round(($CompliantStandards / ($AllCount - $ReportingDisabledStandardsCount)) * 100)
333+
} else {
334+
0
335+
}
356336

357-
$Result = [PSCustomObject]@{
358-
TenantFilter = $TenantName
359-
StandardName = $Template.templateName
360-
StandardId = $Template.GUID
361-
standardType = $Template.type
362-
standardSettings = $Template.Standards
363-
driftAlertEmail = $Template.driftAlertEmail
364-
driftAlertWebhook = $Template.driftAlertWebhook
365-
AlignmentScore = $AlignmentPercentage
366-
LicenseMissingPercentage = $LicenseMissingPercentage
367-
CombinedScore = $AlignmentPercentage + $LicenseMissingPercentage
368-
CompliantStandards = $CompliantStandards
369-
NonCompliantStandards = $NonCompliantStandards
370-
LicenseMissingStandards = $LicenseMissingStandards
371-
TotalStandards = $AllCount
372-
ReportingDisabledCount = $ReportingDisabledStandardsCount
373-
LatestDataCollection = if ($script:LatestDataCollection) { $script:LatestDataCollection } else { $null }
374-
ComparisonDetails = $ComparisonTable
375-
}
337+
$LicenseMissingPercentage = if ($AllCount -gt 0) {
338+
[Math]::Round(($LicenseMissingStandards / $AllCount) * 100)
339+
} else {
340+
0
341+
}
376342

377-
$Results.Add($Result)
343+
$Result = [PSCustomObject]@{
344+
TenantFilter = $TenantName
345+
StandardName = $Template.templateName
346+
StandardId = $Template.GUID
347+
standardType = $Template.type
348+
standardSettings = $Template.Standards
349+
driftAlertEmail = $Template.driftAlertEmail
350+
driftAlertWebhook = $Template.driftAlertWebhook
351+
AlignmentScore = $AlignmentPercentage
352+
LicenseMissingPercentage = $LicenseMissingPercentage
353+
CombinedScore = $AlignmentPercentage + $LicenseMissingPercentage
354+
CompliantStandards = $CompliantStandards
355+
NonCompliantStandards = $NonCompliantStandards
356+
LicenseMissingStandards = $LicenseMissingStandards
357+
TotalStandards = $AllCount
358+
ReportingDisabledCount = $ReportingDisabledStandardsCount
359+
LatestDataCollection = if ($LatestDataCollection) { $LatestDataCollection } else { $null }
360+
ComparisonDetails = $ComparisonResults
378361
}
362+
363+
$Results.Add($Result)
379364
}
380365
}
381366
}

0 commit comments

Comments
 (0)