On 26 October 2026, Azure Updates announced that Network Watcher’s VNet flow logs filtering capability reached general availability. The feature lets operators log only the network traffic they actually need instead of capturing everything and filtering downstream.
A discrepancy remains on the Microsoft Learn docs page, which still lists the feature as PREVIEW. The update timeline suggests a documentation lag rather than a reversal of status.
What the filtering can do
The filtering capability supports these fields:
| Field | Filter on | Example |
|---|---|---|
| Direction | Traffic direction | Inbound, Outbound |
| SrcIP | Source IP / CIDR | 192.168.1.1, 2001:db8::1/64 |
| SrcPort | Source port | 1024-65535, 80, 443 |
| DstIP | Destination IP / CIDR | 192.168.2.1, 2001:db8::2/64 |
| DstPort | Destination port | 22, 8080-8090 |
| Protocol | Protocol type | TCP, UDP |
| Encryption | Encryption status | All values, NX_ALL (unencrypted) |
Operators: = and != for every field. Logical operands && and || between fields, with AND-before-OR precedence. Maximum filter string length is 1000 characters. Brackets are not supported.
RecordTypes filtering
Flow records can be filtered by lifecycle state:
| Value | Description |
|---|---|
| B | Begin – flow created, no statistics |
| C | Continuing – ongoing flow, stats at 5-minute intervals |
| E | End – flow terminated, statistics provided |
| D | Deny – flow was blocked |
Common patterns: capture only denied traffic (D), only active stats (C), or the full lifecycle (B,C,E).
Why it matters
VNet flow logs capture every IP flow by default. Without filtering, teams ingest and store all traffic regardless of relevance. Filtering at the source reduces Log Analytics ingestion volume and storage costs – a direct impact on teams paying per-GB for ingestion.
For compliance workflows, filtering lets teams capture only specific CIDR ranges or denied traffic for audit purposes, rather than logging everything.
How to set it up
Create a flow log with filtering via PowerShell:
$vnet = Get-AzVirtualNetwork -Name 'myVNet' -ResourceGroupName 'myResourceGroup'
$storageAccount = Get-AzStorageAccount -Name 'myStorageAccount' -ResourceGroupName 'myResourceGroup'
$workspace = New-AzOperationalInsightsWorkspace -Name 'myWorkspace' -ResourceGroupName 'myResourceGroup' -Location 'EastUS'
New-AzNetworkWatcherFlowLog -Enabled $true -Name 'myVNetFlowLog' -NetworkWatcherName 'NetworkWatcher_eastus' `
-ResourceGroupName 'NetworkWatcherRG' -StorageId $storageAccount.Id -TargetResourceId $vnet.Id `
-FormatVersion 2 -EnabledFilteringCriteria 'dstip=20.252.145.59 || DstPort=443' `
-EnableTrafficAnalytics -TrafficAnalyticsWorkspaceId $workspace.ResourceId `
-EnableRetention $true -RetentionPolicyDays 15
Update an existing flow log in place:
Set-AzNetworkWatcherFlowLog -Enabled $true -Name 'myVNetFlowLog' -NetworkWatcherName 'NetworkWatcher_eastus' `
-ResourceGroupName 'NetworkWatcherRG' -StorageId $storageAccount.Id -TargetResourceId $vnet.Id `
-FormatVersion 2 -EnabledFilteringCriteria 'dstip=20.252.145.59 || DstPort=443' `
-EnableTrafficAnalytics -TrafficAnalyticsWorkspaceId $workspace.ResourceId `
-EnableRetention $true -RetentionPolicyDays 15
The enabledFilteringCriteria parameter is also available in Bicep and ARM templates. RecordTypes filtering can be enabled at creation or updated later.
Migration context: VNet flow logs replace NSG Flow Logs v2
NSG Flow Logs v2 is retired. VNet flow logs are the replacement, writing to the ntanetanalytics and ntaipdetails Log Analytics tables instead of the legacy AzureNetworkAnalytics_CL table. The new filtering capability adds to the migration incentive for teams still using the retired version.
What to watch for
- Microsoft Learn docs still show PREVIEW as of 2026-10-27. Verify current status in the Azure portal before planning production work.
- The feature was already available in preview before this announcement – this is a status transition, not a new feature.
- No regional availability or SKU constraints were listed in the Azure Updates entry.
- Complex multi-field filters may need simplification due to the 1000-character limit on filter strings.