From 3ef923bc7d33e64503325da7c2973753e8d4e8f4 Mon Sep 17 00:00:00 2001 From: Komal Date: Mon, 15 Dec 2025 17:39:07 +0530 Subject: [PATCH 01/14] draft 25411 --- .../tests/Test-Assessment.25411.ps1 | 152 ++++++++++++++++++ 1 file changed, 152 insertions(+) create mode 100644 src/powershell/tests/Test-Assessment.25411.ps1 diff --git a/src/powershell/tests/Test-Assessment.25411.ps1 b/src/powershell/tests/Test-Assessment.25411.ps1 new file mode 100644 index 000000000..a30203654 --- /dev/null +++ b/src/powershell/tests/Test-Assessment.25411.ps1 @@ -0,0 +1,152 @@ +<# +.SYNOPSIS + TLS inspection is enabled and correctly configured for outbound traffic in Global Secure Access. +.DESCRIPTION + Verifies that a TLS Inspection policy is properly configured. It will fail if no TLS Inspection policy exists, if the policy is not linked to a Security Profile, or if no Conditional Access policy assigning that Security Profile can be identified. +#> + +function Test-Assessment-25411 { + [ZtTest( + Category = 'Network', + ImplementationCost = 'Low', + MinimumLicense = ('Free'), + Pillar = 'Network', + RiskLevel = 'High', + SfiPillar = 'Protect networks', + TenantType = ('Workforce','External'), + TestId = 25411, + Title = 'TLS inspection is enabled and correctly configured for outbound traffic in Global Secure Access', + UserImpact = 'Low' + )] + [CmdletBinding()] + param() + + + #region Data Collection + Write-PSFMessage '🟦 Start' -Tag Test -Level VeryVerbose + + $activity = 'TLS inspection is enabled and correctly configured for outbound traffic in Global Secure Access.' + Write-ZtProgress -Activity $activity -Status 'Querying TLS inspection policies' + + # Query Q1: Get TLS Inspection policies + $tlsInspectionPolicies = Invoke-ZtGraphRequest -RelativeUri 'networkAccess/tlsInspectionPolicies' -ApiVersion beta + + # Step 2: List all policies in the Baseline Profile and in each Security Profile + Write-ZtProgress -Activity $activity -Status 'Querying filtering profiles and policies' + $filteringProfiles = Invoke-ZtGraphRequest -RelativeUri 'networkAccess/filteringProfiles' -QueryParameters @{ + '$select' = 'id,name,description,state,version,priority' + '$expand' = 'policies($select=id,state;$expand=policy($select=id,name,version)),ConditionalAccessPolicies' + } -ApiVersion beta + + # Query all Conditional Access policies with details + Write-ZtProgress -Activity $activity -Status 'Querying Conditional Access policies' + $allCAPolicies = Invoke-ZtGraphRequest -RelativeUri 'identity/conditionalAccess/policies' -QueryParameters @{ + '$select' = 'id,displayName,state,createdDateTime,modifiedDateTime' + } -ApiVersion beta + + # Initialize test variables + $testResultMarkdown = '' + $passed = $true + #endregion Data Collection + + #region Assessment Logic + if ($null -eq $tlsInspectionPolicies -or $tlsInspectionPolicies.Count -eq 0) { + $testResultMarkdown = '❌ TLS inspection policies are not configured' + $passed = $false + } + + + # Extract TLS inspection policy IDs + $tlsPolicyIds = @() + foreach ($tlsPolicy in $tlsInspectionPolicies) { + $tlsPolicyIds += $tlsPolicy.id + } + #$tlsPolicyIds = @("c363e54f-d24a-46c7-b88d-d9dc8a0eaffe") + + # Search for TLS inspection policy in filtering profiles + $enabledSecurityProfiles = @() + $enabledPolicies = @() + $securityProfile = $filteringProfiles | Where-Object { $_.priority -ne 65000 } + $baseLineProfile = $filteringProfiles | Where-Object { $_.priority -eq 65000 } + foreach ($baseLineProfilePolicy in $baseLineProfile.policies) { + # Check if the policy ID matches a TLS inspection policy + if ($baseLineProfilePolicy.id -in $tlsPolicyIds) { + # Check if the policy state is enabled + if ($baseLineProfilePolicy.state -eq 'enabled') { + $enabledPolicies += [PSCustomObject]@{ + "TLS Profile Id" = $baseLineProfile.id + "TLS Profile Name" = $baseLineProfile.name + "TLS Policy Id" = $baseLineProfilePolicy.policy.id + "TLS Policy Name" = $baseLineProfilePolicy.policy.name + "TLS Policy State" = $baseLineProfilePolicy.state + "TLS Profile State" = $baseLineProfile.state + "TLS Profile Priority" = $baseLineProfile.priority + } + + } + } + } + + foreach ($securityProfileItem in $securityProfile) { + foreach ($securityProfileCAPolicy in $securityProfileItem.ConditionalAccessPolicies) { + $assignedCAPolicy = $allCAPolicies | Where-Object { $_.id -eq $securityProfileCAPolicy.id } + if($true){#($assignedCAPolicy.state -eq 'enabled') { + $enabledSecurityProfiles += [PSCustomObject]@{ + "TLS Profile Id" = $securityProfileItem.id + "TLS Profile Name" = $securityProfileItem.name + "CA Policy Id" = $assignedCAPolicy.id + "Policy Name" = $assignedCAPolicy.displayName + "Policy State" = $assignedCAPolicy.state + "TLS Profile State" = $securityProfileItem.state + "TLS Profile Priority" = $securityProfileItem.priority + } + } + } + } + $securityEnabledProfiles = $enabledSecurityProfiles | where-object { $_.'Policy State' -eq 'enabled' -and $_.'TLS Profile State' -eq 'enabled' } + # Determine test result + if ($enabledPolicies.Count -gt 0 -or $securityEnabledProfiles.Count -gt 0) { + $testResultMarkdown = "✅ TLS inspection policy is enabled and linked to Security Profile(s).`n`n%TestResult%" + $passed = $true + } + else { + $testResultMarkdown = "❌ TLS inspection policy is either not linked to any Security Profile or is not enabled.`n`n%TestResult%" + $passed = $false + } + + #endregion Assessment Logic + + #region Report Generation + $mdInfo = '' + + if ($enabledPolicies.Count -gt 0) { + $mdInfo += "`n## TLS Inspection Policies Linked to Base Line Profiles`n`n" + $mdInfo += "| Profile Name | Policy Name | Policy State | Profile State |`n" + $mdInfo += "| :--- | :--- | :--- | :--- |`n" + foreach ($policy in $enabledPolicies) { + $mdInfo += "| $($policy.'TLS Profile Name') | $($policy.'TLS Policy Name') | $($policy.'TLS Policy State') | $($policy.'TLS Profile State') |`n" + } + } + + if ($enabledSecurityProfiles.Count -gt 0) { + $mdInfo += "`n## Security Profiles Linked to Conditional Access Policies`n`n" + $mdInfo += "| Profile Name | CA Policy Name | CA Policy State | Profile State | Profile Priority |`n" + $mdInfo += "| :--- | :--- | :--- | :--- | :--- |`n" + foreach ($profile in $enabledSecurityProfiles) { + $mdInfo += "| $($profile.'TLS Profile Name') | $($profile.'Policy Name') | $($profile.'Policy State') | $($profile.'TLS Profile State') | $($profile.'TLS Profile Priority') |`n" + } + } + + $testResultMarkdown = $testResultMarkdown -replace '%TestResult%', $mdInfo + #endregion Report Generation + + + $params = @{ + TestId = '25411' + Status = $passed + Result = $testResultMarkdown + } + + # Add test result details + Add-ZtTestResultDetail @params +} From 59b14c18eceabe4af9cc058c06ad0a2ca4ccfd21 Mon Sep 17 00:00:00 2001 From: Komal Date: Tue, 16 Dec 2025 12:06:54 +0530 Subject: [PATCH 02/14] Adding network 25411 --- src/powershell/tests/Test-Assessment.25411.md | 9 ++ .../tests/Test-Assessment.25411.ps1 | 90 ++++++++++--------- 2 files changed, 58 insertions(+), 41 deletions(-) create mode 100644 src/powershell/tests/Test-Assessment.25411.md diff --git a/src/powershell/tests/Test-Assessment.25411.md b/src/powershell/tests/Test-Assessment.25411.md new file mode 100644 index 000000000..2ebf46b3e --- /dev/null +++ b/src/powershell/tests/Test-Assessment.25411.md @@ -0,0 +1,9 @@ +TLS Inspection empowers Microsoft Entra Global Secure Access to securely interpret encrypted traffic, enabling advanced protection. While basic Web Content Filtering works without it, TLS Inspection is required for many Internet Access features like URL Filtering. By decrypting and inspecting TLS sessions, organizations gain deeper visibility and control, ensuring policies are applied effectively to safeguard users and data. + +**Remediation action** + +Please check the article below for guidance on configuring the TLS Inspection Policy. +[Configure Transport Layer Security Inspection Policies - Global Secure Access | Microsoft Learn](https://learn.microsoft.com/en-us/entra/global-secure-access/how-to-transport-layer-security) + + +%TestResult% diff --git a/src/powershell/tests/Test-Assessment.25411.ps1 b/src/powershell/tests/Test-Assessment.25411.ps1 index a30203654..1762efcb4 100644 --- a/src/powershell/tests/Test-Assessment.25411.ps1 +++ b/src/powershell/tests/Test-Assessment.25411.ps1 @@ -8,15 +8,15 @@ function Test-Assessment-25411 { [ZtTest( Category = 'Network', - ImplementationCost = 'Low', + ImplementationCost = 'High', MinimumLicense = ('Free'), Pillar = 'Network', RiskLevel = 'High', SfiPillar = 'Protect networks', - TenantType = ('Workforce','External'), + TenantType = ('Workforce', 'External'), TestId = 25411, Title = 'TLS inspection is enabled and correctly configured for outbound traffic in Global Secure Access', - UserImpact = 'Low' + UserImpact = 'Medium' )] [CmdletBinding()] param() @@ -57,15 +57,11 @@ function Test-Assessment-25411 { # Extract TLS inspection policy IDs - $tlsPolicyIds = @() - foreach ($tlsPolicy in $tlsInspectionPolicies) { - $tlsPolicyIds += $tlsPolicy.id - } - #$tlsPolicyIds = @("c363e54f-d24a-46c7-b88d-d9dc8a0eaffe") + $tlsPolicyIds = [string[]] $tlsInspectionPolicies.id # Search for TLS inspection policy in filtering profiles $enabledSecurityProfiles = @() - $enabledPolicies = @() + $enabledBaseLineProfiles = @() $securityProfile = $filteringProfiles | Where-Object { $_.priority -ne 65000 } $baseLineProfile = $filteringProfiles | Where-Object { $_.priority -eq 65000 } foreach ($baseLineProfilePolicy in $baseLineProfile.policies) { @@ -73,14 +69,14 @@ function Test-Assessment-25411 { if ($baseLineProfilePolicy.id -in $tlsPolicyIds) { # Check if the policy state is enabled if ($baseLineProfilePolicy.state -eq 'enabled') { - $enabledPolicies += [PSCustomObject]@{ - "TLS Profile Id" = $baseLineProfile.id - "TLS Profile Name" = $baseLineProfile.name - "TLS Policy Id" = $baseLineProfilePolicy.policy.id - "TLS Policy Name" = $baseLineProfilePolicy.policy.name - "TLS Policy State" = $baseLineProfilePolicy.state - "TLS Profile State" = $baseLineProfile.state - "TLS Profile Priority" = $baseLineProfile.priority + $enabledBaseLineProfiles += [PSCustomObject]@{ + TLSProfileId = $baseLineProfile.id + TLSProfileName = $baseLineProfile.name + TLSPolicyId = $baseLineProfilePolicy.policy.id + TLSPolicyName = $baseLineProfilePolicy.policy.name + TLSPolicyState = $baseLineProfilePolicy.state + TLSProfileState = $baseLineProfile.state + TLSProfilePriority = $baseLineProfile.priority } } @@ -90,41 +86,52 @@ function Test-Assessment-25411 { foreach ($securityProfileItem in $securityProfile) { foreach ($securityProfileCAPolicy in $securityProfileItem.ConditionalAccessPolicies) { $assignedCAPolicy = $allCAPolicies | Where-Object { $_.id -eq $securityProfileCAPolicy.id } - if($true){#($assignedCAPolicy.state -eq 'enabled') { + if ($null -ne $assignedCAPolicy -and $assignedCAPolicy.state -eq 'enabled') { $enabledSecurityProfiles += [PSCustomObject]@{ - "TLS Profile Id" = $securityProfileItem.id - "TLS Profile Name" = $securityProfileItem.name - "CA Policy Id" = $assignedCAPolicy.id - "Policy Name" = $assignedCAPolicy.displayName - "Policy State" = $assignedCAPolicy.state - "TLS Profile State" = $securityProfileItem.state - "TLS Profile Priority" = $securityProfileItem.priority - } - } + TLSProfileId = $securityProfileItem.id + TLSProfileName = $securityProfileItem.name + CAPolicyId = $assignedCAPolicy.id + CAPolicyName = $assignedCAPolicy.displayName + CAPolicyState = $assignedCAPolicy.state + TLSProfileState = $securityProfileItem.state + TLSProfilePriority = $securityProfileItem.priority + } } } - $securityEnabledProfiles = $enabledSecurityProfiles | where-object { $_.'Policy State' -eq 'enabled' -and $_.'TLS Profile State' -eq 'enabled' } - # Determine test result - if ($enabledPolicies.Count -gt 0 -or $securityEnabledProfiles.Count -gt 0) { - $testResultMarkdown = "✅ TLS inspection policy is enabled and linked to Security Profile(s).`n`n%TestResult%" - $passed = $true - } - else { - $testResultMarkdown = "❌ TLS inspection policy is either not linked to any Security Profile or is not enabled.`n`n%TestResult%" - $passed = $false - } + } + $enabledSecurityProfiles = $enabledSecurityProfiles | where-object { $_.'CAPolicyState' -eq 'enabled' -and $_.'TLSProfileState' -eq 'enabled' } + # Determine test result + if ($enabledBaseLineProfiles.Count -gt 0 -or $enabledSecurityProfiles.Count -gt 0) { + $testResultMarkdown = "✅ TLS inspection policy is enabled and linked to Security Profile(s).`n`n%TestResult%" + $passed = $true + } + else { + $testResultMarkdown = "❌ TLS inspection policy is either not linked to any Security Profile or is not enabled.`n`n%TestResult%" + $passed = $false + } #endregion Assessment Logic #region Report Generation $mdInfo = '' - if ($enabledPolicies.Count -gt 0) { + if ($tlsInspectionPolicies.Count -gt 0) { + $mdInfo += "`n## TLS Inspection Policies`n`n" + $mdInfo += "| Policy ID | Policy Name | State |`n" + $mdInfo += "| :--- | :--- | :--- |`n" + foreach ($tlsPolicy in $tlsInspectionPolicies) { + $mdInfo += "| $($tlsPolicy.id) | $($tlsPolicy.name) | $($tlsPolicy.state) |`n" + } + } + + if ($enabledBaseLineProfiles.Count -gt 0) { + $mdInfo += "`n## TLS Inspection Policies Linked to Base Line Profiles`n`n" $mdInfo += "| Profile Name | Policy Name | Policy State | Profile State |`n" $mdInfo += "| :--- | :--- | :--- | :--- |`n" - foreach ($policy in $enabledPolicies) { - $mdInfo += "| $($policy.'TLS Profile Name') | $($policy.'TLS Policy Name') | $($policy.'TLS Policy State') | $($policy.'TLS Profile State') |`n" + foreach ($policy in $enabledBaseLineProfiles) { + $baseLineProfilePortalLink = "https://entra.microsoft.com/#view/Microsoft_Azure_Network_Access/EditProfileMenuBlade.MenuView/~/basics/profileId/$(($policy.TLSProfileId))" + $mdInfo += "| [$($policy.TLSProfileName)]($baseLineProfilePortalLink) | $($policy.TLSPolicyName) | $($policy.TLSPolicyState) | $($policy.TLSProfileState) |`n" } } @@ -133,7 +140,8 @@ function Test-Assessment-25411 { $mdInfo += "| Profile Name | CA Policy Name | CA Policy State | Profile State | Profile Priority |`n" $mdInfo += "| :--- | :--- | :--- | :--- | :--- |`n" foreach ($profile in $enabledSecurityProfiles) { - $mdInfo += "| $($profile.'TLS Profile Name') | $($profile.'Policy Name') | $($profile.'Policy State') | $($profile.'TLS Profile State') | $($profile.'TLS Profile Priority') |`n" + $securityProfilePortalLink = "https://entra.microsoft.com/#view/Microsoft_Azure_Network_Access/EditProfileMenuBlade.MenuView/~/basics/profileId/$(($profile.TLSProfileId))" + $mdInfo += "| [$($profile.TLSProfileName)]($securityProfilePortalLink) | $($profile.CAPolicyName) | $($profile.CAPolicyState) | $($profile.TLSProfileState) | $($profile.TLSProfilePriority) |`n" } } From 6f2d5b7a7b689d3cc419fe6f36b9360e47df1214 Mon Sep 17 00:00:00 2001 From: Komal Date: Tue, 16 Dec 2025 12:25:48 +0530 Subject: [PATCH 03/14] Adding new property and md formatting --- src/powershell/tests/Test-Assessment.25411.ps1 | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/powershell/tests/Test-Assessment.25411.ps1 b/src/powershell/tests/Test-Assessment.25411.ps1 index 1762efcb4..0703f89d2 100644 --- a/src/powershell/tests/Test-Assessment.25411.ps1 +++ b/src/powershell/tests/Test-Assessment.25411.ps1 @@ -117,10 +117,11 @@ function Test-Assessment-25411 { if ($tlsInspectionPolicies.Count -gt 0) { $mdInfo += "`n## TLS Inspection Policies`n`n" - $mdInfo += "| Policy ID | Policy Name | State |`n" + $mdInfo += "| Policy ID | Policy Name | Action |`n" $mdInfo += "| :--- | :--- | :--- |`n" foreach ($tlsPolicy in $tlsInspectionPolicies) { - $mdInfo += "| $($tlsPolicy.id) | $($tlsPolicy.name) | $($tlsPolicy.state) |`n" + $tlsPolicyPortalLink = "https://entra.microsoft.com/#view/Microsoft_Azure_Network_Access/EditTlsInspectionPolicyMenuBlade.MenuView/~/basics/policyId/$(($tlsPolicy.id))" + $mdInfo += "| [$($tlsPolicy.name)]($tlsPolicyPortalLink) | $($tlsPolicy.id) | $($tlsPolicy.settings.defaultAction) |`n" } } From 05affd283e210f8ee5e704bcb5b99e990c826f6f Mon Sep 17 00:00:00 2001 From: Komal Date: Wed, 17 Dec 2025 11:39:15 +0530 Subject: [PATCH 04/14] add ZtTest info --- src/powershell/tests/Test-Assessment.25411.ps1 | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/powershell/tests/Test-Assessment.25411.ps1 b/src/powershell/tests/Test-Assessment.25411.ps1 index 0703f89d2..31489bd13 100644 --- a/src/powershell/tests/Test-Assessment.25411.ps1 +++ b/src/powershell/tests/Test-Assessment.25411.ps1 @@ -7,13 +7,13 @@ function Test-Assessment-25411 { [ZtTest( - Category = 'Network', + Category = 'Global Secure Access', ImplementationCost = 'High', - MinimumLicense = ('Free'), + MinimumLicense = ('Entra_Premium_Internet_Access'), Pillar = 'Network', RiskLevel = 'High', SfiPillar = 'Protect networks', - TenantType = ('Workforce', 'External'), + TenantType = ('Workforce'), TestId = 25411, Title = 'TLS inspection is enabled and correctly configured for outbound traffic in Global Secure Access', UserImpact = 'Medium' From 6453606535adb016adf1442dd7260b4947aa923a Mon Sep 17 00:00:00 2001 From: Komal Date: Thu, 18 Dec 2025 17:01:39 +0530 Subject: [PATCH 05/14] refactor 25411 --- src/powershell/tests/Test-Assessment.25411.md | 2 +- .../tests/Test-Assessment.25411.ps1 | 44 ++++++++++++------- 2 files changed, 28 insertions(+), 18 deletions(-) diff --git a/src/powershell/tests/Test-Assessment.25411.md b/src/powershell/tests/Test-Assessment.25411.md index 2ebf46b3e..60efcfd51 100644 --- a/src/powershell/tests/Test-Assessment.25411.md +++ b/src/powershell/tests/Test-Assessment.25411.md @@ -3,7 +3,7 @@ TLS Inspection empowers Microsoft Entra Global Secure Access to securely interpr **Remediation action** Please check the article below for guidance on configuring the TLS Inspection Policy. -[Configure Transport Layer Security Inspection Policies - Global Secure Access | Microsoft Learn](https://learn.microsoft.com/en-us/entra/global-secure-access/how-to-transport-layer-security) +- [Configure Transport Layer Security Inspection Policies - Global Secure Access | Microsoft Learn](https://learn.microsoft.com/en-us/entra/global-secure-access/how-to-transport-layer-security) %TestResult% diff --git a/src/powershell/tests/Test-Assessment.25411.ps1 b/src/powershell/tests/Test-Assessment.25411.ps1 index 31489bd13..0ef944a73 100644 --- a/src/powershell/tests/Test-Assessment.25411.ps1 +++ b/src/powershell/tests/Test-Assessment.25411.ps1 @@ -21,6 +21,10 @@ function Test-Assessment-25411 { [CmdletBinding()] param() + #report variable initialization + $testResultMarkdown = '' + $passed = $true + $mdInfo = '' #region Data Collection Write-PSFMessage '🟦 Start' -Tag Test -Level VeryVerbose @@ -40,21 +44,12 @@ function Test-Assessment-25411 { # Query all Conditional Access policies with details Write-ZtProgress -Activity $activity -Status 'Querying Conditional Access policies' - $allCAPolicies = Invoke-ZtGraphRequest -RelativeUri 'identity/conditionalAccess/policies' -QueryParameters @{ - '$select' = 'id,displayName,state,createdDateTime,modifiedDateTime' - } -ApiVersion beta + $allCAPolicies = Get-ZtConditionalAccessPolicy + - # Initialize test variables - $testResultMarkdown = '' - $passed = $true #endregion Data Collection #region Assessment Logic - if ($null -eq $tlsInspectionPolicies -or $tlsInspectionPolicies.Count -eq 0) { - $testResultMarkdown = '❌ TLS inspection policies are not configured' - $passed = $false - } - # Extract TLS inspection policy IDs $tlsPolicyIds = [string[]] $tlsInspectionPolicies.id @@ -101,7 +96,11 @@ function Test-Assessment-25411 { } $enabledSecurityProfiles = $enabledSecurityProfiles | where-object { $_.'CAPolicyState' -eq 'enabled' -and $_.'TLSProfileState' -eq 'enabled' } # Determine test result - if ($enabledBaseLineProfiles.Count -gt 0 -or $enabledSecurityProfiles.Count -gt 0) { + if ($null -eq $tlsInspectionPolicies -or $tlsInspectionPolicies.Count -eq 0) { + $testResultMarkdown = '❌ TLS inspection policies are not configured' + $passed = $false + } + elseif ($enabledBaseLineProfiles.Count -gt 0 -or $enabledSecurityProfiles.Count -gt 0) { $testResultMarkdown = "✅ TLS inspection policy is enabled and linked to Security Profile(s).`n`n%TestResult%" $passed = $true } @@ -113,15 +112,17 @@ function Test-Assessment-25411 { #endregion Assessment Logic #region Report Generation - $mdInfo = '' if ($tlsInspectionPolicies.Count -gt 0) { $mdInfo += "`n## TLS Inspection Policies`n`n" - $mdInfo += "| Policy ID | Policy Name | Action |`n" + $mdInfo += "| Policy Name | Policy ID | Action |`n" $mdInfo += "| :--- | :--- | :--- |`n" foreach ($tlsPolicy in $tlsInspectionPolicies) { $tlsPolicyPortalLink = "https://entra.microsoft.com/#view/Microsoft_Azure_Network_Access/EditTlsInspectionPolicyMenuBlade.MenuView/~/basics/policyId/$(($tlsPolicy.id))" - $mdInfo += "| [$($tlsPolicy.name)]($tlsPolicyPortalLink) | $($tlsPolicy.id) | $($tlsPolicy.settings.defaultAction) |`n" + $policyFullLink = "[$($tlsPolicy.name)]($tlsPolicyPortalLink)" + $tlsPolicyDefaultAction = $tlsPolicy.settings.defaultAction + $tlsPolicyId = $tlsPolicy.id + $mdInfo += "| $policyFullLink | $tlsPolicyId | $tlsPolicyDefaultAction |`n" } } @@ -132,7 +133,11 @@ function Test-Assessment-25411 { $mdInfo += "| :--- | :--- | :--- | :--- |`n" foreach ($policy in $enabledBaseLineProfiles) { $baseLineProfilePortalLink = "https://entra.microsoft.com/#view/Microsoft_Azure_Network_Access/EditProfileMenuBlade.MenuView/~/basics/profileId/$(($policy.TLSProfileId))" - $mdInfo += "| [$($policy.TLSProfileName)]($baseLineProfilePortalLink) | $($policy.TLSPolicyName) | $($policy.TLSPolicyState) | $($policy.TLSProfileState) |`n" + $tlsProfileFullLink = "[$($policy.TLSProfileName)]($baseLineProfilePortalLink)" + $tlsPolicyName = $policy.TLSPolicyName + $tlsPolicyState = $policy.TLSPolicyState + $tlsProfileState = $policy.TLSProfileState + $mdInfo += "| $tlsProfileFullLink | $tlsPolicyName | $tlsPolicyState | $tlsProfileState |`n" } } @@ -142,7 +147,12 @@ function Test-Assessment-25411 { $mdInfo += "| :--- | :--- | :--- | :--- | :--- |`n" foreach ($profile in $enabledSecurityProfiles) { $securityProfilePortalLink = "https://entra.microsoft.com/#view/Microsoft_Azure_Network_Access/EditProfileMenuBlade.MenuView/~/basics/profileId/$(($profile.TLSProfileId))" - $mdInfo += "| [$($profile.TLSProfileName)]($securityProfilePortalLink) | $($profile.CAPolicyName) | $($profile.CAPolicyState) | $($profile.TLSProfileState) | $($profile.TLSProfilePriority) |`n" + $tlsProfileFullLink = "[$($profile.TLSProfileName)]($securityProfilePortalLink)" + $caPolicyName = $profile.CAPolicyName + $caPolicyState = $profile.CAPolicyState + $tlsProfileState = $profile.TLSProfileState + $tlsProfilePriority = $profile.TLSProfilePriority + $mdInfo += "| $tlsProfileFullLink | $caPolicyName | $caPolicyState | $tlsProfileState | $tlsProfilePriority |`n" } } From 50c3739bc5015fd7bd601bde85fb0d5298b3b522 Mon Sep 17 00:00:00 2001 From: Komal Date: Thu, 18 Dec 2025 18:22:51 +0530 Subject: [PATCH 06/14] refactor 25411 --- .../tests/Test-Assessment.25411.ps1 | 62 ++++++++++--------- 1 file changed, 32 insertions(+), 30 deletions(-) diff --git a/src/powershell/tests/Test-Assessment.25411.ps1 b/src/powershell/tests/Test-Assessment.25411.ps1 index 0ef944a73..2419dc189 100644 --- a/src/powershell/tests/Test-Assessment.25411.ps1 +++ b/src/powershell/tests/Test-Assessment.25411.ps1 @@ -21,11 +21,6 @@ function Test-Assessment-25411 { [CmdletBinding()] param() - #report variable initialization - $testResultMarkdown = '' - $passed = $true - $mdInfo = '' - #region Data Collection Write-PSFMessage '🟦 Start' -Tag Test -Level VeryVerbose @@ -49,8 +44,7 @@ function Test-Assessment-25411 { #endregion Data Collection - #region Assessment Logic - + #region Data Processing # Extract TLS inspection policy IDs $tlsPolicyIds = [string[]] $tlsInspectionPolicies.id @@ -79,23 +73,31 @@ function Test-Assessment-25411 { } foreach ($securityProfileItem in $securityProfile) { + $linkedCAPolicies = @() foreach ($securityProfileCAPolicy in $securityProfileItem.ConditionalAccessPolicies) { $assignedCAPolicy = $allCAPolicies | Where-Object { $_.id -eq $securityProfileCAPolicy.id } if ($null -ne $assignedCAPolicy -and $assignedCAPolicy.state -eq 'enabled') { - $enabledSecurityProfiles += [PSCustomObject]@{ - TLSProfileId = $securityProfileItem.id - TLSProfileName = $securityProfileItem.name - CAPolicyId = $assignedCAPolicy.id - CAPolicyName = $assignedCAPolicy.displayName - CAPolicyState = $assignedCAPolicy.state - TLSProfileState = $securityProfileItem.state - TLSProfilePriority = $securityProfileItem.priority - } + $linkedCAPolicies += $assignedCAPolicy.displayName + } + } + if ($linkedCAPolicies.Count -gt 0 -and $securityProfileItem.state -eq 'enabled') { + $enabledSecurityProfiles += [PSCustomObject]@{ + TLSProfileId = $securityProfileItem.id + TLSProfileName = $securityProfileItem.name + CAPolicyNames = $linkedCAPolicies -join ', ' + CAPolicyCount = $linkedCAPolicies.Count + TLSProfileState = $securityProfileItem.state + TLSProfilePriority = $securityProfileItem.priority } } } - $enabledSecurityProfiles = $enabledSecurityProfiles | where-object { $_.'CAPolicyState' -eq 'enabled' -and $_.'TLSProfileState' -eq 'enabled' } - # Determine test result + #endregion Data Processing + #region Assessment logic + + $testResultMarkdown = '' + $passed = $true + $mdInfo = '' + if ($null -eq $tlsInspectionPolicies -or $tlsInspectionPolicies.Count -eq 0) { $testResultMarkdown = '❌ TLS inspection policies are not configured' $passed = $false @@ -105,11 +107,11 @@ function Test-Assessment-25411 { $passed = $true } else { - $testResultMarkdown = "❌ TLS inspection policy is either not linked to any Security Profile or is not enabled.`n`n%TestResult%" + $testResultMarkdown = "❌ TLS inspection policy is not linked to any Security Profile.`n`n%TestResult%" $passed = $false } - #endregion Assessment Logic + #endregion Assessment logic #region Report Generation @@ -119,10 +121,10 @@ function Test-Assessment-25411 { $mdInfo += "| :--- | :--- | :--- |`n" foreach ($tlsPolicy in $tlsInspectionPolicies) { $tlsPolicyPortalLink = "https://entra.microsoft.com/#view/Microsoft_Azure_Network_Access/EditTlsInspectionPolicyMenuBlade.MenuView/~/basics/policyId/$(($tlsPolicy.id))" - $policyFullLink = "[$($tlsPolicy.name)]($tlsPolicyPortalLink)" + $policyName = Get-SafeMarkdown($tlsPolicy.name) $tlsPolicyDefaultAction = $tlsPolicy.settings.defaultAction $tlsPolicyId = $tlsPolicy.id - $mdInfo += "| $policyFullLink | $tlsPolicyId | $tlsPolicyDefaultAction |`n" + $mdInfo += "| [$policyName]($tlsPolicyPortalLink) | $tlsPolicyId | $tlsPolicyDefaultAction |`n" } } @@ -133,26 +135,26 @@ function Test-Assessment-25411 { $mdInfo += "| :--- | :--- | :--- | :--- |`n" foreach ($policy in $enabledBaseLineProfiles) { $baseLineProfilePortalLink = "https://entra.microsoft.com/#view/Microsoft_Azure_Network_Access/EditProfileMenuBlade.MenuView/~/basics/profileId/$(($policy.TLSProfileId))" - $tlsProfileFullLink = "[$($policy.TLSProfileName)]($baseLineProfilePortalLink)" - $tlsPolicyName = $policy.TLSPolicyName + $tlsProfileName = Get-SafeMarkdown($policy.TLSProfileName) + $tlsPolicyName = Get-SafeMarkdown($policy.TLSPolicyName) $tlsPolicyState = $policy.TLSPolicyState $tlsProfileState = $policy.TLSProfileState - $mdInfo += "| $tlsProfileFullLink | $tlsPolicyName | $tlsPolicyState | $tlsProfileState |`n" + $mdInfo += "| [$tlsProfileName]($baseLineProfilePortalLink) | $tlsPolicyName | $tlsPolicyState | $tlsProfileState |`n" } } if ($enabledSecurityProfiles.Count -gt 0) { $mdInfo += "`n## Security Profiles Linked to Conditional Access Policies`n`n" - $mdInfo += "| Profile Name | CA Policy Name | CA Policy State | Profile State | Profile Priority |`n" + $mdInfo += "| Profile Name | CA Policies | CA Policy Count | Profile State | Profile Priority |`n" $mdInfo += "| :--- | :--- | :--- | :--- | :--- |`n" foreach ($profile in $enabledSecurityProfiles) { $securityProfilePortalLink = "https://entra.microsoft.com/#view/Microsoft_Azure_Network_Access/EditProfileMenuBlade.MenuView/~/basics/profileId/$(($profile.TLSProfileId))" - $tlsProfileFullLink = "[$($profile.TLSProfileName)]($securityProfilePortalLink)" - $caPolicyName = $profile.CAPolicyName - $caPolicyState = $profile.CAPolicyState + $tlsProfileName = Get-SafeMarkdown($profile.TLSProfileName) + $caPolicyNames = Get-SafeMarkdown($profile.CAPolicyNames) + $caPolicyCount = $profile.CAPolicyCount $tlsProfileState = $profile.TLSProfileState $tlsProfilePriority = $profile.TLSProfilePriority - $mdInfo += "| $tlsProfileFullLink | $caPolicyName | $caPolicyState | $tlsProfileState | $tlsProfilePriority |`n" + $mdInfo += "| [$tlsProfileName]($securityProfilePortalLink) | $caPolicyNames | $caPolicyCount | $tlsProfileState | $tlsProfilePriority |`n" } } From da5f02a016eed4469f254799b956ff1f290f4b3f Mon Sep 17 00:00:00 2001 From: Komal Date: Mon, 22 Dec 2025 09:39:26 +0530 Subject: [PATCH 07/14] refine spec --- .../tests/Test-Assessment.25411.ps1 | 66 +++++++++++-------- 1 file changed, 37 insertions(+), 29 deletions(-) diff --git a/src/powershell/tests/Test-Assessment.25411.ps1 b/src/powershell/tests/Test-Assessment.25411.ps1 index 2419dc189..28605a9df 100644 --- a/src/powershell/tests/Test-Assessment.25411.ps1 +++ b/src/powershell/tests/Test-Assessment.25411.ps1 @@ -46,48 +46,56 @@ function Test-Assessment-25411 { #region Data Processing # Extract TLS inspection policy IDs - $tlsPolicyIds = [string[]] $tlsInspectionPolicies.id + $tlsPolicyIds = $tlsInspectionPolicies.id # Search for TLS inspection policy in filtering profiles $enabledSecurityProfiles = @() $enabledBaseLineProfiles = @() - $securityProfile = $filteringProfiles | Where-Object { $_.priority -ne 65000 } + $securityProfile = $filteringProfiles | Where-Object { ($_.priority -ne 65000)} $baseLineProfile = $filteringProfiles | Where-Object { $_.priority -eq 65000 } - foreach ($baseLineProfilePolicy in $baseLineProfile.policies) { + foreach ($baseLineProfilePolicy in @($baseLineProfile.policies)) { # Check if the policy ID matches a TLS inspection policy - if ($baseLineProfilePolicy.id -in $tlsPolicyIds) { - # Check if the policy state is enabled - if ($baseLineProfilePolicy.state -eq 'enabled') { - $enabledBaseLineProfiles += [PSCustomObject]@{ - TLSProfileId = $baseLineProfile.id - TLSProfileName = $baseLineProfile.name - TLSPolicyId = $baseLineProfilePolicy.policy.id - TLSPolicyName = $baseLineProfilePolicy.policy.name - TLSPolicyState = $baseLineProfilePolicy.state - TLSProfileState = $baseLineProfile.state - TLSProfilePriority = $baseLineProfile.priority - } - + if ($null -ne $baseLineProfilePolicy -and $baseLineProfilePolicy.policy.id -in @($tlsPolicyIds) -and $baseLineProfilePolicy.state -eq 'enabled') { + $enabledBaseLineProfiles += [PSCustomObject]@{ + TLSProfileId = $baseLineProfile.id + TLSProfileName = $baseLineProfile.name + TLSPolicyId = $baseLineProfilePolicy.policy.id + TLSPolicyName = $baseLineProfilePolicy.policy.name + TLSPolicyState = $baseLineProfilePolicy.state + TLSProfileState = $baseLineProfile.state + TLSProfilePriority = $baseLineProfile.priority } } } foreach ($securityProfileItem in $securityProfile) { - $linkedCAPolicies = @() - foreach ($securityProfileCAPolicy in $securityProfileItem.ConditionalAccessPolicies) { - $assignedCAPolicy = $allCAPolicies | Where-Object { $_.id -eq $securityProfileCAPolicy.id } - if ($null -ne $assignedCAPolicy -and $assignedCAPolicy.state -eq 'enabled') { - $linkedCAPolicies += $assignedCAPolicy.displayName + # Check if the security profile contains a TLS inspection policy + $hasTlsPolicy = $false + foreach ($securityProfilePolicy in $securityProfileItem.policies) { + if ($securityProfilePolicy.policy.id -in @($tlsPolicyIds) -and $securityProfilePolicy.state -eq 'enabled') { + $hasTlsPolicy = $true + break } } - if ($linkedCAPolicies.Count -gt 0 -and $securityProfileItem.state -eq 'enabled') { - $enabledSecurityProfiles += [PSCustomObject]@{ - TLSProfileId = $securityProfileItem.id - TLSProfileName = $securityProfileItem.name - CAPolicyNames = $linkedCAPolicies -join ', ' - CAPolicyCount = $linkedCAPolicies.Count - TLSProfileState = $securityProfileItem.state - TLSProfilePriority = $securityProfileItem.priority + + # Only process if the security profile has an enabled TLS inspection policy + if ($hasTlsPolicy) { + $linkedCAPolicies = @() + foreach ($securityProfileCAPolicy in $securityProfileItem.ConditionalAccessPolicies) { + $assignedCAPolicy = $allCAPolicies | Where-Object { $_.id -eq $securityProfileCAPolicy.id } + if ($null -ne $assignedCAPolicy -and $assignedCAPolicy.state -eq 'enabled') { + $linkedCAPolicies += $assignedCAPolicy.displayName + } + } + if ($linkedCAPolicies.Count -gt 0 -and $securityProfileItem.state -eq 'enabled') { + $enabledSecurityProfiles += [PSCustomObject]@{ + TLSProfileId = $securityProfileItem.id + TLSProfileName = $securityProfileItem.name + CAPolicyNames = $linkedCAPolicies -join ', ' + CAPolicyCount = $linkedCAPolicies.Count + TLSProfileState = $securityProfileItem.state + TLSProfilePriority = $securityProfileItem.priority + } } } } From 9ca20d407efc840429c088ea4f1ffb8380975f5b Mon Sep 17 00:00:00 2001 From: Komal Date: Tue, 30 Dec 2025 23:03:54 +0530 Subject: [PATCH 08/14] draft changes --- .../tests/Test-Assessment.25411.ps1 | 127 +++++++++++------- 1 file changed, 79 insertions(+), 48 deletions(-) diff --git a/src/powershell/tests/Test-Assessment.25411.ps1 b/src/powershell/tests/Test-Assessment.25411.ps1 index 28605a9df..296bdd541 100644 --- a/src/powershell/tests/Test-Assessment.25411.ps1 +++ b/src/powershell/tests/Test-Assessment.25411.ps1 @@ -5,6 +5,38 @@ Verifies that a TLS Inspection policy is properly configured. It will fail if no TLS Inspection policy exists, if the policy is not linked to a Security Profile, or if no Conditional Access policy assigning that Security Profile can be identified. #> +#region Helper functions +function Get-ProfileType { + param ( + $Priority + ) + if ($null -eq $Priority) { + return 'NA' + } + if ($Priority -eq 65000) { + return "Baseline Profile" + } + if ($Priority -lt 65000) { + return "Security Profile" + } +} + +function Get-DefaultAction { + param ( + $TLSPolicies, + $TLSPolicyID + ) + $TLSPolicy = $TLSPolicies | Where-Object { $_.id -eq $TLSPolicyID } + if ($null -ne $TLSPolicy) { + return $TLSPolicy.settings.defaultAction + } + else { + return 'NA' + } +} + +#endregion Helper functions + function Test-Assessment-25411 { [ZtTest( Category = 'Global Secure Access', @@ -51,53 +83,51 @@ function Test-Assessment-25411 { # Search for TLS inspection policy in filtering profiles $enabledSecurityProfiles = @() $enabledBaseLineProfiles = @() - $securityProfile = $filteringProfiles | Where-Object { ($_.priority -ne 65000)} - $baseLineProfile = $filteringProfiles | Where-Object { $_.priority -eq 65000 } - foreach ($baseLineProfilePolicy in @($baseLineProfile.policies)) { - # Check if the policy ID matches a TLS inspection policy - if ($null -ne $baseLineProfilePolicy -and $baseLineProfilePolicy.policy.id -in @($tlsPolicyIds) -and $baseLineProfilePolicy.state -eq 'enabled') { - $enabledBaseLineProfiles += [PSCustomObject]@{ - TLSProfileId = $baseLineProfile.id - TLSProfileName = $baseLineProfile.name - TLSPolicyId = $baseLineProfilePolicy.policy.id - TLSPolicyName = $baseLineProfilePolicy.policy.name - TLSPolicyState = $baseLineProfilePolicy.state - TLSProfileState = $baseLineProfile.state - TLSProfilePriority = $baseLineProfile.priority + $securityProfile = $filteringProfiles | Where-Object { ($_.priority -lt 65000) } + $baseLineProfiles = $filteringProfiles | Where-Object { $_.priority -eq 65000 } + <#foreach ($baseLineProfileItem in $baseLineProfiles) { + foreach ($baseLineProfilePolicy in @($baseLineProfileItem.policies)) { + # Check if the policy ID matches a TLS inspection policy + if ($baseLineProfilePolicy.'@odata.type' -like '*filtering*') { + $enabledBaseLineProfiles += [PSCustomObject]@{ + ProfileId = $baseLineProfileItem.id + ProfileName = $baseLineProfileItem.name + TLSPolicyId = $baseLineProfilePolicy.policy.id + TLSPolicyName = $baseLineProfilePolicy.policy.name + TLSPolicyState = $baseLineProfilePolicy.state + ProfileState = $baseLineProfileItem.state + ProfilePriority = $baseLineProfileItem.priority + ProfileType = Get-ProfileType -Priority $baseLineProfileItem.priority + } } } - } + }#> - foreach ($securityProfileItem in $securityProfile) { + foreach ($securityProfileItem in $filteringProfiles) { # Check if the security profile contains a TLS inspection policy - $hasTlsPolicy = $false foreach ($securityProfilePolicy in $securityProfileItem.policies) { - if ($securityProfilePolicy.policy.id -in @($tlsPolicyIds) -and $securityProfilePolicy.state -eq 'enabled') { - $hasTlsPolicy = $true - break - } - } - - # Only process if the security profile has an enabled TLS inspection policy - if ($hasTlsPolicy) { $linkedCAPolicies = @() - foreach ($securityProfileCAPolicy in $securityProfileItem.ConditionalAccessPolicies) { - $assignedCAPolicy = $allCAPolicies | Where-Object { $_.id -eq $securityProfileCAPolicy.id } + if ($securityProfilePolicy.'@odata.type' -like '*tlsInspectionPolicyLink*') { + $assignedCAPolicy = $allCAPolicies | Where-Object { $_.id -in @($securityProfileItem.ConditionalAccessPolicies.id) } if ($null -ne $assignedCAPolicy -and $assignedCAPolicy.state -eq 'enabled') { - $linkedCAPolicies += $assignedCAPolicy.displayName + $linkedCAPolicies = $assignedCAPolicy.displayName } - } - if ($linkedCAPolicies.Count -gt 0 -and $securityProfileItem.state -eq 'enabled') { - $enabledSecurityProfiles += [PSCustomObject]@{ - TLSProfileId = $securityProfileItem.id - TLSProfileName = $securityProfileItem.name - CAPolicyNames = $linkedCAPolicies -join ', ' - CAPolicyCount = $linkedCAPolicies.Count - TLSProfileState = $securityProfileItem.state - TLSProfilePriority = $securityProfileItem.priority + if ($linkedCAPolicies.Count -gt 0 -and $securityProfileItem.state -eq 'enabled') { + $enabledSecurityProfiles += [PSCustomObject]@{ + ProfileId = $securityProfileItem.id + ProfileName = $securityProfileItem.name + CAPolicyNames = $linkedCAPolicies -join ', ' + CAPolicyCount = $linkedCAPolicies.Count + ProfileState = $securityProfileItem.state + ProfilePriority = $securityProfileItem.priority + ProfileType = Get-ProfileType -Priority $securityProfileItem.priority + TLSInspectionPolicyName = $securityProfilePolicy.policy.name + DefaultAction = Get-DefaultAction -TLSPolicies $tlsInspectionPolicies -TLSPolicyID $securityProfilePolicy.policy.id + } } } } + } #endregion Data Processing #region Assessment logic @@ -139,30 +169,31 @@ function Test-Assessment-25411 { if ($enabledBaseLineProfiles.Count -gt 0) { $mdInfo += "`n## TLS Inspection Policies Linked to Base Line Profiles`n`n" - $mdInfo += "| Profile Name | Policy Name | Policy State | Profile State |`n" + $mdInfo += "| Profile Name | Policy Name | Policy State | Profile State | TLS Inspection Policy Name|`n" $mdInfo += "| :--- | :--- | :--- | :--- |`n" foreach ($policy in $enabledBaseLineProfiles) { - $baseLineProfilePortalLink = "https://entra.microsoft.com/#view/Microsoft_Azure_Network_Access/EditProfileMenuBlade.MenuView/~/basics/profileId/$(($policy.TLSProfileId))" - $tlsProfileName = Get-SafeMarkdown($policy.TLSProfileName) + $baseLineProfilePortalLink = "https://entra.microsoft.com/#view/Microsoft_Azure_Network_Access/EditProfileMenuBlade.MenuView/~/basics/profileId/$(($policy.ProfileId))" + $ProfileName = Get-SafeMarkdown($policy.ProfileName) $tlsPolicyName = Get-SafeMarkdown($policy.TLSPolicyName) $tlsPolicyState = $policy.TLSPolicyState - $tlsProfileState = $policy.TLSProfileState - $mdInfo += "| [$tlsProfileName]($baseLineProfilePortalLink) | $tlsPolicyName | $tlsPolicyState | $tlsProfileState |`n" + $ProfileState = $policy.ProfileState + $mdInfo += "| [$ProfileName]($baseLineProfilePortalLink) | $tlsPolicyName | $tlsPolicyState | $ProfileState |`n" } } if ($enabledSecurityProfiles.Count -gt 0) { $mdInfo += "`n## Security Profiles Linked to Conditional Access Policies`n`n" - $mdInfo += "| Profile Name | CA Policies | CA Policy Count | Profile State | Profile Priority |`n" + $mdInfo += "| Profile Name | CA Policies | Profile State | TLS Inspection Policy Name | Default Action |`n" $mdInfo += "| :--- | :--- | :--- | :--- | :--- |`n" foreach ($profile in $enabledSecurityProfiles) { - $securityProfilePortalLink = "https://entra.microsoft.com/#view/Microsoft_Azure_Network_Access/EditProfileMenuBlade.MenuView/~/basics/profileId/$(($profile.TLSProfileId))" - $tlsProfileName = Get-SafeMarkdown($profile.TLSProfileName) + $securityProfilePortalLink = "https://entra.microsoft.com/#view/Microsoft_Azure_Network_Access/EditProfileMenuBlade.MenuView/~/basics/profileId/$(($profile.ProfileId))" + $ProfileName = Get-SafeMarkdown($profile.ProfileName) $caPolicyNames = Get-SafeMarkdown($profile.CAPolicyNames) - $caPolicyCount = $profile.CAPolicyCount - $tlsProfileState = $profile.TLSProfileState - $tlsProfilePriority = $profile.TLSProfilePriority - $mdInfo += "| [$tlsProfileName]($securityProfilePortalLink) | $caPolicyNames | $caPolicyCount | $tlsProfileState | $tlsProfilePriority |`n" + $ProfileState = $profile.ProfileState + $ProfilePriority = $profile.ProfilePriority + $TlsPolicyName = Get-SafeMarkdown($profile.TLSInspectionPolicyName) + $DefaultAction = $profile.DefaultAction + $mdInfo += "| [$ProfileName]($securityProfilePortalLink) | $caPolicyNames | $ProfileState | $TlsPolicyName | $DefaultAction |`n" } } From ec51c34546f09616c9425633523f5726362c4729 Mon Sep 17 00:00:00 2001 From: Komal Date: Wed, 31 Dec 2025 11:54:39 +0530 Subject: [PATCH 09/14] draft --- src/powershell/tests/Test-Assessment.25411.ps1 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/powershell/tests/Test-Assessment.25411.ps1 b/src/powershell/tests/Test-Assessment.25411.ps1 index 296bdd541..89a4c460e 100644 --- a/src/powershell/tests/Test-Assessment.25411.ps1 +++ b/src/powershell/tests/Test-Assessment.25411.ps1 @@ -107,7 +107,7 @@ function Test-Assessment-25411 { # Check if the security profile contains a TLS inspection policy foreach ($securityProfilePolicy in $securityProfileItem.policies) { $linkedCAPolicies = @() - if ($securityProfilePolicy.'@odata.type' -like '*tlsInspectionPolicyLink*') { + if ($securityProfilePolicy.'@odata.type' -like '*tlsInspectionPolicyLink*' -or $securityProfilePolicy.'@odata.type' -like '*forwarding*') { $assignedCAPolicy = $allCAPolicies | Where-Object { $_.id -in @($securityProfileItem.ConditionalAccessPolicies.id) } if ($null -ne $assignedCAPolicy -and $assignedCAPolicy.state -eq 'enabled') { $linkedCAPolicies = $assignedCAPolicy.displayName From bf28353f3429cac22e2b65b35c948fdc180db557 Mon Sep 17 00:00:00 2001 From: Komal Date: Fri, 2 Jan 2026 13:05:26 +0530 Subject: [PATCH 10/14] refined spec --- .../tests/Test-Assessment.25411.ps1 | 240 ++++++++++-------- 1 file changed, 135 insertions(+), 105 deletions(-) diff --git a/src/powershell/tests/Test-Assessment.25411.ps1 b/src/powershell/tests/Test-Assessment.25411.ps1 index 89a4c460e..c7a1482e5 100644 --- a/src/powershell/tests/Test-Assessment.25411.ps1 +++ b/src/powershell/tests/Test-Assessment.25411.ps1 @@ -5,38 +5,6 @@ Verifies that a TLS Inspection policy is properly configured. It will fail if no TLS Inspection policy exists, if the policy is not linked to a Security Profile, or if no Conditional Access policy assigning that Security Profile can be identified. #> -#region Helper functions -function Get-ProfileType { - param ( - $Priority - ) - if ($null -eq $Priority) { - return 'NA' - } - if ($Priority -eq 65000) { - return "Baseline Profile" - } - if ($Priority -lt 65000) { - return "Security Profile" - } -} - -function Get-DefaultAction { - param ( - $TLSPolicies, - $TLSPolicyID - ) - $TLSPolicy = $TLSPolicies | Where-Object { $_.id -eq $TLSPolicyID } - if ($null -ne $TLSPolicy) { - return $TLSPolicy.settings.defaultAction - } - else { - return 'NA' - } -} - -#endregion Helper functions - function Test-Assessment-25411 { [ZtTest( Category = 'Global Secure Access', @@ -66,7 +34,7 @@ function Test-Assessment-25411 { Write-ZtProgress -Activity $activity -Status 'Querying filtering profiles and policies' $filteringProfiles = Invoke-ZtGraphRequest -RelativeUri 'networkAccess/filteringProfiles' -QueryParameters @{ '$select' = 'id,name,description,state,version,priority' - '$expand' = 'policies($select=id,state;$expand=policy($select=id,name,version)),ConditionalAccessPolicies' + '$expand' = 'policies($select=id,state;$expand=policy($select=id,name,version)),conditionalAccessPolicies($select=id,displayName)' } -ApiVersion beta # Query all Conditional Access policies with details @@ -77,75 +45,136 @@ function Test-Assessment-25411 { #endregion Data Collection #region Data Processing - # Extract TLS inspection policy IDs - $tlsPolicyIds = $tlsInspectionPolicies.id - - # Search for TLS inspection policy in filtering profiles + # Graph responses are automatically unwrapped by Invoke-ZtGraphRequest $enabledSecurityProfiles = @() $enabledBaseLineProfiles = @() - $securityProfile = $filteringProfiles | Where-Object { ($_.priority -lt 65000) } - $baseLineProfiles = $filteringProfiles | Where-Object { $_.priority -eq 65000 } - <#foreach ($baseLineProfileItem in $baseLineProfiles) { - foreach ($baseLineProfilePolicy in @($baseLineProfileItem.policies)) { - # Check if the policy ID matches a TLS inspection policy - if ($baseLineProfilePolicy.'@odata.type' -like '*filtering*') { - $enabledBaseLineProfiles += [PSCustomObject]@{ - ProfileId = $baseLineProfileItem.id - ProfileName = $baseLineProfileItem.name - TLSPolicyId = $baseLineProfilePolicy.policy.id - TLSPolicyName = $baseLineProfilePolicy.policy.name - TLSPolicyState = $baseLineProfilePolicy.state - ProfileState = $baseLineProfileItem.state - ProfilePriority = $baseLineProfileItem.priority - ProfileType = Get-ProfileType -Priority $baseLineProfileItem.priority - } + + # Iterate each TLS inspection policy and find linked profiles + foreach ($tlsPolicy in $tlsInspectionPolicies) { + $tlsId = $tlsPolicy.id + $tlsPolicyLinked = $false + $baselineProfileFound = $false + foreach ($profile in $filteringProfiles) { + $profilePolicies = @() + if ($null -ne $profile.policies) { + $profilePolicies = $profile.policies } - } - }#> - - foreach ($securityProfileItem in $filteringProfiles) { - # Check if the security profile contains a TLS inspection policy - foreach ($securityProfilePolicy in $securityProfileItem.policies) { - $linkedCAPolicies = @() - if ($securityProfilePolicy.'@odata.type' -like '*tlsInspectionPolicyLink*' -or $securityProfilePolicy.'@odata.type' -like '*forwarding*') { - $assignedCAPolicy = $allCAPolicies | Where-Object { $_.id -in @($securityProfileItem.ConditionalAccessPolicies.id) } - if ($null -ne $assignedCAPolicy -and $assignedCAPolicy.state -eq 'enabled') { - $linkedCAPolicies = $assignedCAPolicy.displayName + + foreach ($plink in $profilePolicies) { + $plinkType = $plink.'@odata.type' + $linkedPolicyId = $null + # Only process tlsInspectionPolicyLink entries + if ($plinkType -eq '#microsoft.graph.networkaccess.tlsInspectionPolicyLink' -and $null -ne $plink.policy) { + $linkedPolicyId = $plink.policy.id } - if ($linkedCAPolicies.Count -gt 0 -and $securityProfileItem.state -eq 'enabled') { - $enabledSecurityProfiles += [PSCustomObject]@{ - ProfileId = $securityProfileItem.id - ProfileName = $securityProfileItem.name - CAPolicyNames = $linkedCAPolicies -join ', ' - CAPolicyCount = $linkedCAPolicies.Count - ProfileState = $securityProfileItem.state - ProfilePriority = $securityProfileItem.priority - ProfileType = Get-ProfileType -Priority $securityProfileItem.priority - TLSInspectionPolicyName = $securityProfilePolicy.policy.name - DefaultAction = Get-DefaultAction -TLSPolicies $tlsInspectionPolicies -TLSPolicyID $securityProfilePolicy.policy.id + + if ($null -ne $linkedPolicyId -and $linkedPolicyId -eq $tlsId) { + $tlsPolicyLinked = $true + $linkState = if ($null -ne $plink.state) { + $plink.state + } + else { + 'unknown' + } + $profileState = if ($null -ne $profile.state) { + $profile.state + } + else { + 'unknown' + } + $priority = if ($null -ne $profile.priority) { + [int]$profile.priority + } + else { + $null + } + + if ($priority -eq 65000) { + # Baseline Profile: apply without CA + + if ($linkState -eq 'enabled' -and $profileState -eq 'enabled') { + $baselineProfileFound = $true + $enabledBaseLineProfiles += [PSCustomObject]@{ + ProfileId = $profile.id + ProfileName = $profile.name + ProfileState = $profileState + ProfilePriority = $priority + TLSPolicyId = $tlsId + TLSPolicyName = $plink.policy.name + TLSPolicyLinkState = $linkState + } + break + } + } elseif ($null -ne $priority -and $priority -lt 65000) { + # Security Profile: must be applied via Conditional Access + # Validate CA policies reference this profile via sessionControls + $matchedCAPolicies = @() + foreach ($cap in $allCAPolicies) { + $session = $cap.sessionControls + if ($null -ne $session -and $null -ne $session.globalSecureAccessFilteringProfile) { + $sessionProfileId = $session.globalSecureAccessFilteringProfile.profileId + $sessionEnabled = $session.globalSecureAccessFilteringProfile.isEnabled + if ($sessionProfileId -eq $profile.id -and $sessionEnabled -eq $true -and $cap.state -eq 'enabled') { + $matchedCAPolicies += [PSCustomObject]@{ + Id = $cap.id + DisplayName = $cap.displayName + State = $cap.state + } + } + } + } + + if ($matchedCAPolicies.Count -gt 0 -and $profileState -eq 'enabled' -and $linkState -eq 'enabled') { + $enabledSecurityProfiles += [PSCustomObject]@{ + ProfileId = $profile.id + ProfileName = $profile.name + ProfileState = $profileState + ProfilePriority = $priority + TLSPolicyId = $tlsId + TLSPolicyName = $plink.policy.name + TLSPolicyLinkState = $linkState + CAPolicyNames = ($matchedCAPolicies | Select-Object -ExpandProperty DisplayName) -join ', ' + CAPolicyIds = ($matchedCAPolicies | Select-Object -ExpandProperty Id) -join ', ' + CAPolicyStates = ($matchedCAPolicies | Select-Object -ExpandProperty State) -join ', ' + CAPolicyCount = $matchedCAPolicies.Count + DefaultAction = if ($null -ne $tlsPolicy.settings) { + $tlsPolicy.settings.defaultAction + } + else { + 'unknown' + } + } + } } } } + if ($baselineProfileFound) { + break + } } - } + #endregion Data Processing #region Assessment logic $testResultMarkdown = '' - $passed = $true + $passed = $false $mdInfo = '' if ($null -eq $tlsInspectionPolicies -or $tlsInspectionPolicies.Count -eq 0) { - $testResultMarkdown = '❌ TLS inspection policies are not configured' + $testResultMarkdown = "❌ TLS inspection policies are not configured`n`n%TestResult%" $passed = $false } - elseif ($enabledBaseLineProfiles.Count -gt 0 -or $enabledSecurityProfiles.Count -gt 0) { - $testResultMarkdown = "✅ TLS inspection policy is enabled and linked to Security Profile(s).`n`n%TestResult%" + elseif ($enabledBaseLineProfiles.Count -gt 0) { + $testResultMarkdown = "✅ TLS inspection policy is applied via Baseline Profile(s).`n`n%TestResult%" + $passed = $true + } + elseif ($enabledSecurityProfiles.Count -gt 0) { + $testResultMarkdown = "✅ TLS inspection policy is applied via Security Profile(s) enforced through Conditional Access.`n`n%TestResult%" $passed = $true } else { - $testResultMarkdown = "❌ TLS inspection policy is not linked to any Security Profile.`n`n%TestResult%" + $testResultMarkdown = "❌ TLS inspection policy is not linked to any enabled Baseline or CA-enforced Security Profile.`n`n%TestResult%" $passed = $false } @@ -153,47 +182,48 @@ function Test-Assessment-25411 { #region Report Generation - if ($tlsInspectionPolicies.Count -gt 0) { - $mdInfo += "`n## TLS Inspection Policies`n`n" - $mdInfo += "| Policy Name | Policy ID | Action |`n" - $mdInfo += "| :--- | :--- | :--- |`n" - foreach ($tlsPolicy in $tlsInspectionPolicies) { - $tlsPolicyPortalLink = "https://entra.microsoft.com/#view/Microsoft_Azure_Network_Access/EditTlsInspectionPolicyMenuBlade.MenuView/~/basics/policyId/$(($tlsPolicy.id))" - $policyName = Get-SafeMarkdown($tlsPolicy.name) - $tlsPolicyDefaultAction = $tlsPolicy.settings.defaultAction - $tlsPolicyId = $tlsPolicy.id - $mdInfo += "| [$policyName]($tlsPolicyPortalLink) | $tlsPolicyId | $tlsPolicyDefaultAction |`n" - } - } - if ($enabledBaseLineProfiles.Count -gt 0) { - $mdInfo += "`n## TLS Inspection Policies Linked to Base Line Profiles`n`n" - $mdInfo += "| Profile Name | Policy Name | Policy State | Profile State | TLS Inspection Policy Name|`n" - $mdInfo += "| :--- | :--- | :--- | :--- |`n" + $mdInfo += "`n## TLS Inspection Policies Linked to Baseline Profiles`n`n" + $mdInfo += "| Linked Profile Name | Linked Profile Priority | Linked Policy Name | Policy Link State | Profile State |`n" + $mdInfo += "| :--- | :--- | :--- | :--- | :--- |`n" foreach ($policy in $enabledBaseLineProfiles) { $baseLineProfilePortalLink = "https://entra.microsoft.com/#view/Microsoft_Azure_Network_Access/EditProfileMenuBlade.MenuView/~/basics/profileId/$(($policy.ProfileId))" + $tlsPolicyPortalLink = "https://entra.microsoft.com/#view/Microsoft_Azure_Network_Access/EditTlsInspectionPolicyMenuBlade.MenuView/~/basics/policyId/$(($policy.TLSPolicyId))" $ProfileName = Get-SafeMarkdown($policy.ProfileName) + $ProfilePriority = $policy.ProfilePriority $tlsPolicyName = Get-SafeMarkdown($policy.TLSPolicyName) - $tlsPolicyState = $policy.TLSPolicyState + $tlsPolicyLinkState = $policy.TLSPolicyLinkState $ProfileState = $policy.ProfileState - $mdInfo += "| [$ProfileName]($baseLineProfilePortalLink) | $tlsPolicyName | $tlsPolicyState | $ProfileState |`n" + $mdInfo += "| [$ProfileName]($baseLineProfilePortalLink) | $ProfilePriority | [$tlsPolicyName]($tlsPolicyPortalLink) | $tlsPolicyLinkState | $ProfileState |`n" } } if ($enabledSecurityProfiles.Count -gt 0) { $mdInfo += "`n## Security Profiles Linked to Conditional Access Policies`n`n" - $mdInfo += "| Profile Name | CA Policies | Profile State | TLS Inspection Policy Name | Default Action |`n" - $mdInfo += "| :--- | :--- | :--- | :--- | :--- |`n" + $mdInfo += "| Linked Profile Name | Linked Profile Priority | CA Policy Names | CA Policy State | Profile State | TLS Inspection Policy Name | Default Action |`n" + $mdInfo += "| :--- | :--- | :--- | :--- | :--- | :--- | :--- |`n" foreach ($profile in $enabledSecurityProfiles) { $securityProfilePortalLink = "https://entra.microsoft.com/#view/Microsoft_Azure_Network_Access/EditProfileMenuBlade.MenuView/~/basics/profileId/$(($profile.ProfileId))" + $tlsPolicyPortalLink = "https://entra.microsoft.com/#view/Microsoft_Azure_Network_Access/EditTlsInspectionPolicyMenuBlade.MenuView/~/basics/policyId/$(($profile.TLSPolicyId))" $ProfileName = Get-SafeMarkdown($profile.ProfileName) - $caPolicyNames = Get-SafeMarkdown($profile.CAPolicyNames) - $ProfileState = $profile.ProfileState $ProfilePriority = $profile.ProfilePriority - $TlsPolicyName = Get-SafeMarkdown($profile.TLSInspectionPolicyName) + + # Build CA policy links + $caNames = $profile.CAPolicyNames -split ', ' + $caIds = $profile.CAPolicyIds -split ', ' + $caPolicyLinksMarkdown = @() + for ($i = 0; $i -lt $caNames.Count; $i++) { + $caPolicyPortalLink = "https://entra.microsoft.com/#view/Microsoft_Azure_Intune_Actions/ConditionalAccessBlade/~/Policies/$($caIds[$i].Trim())" + $safeName = Get-SafeMarkdown($caNames[$i]) + $caPolicyLinksMarkdown += "[$safeName]($caPolicyPortalLink)" + } + $caPolicyNamesLinked = $caPolicyLinksMarkdown -join ', ' + $caPolicyStates = Get-SafeMarkdown($profile.CAPolicyStates) + $ProfileState = $profile.ProfileState + $TlsPolicyName = Get-SafeMarkdown($profile.TLSPolicyName) $DefaultAction = $profile.DefaultAction - $mdInfo += "| [$ProfileName]($securityProfilePortalLink) | $caPolicyNames | $ProfileState | $TlsPolicyName | $DefaultAction |`n" + $mdInfo += "| [$ProfileName]($securityProfilePortalLink) | $ProfilePriority | $caPolicyNamesLinked | $caPolicyStates | $ProfileState | [$TlsPolicyName]($tlsPolicyPortalLink) | $DefaultAction |`n" } } From cec730ebee5f68d42321e75d068a1e2f63896eeb Mon Sep 17 00:00:00 2001 From: Komal Date: Mon, 5 Jan 2026 17:07:29 +0530 Subject: [PATCH 11/14] updated user facing messages --- .../tests/Test-Assessment.25411.ps1 | 65 +++++++++---------- 1 file changed, 31 insertions(+), 34 deletions(-) diff --git a/src/powershell/tests/Test-Assessment.25411.ps1 b/src/powershell/tests/Test-Assessment.25411.ps1 index c7a1482e5..17609436f 100644 --- a/src/powershell/tests/Test-Assessment.25411.ps1 +++ b/src/powershell/tests/Test-Assessment.25411.ps1 @@ -27,7 +27,7 @@ function Test-Assessment-25411 { $activity = 'TLS inspection is enabled and correctly configured for outbound traffic in Global Secure Access.' Write-ZtProgress -Activity $activity -Status 'Querying TLS inspection policies' - # Query Q1: Get TLS Inspection policies + # Step 1: Get TLS Inspection policies $tlsInspectionPolicies = Invoke-ZtGraphRequest -RelativeUri 'networkAccess/tlsInspectionPolicies' -ApiVersion beta # Step 2: List all policies in the Baseline Profile and in each Security Profile @@ -52,12 +52,11 @@ function Test-Assessment-25411 { # Iterate each TLS inspection policy and find linked profiles foreach ($tlsPolicy in $tlsInspectionPolicies) { $tlsId = $tlsPolicy.id - $tlsPolicyLinked = $false $baselineProfileFound = $false - foreach ($profile in $filteringProfiles) { + foreach ($profileItem in $filteringProfiles) { $profilePolicies = @() - if ($null -ne $profile.policies) { - $profilePolicies = $profile.policies + if ($null -ne $profileItem.policies) { + $profilePolicies = $profileItem.policies } foreach ($plink in $profilePolicies) { @@ -69,21 +68,20 @@ function Test-Assessment-25411 { } if ($null -ne $linkedPolicyId -and $linkedPolicyId -eq $tlsId) { - $tlsPolicyLinked = $true $linkState = if ($null -ne $plink.state) { $plink.state } else { 'unknown' } - $profileState = if ($null -ne $profile.state) { - $profile.state + $profileState = if ($null -ne $profileItem.state) { + $profileItem.state } else { 'unknown' } - $priority = if ($null -ne $profile.priority) { - [int]$profile.priority + $priority = if ($null -ne $profileItem.priority) { + [int]$profileItem.priority } else { $null @@ -95,8 +93,8 @@ function Test-Assessment-25411 { if ($linkState -eq 'enabled' -and $profileState -eq 'enabled') { $baselineProfileFound = $true $enabledBaseLineProfiles += [PSCustomObject]@{ - ProfileId = $profile.id - ProfileName = $profile.name + ProfileId = $profileItem.id + ProfileName = $profileItem.name ProfileState = $profileState ProfilePriority = $priority TLSPolicyId = $tlsId @@ -114,7 +112,7 @@ function Test-Assessment-25411 { if ($null -ne $session -and $null -ne $session.globalSecureAccessFilteringProfile) { $sessionProfileId = $session.globalSecureAccessFilteringProfile.profileId $sessionEnabled = $session.globalSecureAccessFilteringProfile.isEnabled - if ($sessionProfileId -eq $profile.id -and $sessionEnabled -eq $true -and $cap.state -eq 'enabled') { + if ($sessionProfileId -eq $profileItem.id -and $sessionEnabled -eq $true -and $cap.state -eq 'enabled') { $matchedCAPolicies += [PSCustomObject]@{ Id = $cap.id DisplayName = $cap.displayName @@ -126,8 +124,8 @@ function Test-Assessment-25411 { if ($matchedCAPolicies.Count -gt 0 -and $profileState -eq 'enabled' -and $linkState -eq 'enabled') { $enabledSecurityProfiles += [PSCustomObject]@{ - ProfileId = $profile.id - ProfileName = $profile.name + ProfileId = $profileItem.id + ProfileName = $profileItem.name ProfileState = $profileState ProfilePriority = $priority TLSPolicyId = $tlsId @@ -162,19 +160,19 @@ function Test-Assessment-25411 { $mdInfo = '' if ($null -eq $tlsInspectionPolicies -or $tlsInspectionPolicies.Count -eq 0) { - $testResultMarkdown = "❌ TLS inspection policies are not configured`n`n%TestResult%" + $testResultMarkdown = "❌ TLS Inspection Policy has not been properly configured. `n`n%TestResult%" $passed = $false } elseif ($enabledBaseLineProfiles.Count -gt 0) { - $testResultMarkdown = "✅ TLS inspection policy is applied via Baseline Profile(s).`n`n%TestResult%" + $testResultMarkdown = "✅ TLS Inspection Policy is enabled and properly configured to inspect encrypted outbound traffic.`n`n%TestResult%" $passed = $true } elseif ($enabledSecurityProfiles.Count -gt 0) { - $testResultMarkdown = "✅ TLS inspection policy is applied via Security Profile(s) enforced through Conditional Access.`n`n%TestResult%" + $testResultMarkdown = "✅ TLS Inspection Policy is enabled and properly configured to inspect encrypted outbound traffic.`n`n%TestResult%" $passed = $true } else { - $testResultMarkdown = "❌ TLS inspection policy is not linked to any enabled Baseline or CA-enforced Security Profile.`n`n%TestResult%" + $testResultMarkdown = "❌ TLS Inspection Policy has not been properly configured.`n`n%TestResult%" $passed = $false } @@ -190,9 +188,9 @@ function Test-Assessment-25411 { foreach ($policy in $enabledBaseLineProfiles) { $baseLineProfilePortalLink = "https://entra.microsoft.com/#view/Microsoft_Azure_Network_Access/EditProfileMenuBlade.MenuView/~/basics/profileId/$(($policy.ProfileId))" $tlsPolicyPortalLink = "https://entra.microsoft.com/#view/Microsoft_Azure_Network_Access/EditTlsInspectionPolicyMenuBlade.MenuView/~/basics/policyId/$(($policy.TLSPolicyId))" - $ProfileName = Get-SafeMarkdown($policy.ProfileName) + $ProfileName = Get-SafeMarkdown -Text $policy.ProfileName $ProfilePriority = $policy.ProfilePriority - $tlsPolicyName = Get-SafeMarkdown($policy.TLSPolicyName) + $tlsPolicyName = Get-SafeMarkdown -Text $policy.TLSPolicyName $tlsPolicyLinkState = $policy.TLSPolicyLinkState $ProfileState = $policy.ProfileState $mdInfo += "| [$ProfileName]($baseLineProfilePortalLink) | $ProfilePriority | [$tlsPolicyName]($tlsPolicyPortalLink) | $tlsPolicyLinkState | $ProfileState |`n" @@ -203,26 +201,25 @@ function Test-Assessment-25411 { $mdInfo += "`n## Security Profiles Linked to Conditional Access Policies`n`n" $mdInfo += "| Linked Profile Name | Linked Profile Priority | CA Policy Names | CA Policy State | Profile State | TLS Inspection Policy Name | Default Action |`n" $mdInfo += "| :--- | :--- | :--- | :--- | :--- | :--- | :--- |`n" - foreach ($profile in $enabledSecurityProfiles) { - $securityProfilePortalLink = "https://entra.microsoft.com/#view/Microsoft_Azure_Network_Access/EditProfileMenuBlade.MenuView/~/basics/profileId/$(($profile.ProfileId))" - $tlsPolicyPortalLink = "https://entra.microsoft.com/#view/Microsoft_Azure_Network_Access/EditTlsInspectionPolicyMenuBlade.MenuView/~/basics/policyId/$(($profile.TLSPolicyId))" - $ProfileName = Get-SafeMarkdown($profile.ProfileName) - $ProfilePriority = $profile.ProfilePriority - + foreach ($enabledProfile in $enabledSecurityProfiles) { + $securityProfilePortalLink = "https://entra.microsoft.com/#view/Microsoft_Azure_Network_Access/EditProfileMenuBlade.MenuView/~/basics/profileId/$(($enabledProfile.ProfileId))" + $tlsPolicyPortalLink = "https://entra.microsoft.com/#view/Microsoft_Azure_Network_Access/EditTlsInspectionPolicyMenuBlade.MenuView/~/basics/policyId/$(($enabledProfile.TLSPolicyId))" + $ProfileName = Get-SafeMarkdown -Text $enabledProfile.ProfileName + $ProfilePriority = $enabledProfile.ProfilePriority # Build CA policy links - $caNames = $profile.CAPolicyNames -split ', ' - $caIds = $profile.CAPolicyIds -split ', ' + $caNames = $enabledProfile.CAPolicyNames -split ', ' + $caIds = $enabledProfile.CAPolicyIds -split ', ' $caPolicyLinksMarkdown = @() for ($i = 0; $i -lt $caNames.Count; $i++) { $caPolicyPortalLink = "https://entra.microsoft.com/#view/Microsoft_Azure_Intune_Actions/ConditionalAccessBlade/~/Policies/$($caIds[$i].Trim())" - $safeName = Get-SafeMarkdown($caNames[$i]) + $safeName = Get-SafeMarkdown -Text $caNames[$i] $caPolicyLinksMarkdown += "[$safeName]($caPolicyPortalLink)" } $caPolicyNamesLinked = $caPolicyLinksMarkdown -join ', ' - $caPolicyStates = Get-SafeMarkdown($profile.CAPolicyStates) - $ProfileState = $profile.ProfileState - $TlsPolicyName = Get-SafeMarkdown($profile.TLSPolicyName) - $DefaultAction = $profile.DefaultAction + $caPolicyStates = Get-SafeMarkdown -Text $enabledProfile.CAPolicyStates + $ProfileState = $enabledProfile.ProfileState + $TlsPolicyName = Get-SafeMarkdown -Text $enabledProfile.TLSPolicyName + $DefaultAction = $enabledProfile.DefaultAction $mdInfo += "| [$ProfileName]($securityProfilePortalLink) | $ProfilePriority | $caPolicyNamesLinked | $caPolicyStates | $ProfileState | [$TlsPolicyName]($tlsPolicyPortalLink) | $DefaultAction |`n" } } From 58952a56f0df36f4826abffad501ef77ecf9b104 Mon Sep 17 00:00:00 2001 From: Komal Date: Mon, 5 Jan 2026 21:06:26 +0530 Subject: [PATCH 12/14] fix variable case-optimize code for ca policy iteration --- .../tests/Test-Assessment.25411.ps1 | 67 +++++++++++-------- 1 file changed, 40 insertions(+), 27 deletions(-) diff --git a/src/powershell/tests/Test-Assessment.25411.ps1 b/src/powershell/tests/Test-Assessment.25411.ps1 index 17609436f..900c3e4fe 100644 --- a/src/powershell/tests/Test-Assessment.25411.ps1 +++ b/src/powershell/tests/Test-Assessment.25411.ps1 @@ -21,6 +21,9 @@ function Test-Assessment-25411 { [CmdletBinding()] param() + # Define constants + [int]$BASELINE_PROFILE_PRIORITY = 65000 + #region Data Collection Write-PSFMessage '🟦 Start' -Tag Test -Level VeryVerbose @@ -41,6 +44,27 @@ function Test-Assessment-25411 { Write-ZtProgress -Activity $activity -Status 'Querying Conditional Access policies' $allCAPolicies = Get-ZtConditionalAccessPolicy + # Build CA profile lookup for O(1) access instead of O(N) search per profile + Write-ZtProgress -Activity $activity -Status 'Building Conditional Access policy lookup' + $caProfileLookup = @{} + foreach ($cap in $allCAPolicies) { + $session = $cap.sessionControls + if ($null -ne $session -and $null -ne $session.globalSecureAccessFilteringProfile) { + $sessionProfileId = $session.globalSecureAccessFilteringProfile.profileId + $sessionEnabled = $session.globalSecureAccessFilteringProfile.isEnabled + + if ($sessionEnabled -eq $true -and $cap.state -eq 'enabled') { + if (-not $caProfileLookup.ContainsKey($sessionProfileId)) { + $caProfileLookup[$sessionProfileId] = @() + } + $caProfileLookup[$sessionProfileId] += [PSCustomObject]@{ + Id = $cap.id + DisplayName = $cap.displayName + State = $cap.state + } + } + } + } #endregion Data Collection @@ -87,11 +111,11 @@ function Test-Assessment-25411 { $null } - if ($priority -eq 65000) { + if ($priority -eq $BASELINE_PROFILE_PRIORITY) { # Baseline Profile: apply without CA if ($linkState -eq 'enabled' -and $profileState -eq 'enabled') { - $baselineProfileFound = $true + $baseLineProfileFound = $true $enabledBaseLineProfiles += [PSCustomObject]@{ ProfileId = $profileItem.id ProfileName = $profileItem.name @@ -103,23 +127,12 @@ function Test-Assessment-25411 { } break } - } elseif ($null -ne $priority -and $priority -lt 65000) { + } elseif ($null -ne $priority -and $priority -lt $BASELINE_PROFILE_PRIORITY) { # Security Profile: must be applied via Conditional Access # Validate CA policies reference this profile via sessionControls $matchedCAPolicies = @() - foreach ($cap in $allCAPolicies) { - $session = $cap.sessionControls - if ($null -ne $session -and $null -ne $session.globalSecureAccessFilteringProfile) { - $sessionProfileId = $session.globalSecureAccessFilteringProfile.profileId - $sessionEnabled = $session.globalSecureAccessFilteringProfile.isEnabled - if ($sessionProfileId -eq $profileItem.id -and $sessionEnabled -eq $true -and $cap.state -eq 'enabled') { - $matchedCAPolicies += [PSCustomObject]@{ - Id = $cap.id - DisplayName = $cap.displayName - State = $cap.state - } - } - } + if ($caProfileLookup.ContainsKey($profileItem.id)) { + $matchedCAPolicies = $caProfileLookup[$profileItem.id] } if ($matchedCAPolicies.Count -gt 0 -and $profileState -eq 'enabled' -and $linkState -eq 'enabled') { @@ -146,7 +159,7 @@ function Test-Assessment-25411 { } } } - if ($baselineProfileFound) { + if ($baseLineProfileFound) { break } } @@ -188,12 +201,12 @@ function Test-Assessment-25411 { foreach ($policy in $enabledBaseLineProfiles) { $baseLineProfilePortalLink = "https://entra.microsoft.com/#view/Microsoft_Azure_Network_Access/EditProfileMenuBlade.MenuView/~/basics/profileId/$(($policy.ProfileId))" $tlsPolicyPortalLink = "https://entra.microsoft.com/#view/Microsoft_Azure_Network_Access/EditTlsInspectionPolicyMenuBlade.MenuView/~/basics/policyId/$(($policy.TLSPolicyId))" - $ProfileName = Get-SafeMarkdown -Text $policy.ProfileName - $ProfilePriority = $policy.ProfilePriority + $profileName = Get-SafeMarkdown -Text $policy.ProfileName + $profilePriority = $policy.ProfilePriority $tlsPolicyName = Get-SafeMarkdown -Text $policy.TLSPolicyName $tlsPolicyLinkState = $policy.TLSPolicyLinkState - $ProfileState = $policy.ProfileState - $mdInfo += "| [$ProfileName]($baseLineProfilePortalLink) | $ProfilePriority | [$tlsPolicyName]($tlsPolicyPortalLink) | $tlsPolicyLinkState | $ProfileState |`n" + $profileState = $policy.ProfileState + $mdInfo += "| [$profileName]($baseLineProfilePortalLink) | $profilePriority | [$tlsPolicyName]($tlsPolicyPortalLink) | $tlsPolicyLinkState | $profileState |`n" } } @@ -204,8 +217,8 @@ function Test-Assessment-25411 { foreach ($enabledProfile in $enabledSecurityProfiles) { $securityProfilePortalLink = "https://entra.microsoft.com/#view/Microsoft_Azure_Network_Access/EditProfileMenuBlade.MenuView/~/basics/profileId/$(($enabledProfile.ProfileId))" $tlsPolicyPortalLink = "https://entra.microsoft.com/#view/Microsoft_Azure_Network_Access/EditTlsInspectionPolicyMenuBlade.MenuView/~/basics/policyId/$(($enabledProfile.TLSPolicyId))" - $ProfileName = Get-SafeMarkdown -Text $enabledProfile.ProfileName - $ProfilePriority = $enabledProfile.ProfilePriority + $profileName = Get-SafeMarkdown -Text $enabledProfile.ProfileName + $profilePriority = $enabledProfile.ProfilePriority # Build CA policy links $caNames = $enabledProfile.CAPolicyNames -split ', ' $caIds = $enabledProfile.CAPolicyIds -split ', ' @@ -217,10 +230,10 @@ function Test-Assessment-25411 { } $caPolicyNamesLinked = $caPolicyLinksMarkdown -join ', ' $caPolicyStates = Get-SafeMarkdown -Text $enabledProfile.CAPolicyStates - $ProfileState = $enabledProfile.ProfileState - $TlsPolicyName = Get-SafeMarkdown -Text $enabledProfile.TLSPolicyName - $DefaultAction = $enabledProfile.DefaultAction - $mdInfo += "| [$ProfileName]($securityProfilePortalLink) | $ProfilePriority | $caPolicyNamesLinked | $caPolicyStates | $ProfileState | [$TlsPolicyName]($tlsPolicyPortalLink) | $DefaultAction |`n" + $profileState = $enabledProfile.ProfileState + $tlsPolicyName = Get-SafeMarkdown -Text $enabledProfile.TLSPolicyName + $defaultAction = $enabledProfile.DefaultAction + $mdInfo += "| [$profileName]($securityProfilePortalLink) | $profilePriority | $caPolicyNamesLinked | $caPolicyStates | $profileState | [$tlsPolicyName]($tlsPolicyPortalLink) | $defaultAction |`n" } } From 9c9c0c52e9d58b65ae459ba3284365584f619877 Mon Sep 17 00:00:00 2001 From: Komal Date: Mon, 5 Jan 2026 21:14:21 +0530 Subject: [PATCH 13/14] fix variable case for baselineprofilefound --- src/powershell/tests/Test-Assessment.25411.ps1 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/powershell/tests/Test-Assessment.25411.ps1 b/src/powershell/tests/Test-Assessment.25411.ps1 index 900c3e4fe..be6d922d0 100644 --- a/src/powershell/tests/Test-Assessment.25411.ps1 +++ b/src/powershell/tests/Test-Assessment.25411.ps1 @@ -76,7 +76,7 @@ function Test-Assessment-25411 { # Iterate each TLS inspection policy and find linked profiles foreach ($tlsPolicy in $tlsInspectionPolicies) { $tlsId = $tlsPolicy.id - $baselineProfileFound = $false + $baseLineProfileFound = $false foreach ($profileItem in $filteringProfiles) { $profilePolicies = @() if ($null -ne $profileItem.policies) { From 5a88c1c97aa6b6552654e80e21d7dcc2d586b3d3 Mon Sep 17 00:00:00 2001 From: Komal Date: Tue, 6 Jan 2026 11:47:48 +0530 Subject: [PATCH 14/14] fix CA policy seperator --- src/powershell/tests/Test-Assessment.25411.ps1 | 16 +++++++--------- 1 file changed, 7 insertions(+), 9 deletions(-) diff --git a/src/powershell/tests/Test-Assessment.25411.ps1 b/src/powershell/tests/Test-Assessment.25411.ps1 index be6d922d0..3250d4323 100644 --- a/src/powershell/tests/Test-Assessment.25411.ps1 +++ b/src/powershell/tests/Test-Assessment.25411.ps1 @@ -144,9 +144,7 @@ function Test-Assessment-25411 { TLSPolicyId = $tlsId TLSPolicyName = $plink.policy.name TLSPolicyLinkState = $linkState - CAPolicyNames = ($matchedCAPolicies | Select-Object -ExpandProperty DisplayName) -join ', ' - CAPolicyIds = ($matchedCAPolicies | Select-Object -ExpandProperty Id) -join ', ' - CAPolicyStates = ($matchedCAPolicies | Select-Object -ExpandProperty State) -join ', ' + MatchedCAPolicies = $matchedCAPolicies CAPolicyCount = $matchedCAPolicies.Count DefaultAction = if ($null -ne $tlsPolicy.settings) { $tlsPolicy.settings.defaultAction @@ -220,16 +218,16 @@ function Test-Assessment-25411 { $profileName = Get-SafeMarkdown -Text $enabledProfile.ProfileName $profilePriority = $enabledProfile.ProfilePriority # Build CA policy links - $caNames = $enabledProfile.CAPolicyNames -split ', ' - $caIds = $enabledProfile.CAPolicyIds -split ', ' $caPolicyLinksMarkdown = @() - for ($i = 0; $i -lt $caNames.Count; $i++) { - $caPolicyPortalLink = "https://entra.microsoft.com/#view/Microsoft_Azure_Intune_Actions/ConditionalAccessBlade/~/Policies/$($caIds[$i].Trim())" - $safeName = Get-SafeMarkdown -Text $caNames[$i] + $caPolicyStatesList = @() + foreach ($caPolicy in $enabledProfile.MatchedCAPolicies) { + $caPolicyPortalLink = "https://entra.microsoft.com/#view/Microsoft_AAD_ConditionalAccess/PolicyBlade/policyId/$($caPolicy.Id)" + $safeName = Get-SafeMarkdown -Text $caPolicy.DisplayName $caPolicyLinksMarkdown += "[$safeName]($caPolicyPortalLink)" + $caPolicyStatesList += $caPolicy.State } $caPolicyNamesLinked = $caPolicyLinksMarkdown -join ', ' - $caPolicyStates = Get-SafeMarkdown -Text $enabledProfile.CAPolicyStates + $caPolicyStates = $caPolicyStatesList -join ', ' $profileState = $enabledProfile.ProfileState $tlsPolicyName = Get-SafeMarkdown -Text $enabledProfile.TLSPolicyName $defaultAction = $enabledProfile.DefaultAction