@@ -24,7 +24,7 @@ function Test-Assessment-27000 {
2424 SfiPillar = ' Protect networks' ,
2525 TenantType = (' Workforce' ),
2626 TestId = 27000 ,
27- Title = ' High-risk WCF categories (Criminal activity, Hacking, Illegal software) are blocked ' ,
27+ Title = ' Web content filtering blocks high-risk categories ' ,
2828 UserImpact = ' Low'
2929 )]
3030 [CmdletBinding ()]
@@ -55,6 +55,141 @@ function Test-Assessment-27000 {
5555 }
5656 return $results
5757 }
58+
59+ function Get-CategoryBlockStatus {
60+ <#
61+ . SYNOPSIS
62+ Evaluates whether a specific WCF category is blocked through an effective profile.
63+
64+ . DESCRIPTION
65+ Finds policies covering the category, identifies linked profiles, and determines
66+ the effective profile based on priority and CA enforcement criteria.
67+ #>
68+ param (
69+ [Parameter (Mandatory )]
70+ [string ]$CategoryName ,
71+
72+ [Parameter (Mandatory )]
73+ [string ]$CategoryDisplayName ,
74+
75+ [Parameter (Mandatory )]
76+ [array ]$FilteringPolicies ,
77+
78+ [Parameter (Mandatory )]
79+ [array ]$FilteringProfiles ,
80+
81+ [Parameter (Mandatory )]
82+ [AllowNull ()]
83+ [array ]$CAPolicies ,
84+
85+ [Parameter (Mandatory )]
86+ [int ]$BaselinePriority
87+ )
88+
89+ # Find all policies that cover this category
90+ $policiesCoveringCategory = @ ($FilteringPolicies | Where-Object {
91+ $policy = $_
92+ $webCatRules = @ ($policy.policyRules | Where-Object { $_.ruleType -eq ' webCategory' })
93+ $webCatRules | Where-Object {
94+ $_.destinations | Where-Object { $_.name -eq $CategoryName }
95+ }
96+ })
97+
98+ # Collect profile candidates from all matching policies
99+ $profileCandidates = @ ()
100+ foreach ($policy in $policiesCoveringCategory ) {
101+ $findParams = @ {
102+ PolicyId = $policy.id
103+ FilteringProfiles = $FilteringProfiles
104+ CAPolicies = $CAPolicies
105+ BaselinePriority = $BaselinePriority
106+ PolicyLinkType = ' filteringPolicyLink'
107+ PolicyRules = @ ($policy.policyRules )
108+ }
109+ $linkedProfiles = Find-ZtProfilesLinkedToPolicy @findParams
110+
111+ foreach ($linkedProfile in $linkedProfiles ) {
112+ # Skip disabled profiles
113+ if ($linkedProfile.ProfileState -ne ' enabled' ) {
114+ Write-PSFMessage " Skipping disabled profile '$ ( $linkedProfile.ProfileName ) '" - Level Verbose
115+ continue
116+ }
117+
118+ # Get the profile object to access policies collection
119+ $filteringProfile = $FilteringProfiles | Where-Object { $_.id -eq $linkedProfile.ProfileId }
120+ if (-not $filteringProfile ) {
121+ Write-PSFMessage " Profile '$ ( $linkedProfile.ProfileName ) ' not found in filteringProfiles collection" - Level Warning
122+ continue
123+ }
124+
125+ # Find the policy link to get priority and action
126+ foreach ($policyLink in $filteringProfile.policies ) {
127+ if ($policyLink.policy.id -ne $policy.id ) { continue }
128+
129+ # Skip disabled policy links
130+ if ($policyLink.state -ne ' enabled' ) {
131+ Write-PSFMessage " Skipping disabled policy link in profile '$ ( $linkedProfile.ProfileName ) ' for policy '$ ( $policy.name ) '" - Level Verbose
132+ continue
133+ }
134+
135+ $linkPriority = try { [int ]$policyLink.priority } catch { [int ]::MaxValue }
136+
137+ # Use policy action directly (not overridden at profile level)
138+ $linkAction = if ($policyLink.policy.action ) {
139+ $policyLink.policy.action.ToString ().ToLower()
140+ }
141+ else {
142+ Write-PSFMessage " Policy action is null for policy '$ ( $policy.name ) ' - defaulting to 'unknown'" - Level Warning
143+ ' unknown'
144+ }
145+
146+ $profileCandidates += [PSCustomObject ]@ {
147+ ProfileId = $linkedProfile.ProfileId
148+ ProfileName = $linkedProfile.ProfileName
149+ ProfilePriority = $linkedProfile.ProfilePriority
150+ IsBaseline = ($linkedProfile.ProfileType -eq ' Baseline Profile' )
151+ PolicyAction = $linkAction
152+ PolicyPriority = $linkPriority
153+ PassesCriteria = $linkedProfile.PassesCriteria
154+ }
155+ }
156+ }
157+ }
158+
159+ # Sort by profile priority, then policy priority
160+ $profileCandidates = @ ($profileCandidates | Sort-Object ProfilePriority, PolicyPriority)
161+
162+ # Find effective profile per spec logic
163+ $effectiveProfileName = ' None'
164+ $caEnforced = ' N/A'
165+ $status = ' Not blocked'
166+
167+ foreach ($pc in $profileCandidates ) {
168+ if ($pc.IsBaseline ) {
169+ # Baseline profile is always effective
170+ $effectiveProfileName = $pc.ProfileName
171+ $caEnforced = ' N/A'
172+ $status = if ($pc.PolicyAction -eq ' block' ) { ' Blocked' } else { ' Not blocked' }
173+ break
174+ }
175+ else {
176+ # Security profile - check if it passes CA enforcement criteria
177+ if ($pc.PassesCriteria ) {
178+ $effectiveProfileName = $pc.ProfileName
179+ $caEnforced = ' Yes'
180+ $status = if ($pc.PolicyAction -eq ' block' ) { ' Blocked' } else { ' Not blocked' }
181+ break
182+ }
183+ }
184+ }
185+
186+ return [PSCustomObject ]@ {
187+ Category = $CategoryDisplayName
188+ EnforcedBy = $effectiveProfileName
189+ CAEnforced = $caEnforced
190+ Status = $status
191+ }
192+ }
58193 # endregion Helper Functions
59194
60195 # region Data Collection
@@ -106,122 +241,46 @@ function Test-Assessment-27000 {
106241 $categoryResults = @ ()
107242
108243 if ($errorMsg ) {
244+ # Error occurred during data collection, cannot proceed with assessment -> Fail
109245 Write-PSFMessage " Error during data collection: $errorMsg " - Level Error
110246 $testResultMarkdown = " ❌ Failed to retrieve necessary data for assessment.`n`n Error: $errorMsg "
111247 }
112248 elseif (-not $filteringPolicies -or $filteringPolicies.Count -eq 0 ){
113- Write-PSFMessage " No WCF policies found" - Level Warning
249+ Write-PSFMessage " No WCF policies found -> Fail" - Level Warning
250+ $categoryResults = New-FailedCategoryResults - RequiredCategories $requiredCategories - CategoryDisplayNames $categoryDisplayNames
251+ $blockedCount = 0
252+ $notBlockedCount = $requiredCategories.Count
253+ }
254+ elseif ($filteringPolicies -and $filteringPolicies.count -eq 1 -and $filteringPolicies [0 ].name -eq ' All Websites' ){
255+ Write-PSFMessage " Only default 'All Websites' policy exists -> Fail" - Level Warning
114256 $categoryResults = New-FailedCategoryResults - RequiredCategories $requiredCategories - CategoryDisplayNames $categoryDisplayNames
115257 $blockedCount = 0
116258 $notBlockedCount = $requiredCategories.Count
117259 }
118260 elseif (-not $filteringProfiles -or $filteringProfiles.Count -eq 0 ) {
119- Write-PSFMessage " No filtering profiles found" - Level Warning
261+ Write-PSFMessage " No filtering profiles found -> Fail " - Level Warning
120262 $categoryResults = New-FailedCategoryResults - RequiredCategories $requiredCategories - CategoryDisplayNames $categoryDisplayNames
121263 $blockedCount = 0
122264 $notBlockedCount = $requiredCategories.Count
123265 }
124266 else {
125267 [int ]$BASELINE_PROFILE_PRIORITY = 65000
126268
127- # Evaluate each category
269+ # Evaluate each category using the helper function
128270 foreach ($catName in $requiredCategories ) {
129271 $catDisplay = $categoryDisplayNames [$catName ]
130272
131- # Find all policies that cover this category using filtering
132- $policiesCoveringCategory = @ ($filteringPolicies | Where-Object {
133- $policy = $_
134- $webCatRules = @ ($policy.policyRules | Where-Object { $_.ruleType -eq ' webCategory' })
135- $webCatRules | Where-Object {
136- $_.destinations | Where-Object { $_.name -eq $catName }
137- }
138- })
139-
140- # Find all profiles linked to these policies using Find-ZtProfilesLinkedToPolicy
141- $profileCandidates = @ ()
142- foreach ($policy in $policiesCoveringCategory ) {
143- $findParams = @ {
144- PolicyId = $policy.id
145- FilteringProfiles = $filteringProfiles
146- CAPolicies = $caPolicies
147- BaselinePriority = $BASELINE_PROFILE_PRIORITY
148- PolicyLinkType = ' filteringPolicyLink'
149- PolicyRules = @ ($policy.policyRules )
150- }
151- $linkedProfiles = Find-ZtProfilesLinkedToPolicy @findParams
152-
153- # For each linked profile, get the policy link priority and action
154- foreach ($linkedProfile in $linkedProfiles ) {
155- $filteringProfile = $filteringProfiles | Where-Object { $_.id -eq $linkedProfile.ProfileId }
156- if (-not $filteringProfile -or $filteringProfile.state -ne ' enabled' ) { continue }
157-
158- # Find the policy link and get its priority and action from the expanded policy
159- foreach ($policyLink in $filteringProfile.policies ) {
160- if ($policyLink.policy.id -ne $policy.id ) { continue }
161-
162- # Skip disabled policy links
163- if ($policyLink.state -ne ' enabled' ) {
164- Write-PSFMessage " Skipping disabled policy link in profile '$ ( $filteringProfile.name ) ' for policy '$ ( $policy.name ) '" - Level Verbose
165- continue
166- }
167-
168- $linkPriority = try { [int ]$policyLink.priority } catch { [int ]::MaxValue }
169-
170- # Get action from the expanded policy object
171- $linkAction = if ($policyLink.policy.action ) {
172- $policyLink.policy.action.ToString ().ToLower()
173- }
174- else {
175- # Default to block for WCF policies
176- ' block'
177- }
178-
179- $profileCandidates += [PSCustomObject ]@ {
180- ProfileId = $linkedProfile.ProfileId
181- ProfileName = $linkedProfile.ProfileName
182- ProfilePriority = $linkedProfile.ProfilePriority
183- IsBaseline = ($linkedProfile.ProfileType -eq ' Baseline Profile' )
184- PolicyAction = $linkAction
185- PolicyPriority = $linkPriority
186- PassesCriteria = $linkedProfile.PassesCriteria
187- }
188- }
189- }
190- }
191-
192- # Sort by profile priority, then policy priority
193- $profileCandidates = @ ($profileCandidates | Sort-Object ProfilePriority, PolicyPriority)
194-
195- # Find effective profile per spec logic
196- $effectiveProfileName = ' None'
197- $caEnforced = ' N/A' # Default to N/A when no profile found
198- $status = ' Not blocked'
199-
200- foreach ($pc in $profileCandidates ) {
201- if ($pc.IsBaseline ) {
202- # Baseline profile is always effective
203- $effectiveProfileName = $pc.ProfileName
204- $caEnforced = ' N/A'
205- $status = if ($pc.PolicyAction -eq ' block' ) { ' Blocked' } else { ' Not blocked' }
206- break
207- }
208- else {
209- # Security profile - check if it passes CA enforcement criteria
210- if ($pc.PassesCriteria ) {
211- $effectiveProfileName = $pc.ProfileName
212- $caEnforced = ' Yes'
213- $status = if ($pc.PolicyAction -eq ' block' ) { ' Blocked' } else { ' Not blocked' }
214- break
215- }
216- }
273+ $getCategoryParams = @ {
274+ CategoryName = $catName
275+ CategoryDisplayName = $catDisplay
276+ FilteringPolicies = $filteringPolicies
277+ FilteringProfiles = $filteringProfiles
278+ CAPolicies = $caPolicies
279+ BaselinePriority = $BASELINE_PROFILE_PRIORITY
217280 }
218281
219- $categoryResults += [PSCustomObject ]@ {
220- Category = $catDisplay
221- EnforcedBy = $effectiveProfileName
222- CAEnforced = $caEnforced
223- Status = $status
224- }
282+ $categoryResult = Get-CategoryBlockStatus @getCategoryParams
283+ $categoryResults += $categoryResult
225284 }
226285
227286 # Determine pass/fail
@@ -280,7 +339,7 @@ function Test-Assessment-27000 {
280339
281340 $params = @ {
282341 TestId = ' 27000'
283- Title = ' High-risk WCF categories (Criminal activity, Hacking, Illegal software) are blocked '
342+ Title = ' Web content filtering blocks high-risk categories '
284343 Status = $passed
285344 Result = $testResultMarkdown
286345 }
0 commit comments