tests/Test-Assessment.25411.ps1
|
<#
.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 Baseline or Security Profile with an enabled policy link, or (for Security Profiles) if no enabled Conditional Access policy assigning that profile can be identified. #> function Test-Assessment-25411 { [ZtTest( Category = 'Global Secure Access', ImplementationCost = 'High', Service = ('Graph'), MinimumLicense = ('Entra_Premium_Internet_Access'), CompatibleLicense = ('Entra_Premium_Internet_Access'), Pillar = 'Network', RiskLevel = 'High', SfiPillar = 'Protect networks', TenantType = ('Workforce'), TestId = 25411, Title = 'TLS inspection is enabled and correctly configured for outbound traffic', UserImpact = 'Medium' )] [CmdletBinding()] param() # Define constants [int]$BASELINE_PROFILE_PRIORITY = 65000 #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' # 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 Write-ZtProgress -Activity $activity -Status 'Querying filtering profiles and policies' $filteringProfiles = Invoke-ZtGraphRequest -RelativeUri 'networkAccess/filteringProfiles' -QueryParameters @{ '$select' = 'id,name,description,state,priority' '$expand' = 'policies($select=id,state;$expand=policy($select=id,name,version))' } -ApiVersion beta # Query all Conditional Access policies with details Write-ZtProgress -Activity $activity -Status 'Querying Conditional Access policies' $allCAPolicies = Get-ZtConditionalAccessPolicy #endregion Data Collection #region Data Processing # Graph responses are automatically unwrapped by Invoke-ZtGraphRequest $baselineProfileResults = [System.Collections.Generic.List[object]]::new() $securityProfileResults = [System.Collections.Generic.List[object]]::new() # Iterate each TLS inspection policy and find linked profiles using the helper function foreach ($tlsPolicy in $tlsInspectionPolicies) { $findParams = @{ PolicyId = $tlsPolicy.id FilteringProfiles = $filteringProfiles CAPolicies = $allCAPolicies BaselinePriority = $BASELINE_PROFILE_PRIORITY PolicyLinkType = 'tlsInspectionPolicyLink' PolicyRules = $tlsPolicy } $linkedProfiles = Find-ZtProfilesLinkedToPolicy @findParams foreach ($policyProfile in $linkedProfiles) { if ($policyProfile.ProfileType -eq 'Baseline Profile') { $baselineProfileResults.Add([PSCustomObject]@{ ProfileId = $policyProfile.ProfileId ProfileName = $policyProfile.ProfileName ProfileState = $policyProfile.ProfileState ProfilePriority = $policyProfile.ProfilePriority TLSPolicyId = $tlsPolicy.id TLSPolicyName = $tlsPolicy.name TLSPolicyLinkState = $policyProfile.PolicyLinkState }) } elseif ($policyProfile.ProfileType -eq 'Security Profile') { $matchedCAPolicies = @() if ($null -ne $policyProfile.CAPolicy) { $matchedCAPolicies = @($policyProfile.CAPolicy) } # Collect all linked security profiles for table display (regardless of state or CA policy linkage) $securityProfileResults.Add([PSCustomObject]@{ ProfileId = $policyProfile.ProfileId ProfileName = $policyProfile.ProfileName ProfileState = $policyProfile.ProfileState ProfilePriority = $policyProfile.ProfilePriority TLSPolicyId = $tlsPolicy.id TLSPolicyName = $tlsPolicy.name TLSPolicyLinkState = $policyProfile.PolicyLinkState MatchedCAPolicies = $matchedCAPolicies PassesCriteria = $policyProfile.PassesCriteria }) } } } # Baseline profiles that pass: both policy link state and profile state must be enabled $enabledBaselineProfiles = @($baselineProfileResults | Where-Object { $_.ProfileState -eq 'enabled' -and $_.TLSPolicyLinkState -eq 'enabled' }) # Security profiles that pass: profile enabled, policy link enabled, and at least one enabled CA policy linked $enabledSecurityProfiles = @($securityProfileResults | Where-Object { $_.ProfileState -eq 'enabled' -and $_.TLSPolicyLinkState -eq 'enabled' -and $_.PassesCriteria }) #endregion Data Processing #region Assessment logic $testResultMarkdown = '' $passed = $false $mdInfo = '' if ($null -eq $tlsInspectionPolicies -or $tlsInspectionPolicies.Count -eq 0) { $testResultMarkdown = "❌ TLS Inspection Policy has not been properly configured. `n`n%TestResult%" } elseif ($enabledBaselineProfiles.Count -gt 0 -or $enabledSecurityProfiles.Count -gt 0) { $testResultMarkdown = "✅ TLS Inspection Policy is enabled and properly configured to inspect encrypted outbound traffic.`n`n%TestResult%" $passed = $true } else { $testResultMarkdown = "❌ TLS Inspection Policy has not been properly configured.`n`n%TestResult%" $passed = $false } #endregion Assessment logic #region Report Generation if ($baselineProfileResults.Count -gt 0) { $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 $baselineProfileResults) { $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 $tlsPolicyName = Get-SafeMarkdown -Text $policy.TLSPolicyName $tlsPolicyLinkState = if ($policy.TLSPolicyLinkState -eq 'enabled') { '✅ Enabled' } else { '❌ Disabled' } $profileState = if ($policy.ProfileState -eq 'enabled') { '✅ Enabled' } else { '❌ Disabled' } $mdInfo += "| [$profileName]($baselineProfilePortalLink) | $profilePriority | [$tlsPolicyName]($tlsPolicyPortalLink) | $tlsPolicyLinkState | $profileState |`n" } } if ($securityProfileResults.Count -gt 0) { $mdInfo += "`n## TLS Inspection Policies Linked to Security Profiles`n`n" $mdInfo += "| Linked profile name | Linked profile priority | Linked policy name | Policy link state | Profile state | CA policy name | CA policy state |`n" $mdInfo += "| :--- | :--- | :--- | :--- | :--- | :--- | :--- |`n" foreach ($profile in $securityProfileResults) { $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 -Text $profile.ProfileName $profilePriority = $profile.ProfilePriority $tlsPolicyName = Get-SafeMarkdown -Text $profile.TLSPolicyName $tlsPolicyLinkState = if ($profile.TLSPolicyLinkState -eq 'enabled') { '✅ Enabled' } else { '❌ Disabled' } $profileState = if ($profile.ProfileState -eq 'enabled') { '✅ Enabled' } else { '❌ Disabled' } if ($profile.MatchedCAPolicies.Count -gt 0) { $caPolicyLinksMarkdown = [System.Collections.Generic.List[string]]::new() $caPolicyStatesList = [System.Collections.Generic.List[string]]::new() foreach ($caPolicy in $profile.MatchedCAPolicies) { $caPolicyPortalLink = "https://entra.microsoft.com/#view/Microsoft_AAD_ConditionalAccess/PolicyBlade/policyId/$($caPolicy.Id)" $safeName = Get-SafeMarkdown -Text $caPolicy.DisplayName $caPolicyLinksMarkdown.Add("[$safeName]($caPolicyPortalLink)") $caPolicyStatesList.Add($(if ($caPolicy.State -eq 'enabled') { '✅ Enabled' } elseif ($caPolicy.State -eq 'enabledForReportingButNotEnforced') { '⚠️ Report Only' } else { '❌ Disabled' })) } $caPolicyNamesLinked = $caPolicyLinksMarkdown -join ', ' $caPolicyStates = $caPolicyStatesList -join ', ' } else { $caPolicyNamesLinked = 'Missing' $caPolicyStates = 'Missing' } $mdInfo += "| [$profileName]($securityProfilePortalLink) | $profilePriority | [$tlsPolicyName]($tlsPolicyPortalLink) | $tlsPolicyLinkState | $profileState | $caPolicyNamesLinked | $caPolicyStates |`n" } } $testResultMarkdown = $testResultMarkdown -replace '%TestResult%', $mdInfo #endregion Report Generation $params = @{ TestId = '25411' Status = $passed Result = $testResultMarkdown } # Add test result details Add-ZtTestResultDetail @params } |