Private/Select-InforcerBaselinePolicies.ps1
|
function Select-InforcerBaselinePolicies { <# .SYNOPSIS Filters a DocData policy collection to only policies belonging to a specific baseline. .DESCRIPTION Resolves the baseline identifier (GUID or friendly name), retrieves alignment details from the Inforcer API, and filters DocData.Policies in place to only those in the baseline. Must be called while the correct $script:InforcerSession is active. .PARAMETER DocData The DocData hashtable from Get-InforcerDocData. Contains .Tenant.clientTenantId and .Policies. Policies array is modified in place. .PARAMETER BaselineId Baseline GUID or friendly name. .OUTPUTS System.String — the resolved baseline display name, or $null if alignment data could not be retrieved. #> [CmdletBinding()] [OutputType([string])] param( [Parameter(Mandatory)] [object]$DocData, [Parameter(Mandatory)] [string]$BaselineId ) $clientTenantId = $DocData.Tenant.clientTenantId # Resolve baseline name to GUID $baselineGuid = $null $baselineFilterName = $null $guidTest = [guid]::Empty if ([guid]::TryParse($BaselineId.Trim(), [ref]$guidTest)) { $baselineGuid = $BaselineId.Trim() } else { $allBaselines = @(Invoke-InforcerApiRequest -Endpoint '/beta/baselines' -Method GET -OutputType PowerShellObject) $baselineGuid = Resolve-InforcerBaselineId -BaselineId $BaselineId -BaselineData $allBaselines foreach ($bl in $allBaselines) { if ($bl.id -eq $baselineGuid) { $baselineFilterName = $bl.name; break } } } if (-not $baselineFilterName) { $baselineFilterName = $BaselineId } # Get alignment details Write-Host ' Retrieving alignment details...' -ForegroundColor Gray $alignEndpoint = "/beta/tenants/$clientTenantId/alignmentDetails?customBaselineId=$baselineGuid" $alignResponse = Invoke-InforcerApiRequest -Endpoint $alignEndpoint -Method GET -OutputType PowerShellObject -ErrorAction SilentlyContinue if ($null -eq $alignResponse) { Write-Warning "Could not retrieve alignment details for baseline '$baselineFilterName'." return $null } # Collect policy names AND GUIDs from baseline alignment status arrays $baselinePolicyNames = [System.Collections.Generic.HashSet[string]]::new([System.StringComparer]::OrdinalIgnoreCase) $baselinePolicyGuids = [System.Collections.Generic.HashSet[string]]::new([System.StringComparer]::OrdinalIgnoreCase) $alignment = $alignResponse.alignment if ($null -ne $alignment) { $baselineArrays = @('matchedPolicies', 'matchedWithAcceptedDeviations', 'deviatedUnaccepted', 'missingFromSubjectUnaccepted') foreach ($arrayName in $baselineArrays) { $arr = $alignment.PSObject.Properties[$arrayName] if ($arr -and $null -ne $arr.Value) { foreach ($p in @($arr.Value)) { if ($p -is [PSObject]) { if ($p.PSObject.Properties['policyName'] -and $p.policyName) { [void]$baselinePolicyNames.Add($p.policyName) } if ($p.PSObject.Properties['policyGuid'] -and $p.policyGuid) { [void]$baselinePolicyGuids.Add($p.policyGuid) } } } } } } $baselineTotal = $baselinePolicyNames.Count if ($baselinePolicyGuids.Count -gt $baselineTotal) { $baselineTotal = $baselinePolicyGuids.Count } if ($baselineTotal -eq 0) { Write-Warning "Baseline '$baselineFilterName' contains no policies in alignment data." return $null } # Filter DocData.Policies in place using multi-field matching chain $originalCount = @($DocData.Policies).Count $DocData.Policies = @($DocData.Policies | Where-Object { foreach ($n in @($_.displayName, $_.friendlyName, $_.name, $_.inforcerPolicyTypeName)) { if (-not [string]::IsNullOrWhiteSpace($n) -and $baselinePolicyNames.Contains($n)) { return $true } } if ($_.policyData) { foreach ($n in @($_.policyData.displayName, $_.policyData.name)) { if (-not [string]::IsNullOrWhiteSpace($n) -and $baselinePolicyNames.Contains($n)) { return $true } } } foreach ($g in @($_.policyGuid, $_.id)) { if (-not [string]::IsNullOrWhiteSpace($g) -and $baselinePolicyGuids.Contains($g)) { return $true } } if ($_.policyData -and $_.policyData.id) { if ($baselinePolicyGuids.Contains($_.policyData.id)) { return $true } } return $false }) $matchedCount = @($DocData.Policies).Count Write-Host " Filtered to $matchedCount of $originalCount policies in baseline '$baselineFilterName'" -ForegroundColor Gray # Warn about unmatched baseline policies if ($matchedCount -lt $baselineTotal) { $matchedNames = [System.Collections.Generic.HashSet[string]]::new([System.StringComparer]::OrdinalIgnoreCase) foreach ($pol in @($DocData.Policies)) { foreach ($n in @($pol.displayName, $pol.friendlyName, $pol.name)) { if (-not [string]::IsNullOrWhiteSpace($n)) { [void]$matchedNames.Add($n) } } if ($pol.policyData) { foreach ($n in @($pol.policyData.displayName, $pol.policyData.name)) { if (-not [string]::IsNullOrWhiteSpace($n)) { [void]$matchedNames.Add($n) } } } } $unmatched = @($baselinePolicyNames | Where-Object { -not $matchedNames.Contains($_) }) if ($unmatched.Count -gt 0) { Write-Warning "$($unmatched.Count) baseline policies not found in tenant:" foreach ($u in $unmatched | Sort-Object) { Write-Warning " - $u" } } } return $baselineFilterName } |