Skip to content
Closed
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 7 additions & 0 deletions src/powershell/tests/Test-Assessment.25537.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
Azure Firewall Threat intelligence-based filtering alerts and denies traffic from/to known malicious IP addresses, FQDNs, and URLs. The IP addresses, domains, and URLs are sourced from the Microsoft Threat Intelligence feed, which includes multiple sources including the Microsoft Cyber Security team. When threat intelligence-based filtering is enabled, Azure Firewall evaluates traffic against the threat intelligence rules before applying NAT, network, or application rules. This check verifies that Threat Intelligence feature is enabled in “Alert and Deny” mode in the Azure Firewall policy configuration. The check will fail if Threat Intelligence is either “Disabled” or if it is not configured in “Alert and Deny” mode, in the firewall policy attached to the firewall.

**Remediation action**

- [Please check this article for guidance on how to enable Threat Intelligence in “Alert and Deny” mode in the Azure Firewall Policy.](https://learn.microsoft.com/en-us/azure/firewall-manager/threat-intelligence-settings)
<!--- Results --->
%TestResult%
130 changes: 130 additions & 0 deletions src/powershell/tests/Test-Assessment.25537.ps1
Original file line number Diff line number Diff line change
@@ -0,0 +1,130 @@
<#
.SYNOPSIS
Validates Threat intelligence is Enabled in Deny Mode on Azure Firewall.
.DESCRIPTION
This test validates that Azure Firewall Policies have Threat Intelligence enabled in Deny mode.
Checks all firewall policies in the subscription and reports their threat intelligence status.
Copy link

Copilot AI Jan 19, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The comment-based help says this “checks all firewall policies in the subscription”, but the implementation enumerates all subscriptions via Get-AzSubscription and loops through each. Please align the description with the actual behavior (either scope to current subscription only, or update the comment to say it iterates all accessible subscriptions).

Suggested change
Checks all firewall policies in the subscription and reports their threat intelligence status.
Checks all firewall policies across all accessible subscriptions and reports their threat intelligence status.

Copilot uses AI. Check for mistakes.
.NOTES
Test ID: 25537
Category: Internet Access Control
Required API: Azure Firewall Policies
#>

function Test-Assessment-25537 {
[ZtTest(
Category = 'Internet Access Control',
ImplementationCost = 'Low',
MinimumLicense = ('Azure_Firewall_Standard','Azure_Firewall_Premium'),
Pillar = 'Network',
RiskLevel = 'High',
SfiPillar = 'Protect networks',
TenantType = ('Workforce'),
TestId = 25537,
Title = 'Threat intelligence is Enabled in Deny Mode on Azure Firewall',
UserImpact = 'Low'
)]
[CmdletBinding()]
param()

Write-PSFMessage '🟦 Start' -Tag Test -Level VeryVerbose

#region Authentication Check
try {
$accessToken = Get-AzAccessToken -AsSecureString -ErrorAction SilentlyContinue -WarningAction SilentlyContinue
}
catch {
Write-PSFMessage $_.Exception.Message -Tag Test -Level Error
}

if (!$accessToken) {
Write-PSFMessage "Azure authentication token not found." -Level Warning
Add-ZtTestResultDetail -SkippedBecause NotConnectedAzure
return
}
#endregion Authentication Check

#region Data Collection
Write-ZtProgress `
-Activity 'Azure Firewall Threat Intelligence' `
-Status 'Enumerating Firewall Policies'

try {
$policies = Get-AzResource -ResourceType "Microsoft.Network/firewallPolicies" -ErrorAction Stop
}
catch {
Write-PSFMessage $_.Exception.Message -Tag Test -Level Error
Add-ZtTestResultDetail -SkippedBecause NoAzureAccess
return
}
#endregion Data Collection

#region Assessment Logic
$passed = $false
$testResultMarkdown = ""
$results = @()

if (-not $policies) {
$testResultMarkdown = "No Azure Firewall Policies were found in this subscription."
Add-ZtTestResultDetail `
-TestId '25537' `
-Title 'Threat intelligence is Enabled in Deny Mode on Azure Firewall' `
-Status $false `
-Result $testResultMarkdown
return
}

$results = @()

foreach ($policyResource in $policies) {
$policy = Get-AzFirewallPolicy `
-Name $policyResource.Name `
-ResourceGroupName $policyResource.ResourceGroupName `
-ErrorAction SilentlyContinue

$mode = $policy.ThreatIntelMode

$result = switch ($mode) {
'Deny' { '✅ Enabled (Alert and Deny)' }
'Alert' { '❌ Alert only' }
'Off' { '❌ Disabled' }
default { '❌ Not configured' }
}

$results += [PSCustomObject]@{
PolicyName = $policy.Name
ResourceGroup = $policy.ResourceGroupName
ThreatIntelMode = $mode
Result = $result
}
}
#endregion Data Collection

#region Assessment Logic Evaluation
$failedPolicies = $results | Where-Object { $_.ThreatIntelMode -ne 'Deny' }
$passed = ($failedPolicies.Count -eq 0)

if ($passed) {
$testResultMarkdown = "Threat Intelligence is enabled in **Alert and Deny** mode for all Azure Firewall Policies.`n`n%TestResult%"
} else {
$testResultMarkdown = "One or more Azure Firewall Policies do **not** have Threat Intelligence enabled in **Alert and Deny** mode.`n`n%TestResult%"
}
#endregion Assessment Logic Evaluation

#region Report Generation
$mdInfo = "## Azure Firewall Threat Intelligence Status`n`n"
$mdInfo += "Policy Name | Resource Group | Threat Intel Mode | Result |`n"
$mdInfo += "| :--- | :--- | :--- | :---: |`n"

foreach ($item in $results | Sort-Object PolicyName) {
$mdInfo += "| $($item.PolicyName) | $($item.ResourceGroup) | $($item.ThreatIntelMode) | $($item.Result) |`n"
}

$testResultMarkdown = $testResultMarkdown -replace "%TestResult%", $mdInfo

# --- Final result (NO AppliesTo) ---
Add-ZtTestResultDetail `
-TestId '25537' `
-Title 'Azure Firewall Threat Intelligence is enabled in Alert and Deny mode' `
-Status $passed `
-Result $testResultMarkdown
}