Skip to content

Commit 115cc10

Browse files
authored
Merge branch 'psnext' into psnext-test-metadata-stage2
2 parents 79252d9 + 4bba1b3 commit 115cc10

12 files changed

Lines changed: 824 additions & 114 deletions
Lines changed: 165 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,165 @@
1+
<#
2+
.SYNOPSIS
3+
Filters policies based on specific setting configurations and their expected values.
4+
5+
.DESCRIPTION
6+
This function filters an array of policies by checking if they contain specific settings with expected values.
7+
Each setting can have its own path configuration for navigating the policy's JSON structure, making this
8+
function flexible enough to work with different policy types and structures.
9+
10+
.PARAMETER Policies
11+
An array of policy objects to filter. Each policy should contain settings that can be navigated using
12+
the paths specified in RequiredSettings.
13+
14+
.PARAMETER RequiredSettings
15+
A hashtable where each key is a setting definition ID and the value is a configuration object containing:
16+
- ExpectedValues: Array of values that the setting should have
17+
- ContainerPath: Dot-separated path to the container holding the settings (e.g., 'settings.settinginstance.groupSettingCollectionValue.children')
18+
- SettingIdPath: Property name or path to access the setting ID within each container item
19+
- ValuePath: Property name or path to access the setting value within the target setting
20+
- Description: (Optional) Human-readable description of what the setting controls
21+
22+
.OUTPUTS
23+
System.Array
24+
Returns an array of policy objects that contain all of the required settings with matching values.
25+
26+
.EXAMPLE
27+
$requiredSettings = @{
28+
'com.apple.extensiblesso_extensionidentifier' = @{
29+
ExpectedValues = @('com.microsoft.CompanyPortalMac.ssoextension')
30+
ContainerPath = 'settings.settinginstance.groupSettingCollectionValue.children'
31+
SettingIdPath = 'settingDefinitionId'
32+
ValuePath = 'simplesettingvalue.value'
33+
Description = 'Microsoft SSO Extension Identifier'
34+
}
35+
}
36+
37+
$filteredPolicies = Get-FilteredPoliciesBySetting -Policies $allPolicies -RequiredSettings $requiredSettings
38+
39+
Filters policies to include only those that have the Microsoft SSO extension configured.
40+
41+
.EXAMPLE
42+
$multipleSettings = @{
43+
'setting.id.one' = @{
44+
ExpectedValues = @('value1', 'value2')
45+
ContainerPath = 'settings.configurations'
46+
SettingIdPath = 'id'
47+
ValuePath = 'value'
48+
}
49+
'setting.id.two' = @{
50+
ExpectedValues = @('requiredvalue')
51+
ContainerPath = 'customSettings.payloadContent'
52+
SettingIdPath = 'payloadType'
53+
ValuePath = 'payloadContent.value'
54+
}
55+
}
56+
57+
$filteredPolicies = Get-FilteredPoliciesBySetting -Policies $policies -RequiredSettings $multipleSettings
58+
59+
Filters policies that contain both required settings, each located in different JSON paths.
60+
61+
.NOTES
62+
- The function uses a nested helper function Get-NestedProperty to safely navigate object properties
63+
- If any path evaluation fails, the function logs a verbose message and continues with the next setting
64+
- The function returns policies that match ALL of the required settings (AND logic)
65+
- Empty or null policy arrays are handled gracefully by returning an empty array
66+
#>
67+
function Get-FilteredPoliciesBySetting {
68+
[CmdletBinding()]
69+
param(
70+
[Parameter(Mandatory)]
71+
[array]$Policies,
72+
73+
[Parameter(Mandatory)]
74+
[hashtable]$RequiredSettings
75+
)
76+
77+
<#
78+
.SYNOPSIS
79+
Retrieves a nested property value from an object using a dot-separated path.
80+
81+
.DESCRIPTION
82+
Traverses an object's properties according to the provided dot-separated path and returns the value found at that path, or $null if any segment is missing.
83+
84+
.PARAMETER InputObject
85+
The object from which to retrieve the nested property.
86+
87+
.PARAMETER Path
88+
The dot-separated path string indicating the property to retrieve (e.g., 'settings.settinginstance.groupSettingCollectionValue').
89+
90+
.OUTPUTS
91+
Returns the value at the specified path, or $null if not found.
92+
#>
93+
function Get-NestedProperty {
94+
[CmdletBinding()]
95+
param(
96+
[Parameter(Mandatory)][object]$InputObject,
97+
[Parameter(Mandatory)][string]$Path
98+
)
99+
$current = $InputObject
100+
foreach ($segment in $Path -split '\.') {
101+
if ($null -eq $current) {
102+
return $null
103+
}
104+
$current = $current."$segment"
105+
}
106+
return $current
107+
}
108+
109+
$filteredPolicies = @()
110+
111+
foreach ($policy in $Policies) {
112+
$matchedSettingsCount = 0
113+
114+
# Check each required setting configuration
115+
foreach ($settingId in $RequiredSettings.Keys) {
116+
$settingConfig = $RequiredSettings[$settingId]
117+
$expectedValues = $settingConfig.ExpectedValues
118+
$containerPath = $settingConfig.ContainerPath
119+
$settingIdPath = $settingConfig.SettingIdPath
120+
$valuePath = $settingConfig.ValuePath
121+
122+
$settingMatched = $false
123+
124+
try {
125+
# Get the settings container using the configured path
126+
$settingsContainer = Get-NestedProperty -InputObject $policy -Path $containerPath
127+
128+
if ($settingsContainer) {
129+
# Find the specific setting by ID
130+
$targetSetting = $settingsContainer | Where-Object {
131+
(Get-NestedProperty -InputObject $_ -Path $settingIdPath) -eq $settingId
132+
}
133+
134+
if ($targetSetting) {
135+
# Get actual values using the configured value path
136+
$actualValues = @(Get-NestedProperty -InputObject $targetSetting -Path $valuePath)
137+
138+
# Check if any actual value matches any expected value
139+
foreach ($actualValue in $actualValues) {
140+
if ($expectedValues -contains $actualValue) {
141+
$settingMatched = $true
142+
break
143+
}
144+
}
145+
}
146+
}
147+
}
148+
catch {
149+
Write-Verbose "Failed to evaluate paths for setting $settingId : $_"
150+
continue
151+
}
152+
153+
if ($settingMatched) {
154+
$matchedSettingsCount++
155+
}
156+
}
157+
158+
# Policy must match ALL required settings (AND logic)
159+
if ($matchedSettingsCount -eq $RequiredSettings.Keys.Count) {
160+
$filteredPolicies += $policy
161+
}
162+
}
163+
164+
return $filteredPolicies
165+
}

0 commit comments

Comments
 (0)