NSX - Counting DFW Rules per VM and Host with Bash Script
You can use a Bash script to audit Distributed Firewall (DFW) rule counts across virtual machines and hosts in your NSX environment, helping identify rule bloat and optimize firewall performance.
In NSX, as you create and modify firewall policies over time, DFW rules can accumulate on individual vNICs. Excessive rules per vNIC can impact throughput and latency. The NSX documentation provides guidance on rule limits, but there’s no built-in automated way to enumerate and aggregate rule counts across all VMs on a host.
Use Case
- NSX environment running on ESXi hosts with DFW enabled
- Security administrators need to identify VMs approaching rule count limits
- Operations teams require per-host and per-VM rule distribution for capacity planning
- Troubleshooting scenarios where DFW performance is degraded
- Audit and compliance reporting on firewall rule sprawl
Solution
The solution is a Bash script that runs directly on an ESXi host, leveraging native NSX CLI tools (vsipioctl, summarize-dvfilter, vim-cmd) to enumerate filters, count rules per vNIC, correlate with VM names, and produce a comprehensive report.
Script Features
- Runs natively on ESXi - no external dependencies, uses built-in NSX CLI tools
- Single-pass data collection - collects
summarize-dvfilterandvsipioctl getfiltersonce, reuses in memory - VM name resolution - correlates vNIC filter UUIDs to human-readable VM names via
vim-cmdcache anddvfiltermapping - Per-VM rule count table - formatted output showing VM name, filter UUID, and rule count
- High rule count alerting - identifies VMs exceeding 4000 rules (NSX recommended limit)
- Summary statistics - totals, averages, and distribution buckets
- Top 5 VMs by rule count - quick identification of heaviest consumers
- Verbose mode - optional detailed rule listing per vNIC for deep inspection
- Zero temp files - all processing in memory using Bash associative arrays
Prerequisites
- ESXi host with NSX DFW configured and running
- Access to ESXi shell (SSH or console)
- NSX VIBs installed (
vsipioctl,summarize-dvfilteravailable) - Appropriate privileges to run
vim-cmd vmsvc/get.config
Script Parameters
| Parameter | Description |
|---|---|
-v |
Verbose output - shows individual rule details per vNIC |
-h |
Show help message |
Usage Examples
1. Basic rule count report (Recommended First Step)
./count_dfw_rules-v2.1.sh
2. Verbose output with individual rule details
./count_dfw_rules-v2.1.sh -v
3. Show help
./count_dfw_rules-v2.1.sh -h
How It Works
1. Environment Validation
The script validates it’s running on an ESXi host with NSX by checking for required commands:
vsipioctl- NSX vShield endpoint CLIsummarize-dvfilter- DVFilter summary toolvim-cmd- VM management CLI
If any are missing, the script exits with an error.
2. Data Collection (Single Pass)
The script collects all raw data once to minimize overhead:
summarize-dvfilter- Maps world IDs to VM names viavmmdevice namesvsipioctl getfilters- Lists all NSX filters (one per vNIC) with their UUIDsvim-cmd vmsvc/get.config- Resolves world IDs to VM display names (cached per world ID)
3. Lookup Table Construction
Two in-memory associative arrays are built:
WORLD_VM_MAP- world_id → VM name fromdvfilteroutput (fallback)VIM_CACHE- world_id → VM name fromvim-cmd(primary, more reliable)
The vim-cmd cache is pre-populated with a single call per unique world ID for efficiency.
4. Per-Filter Rule Counting
For each NSX filter (vNIC):
- Count rules -
vsipioctl getrules -f <filter>piped togrep -c "rule" - Find world_id - Search
dvfilteroutput for the filter UUID, extract precedingworldline - Resolve VM name - Priority:
VIM_CACHE→WORLD_VM_MAP→ filter UUID as fallback - Store results - Accumulate in arrays for later statistics
5. Reporting and Analysis
After processing all filters:
- Per-VM table - Formatted columns: VM Name, Filter UUID, Rule Count
- High rule count alert - Lists VMs with >4000 rules (configurable threshold)
- Summary statistics - Total VMs, total rules, average rules/VM
- Distribution buckets - 0-100, 101-500, 501-1000, 1001-2000, 2001-4000, >4000
- Top 5 VMs - Sorted descending by rule count
6. Verbose Mode (Optional)
When -v is specified, the script additionally outputs:
- Debug lookup source (VIM_CACHE vs WORLD_VM_MAP) per vNIC
- Full rule listing for each vNIC (first 30 lines via
head)
Safety Features
The script is read-only and non-destructive:
- No modifications - Only queries NSX and ESXi state
- No temp files - All processing in memory
- Graceful degradation - Falls back to filter UUID if VM name resolution fails
- Error suppression - Failed commands don’t halt execution; results marked as 0
- Single execution - Data collected once, reused throughout
Sample Output
When run in basic mode:
==============================================
ESXi DFW Rules Count - Per VM and Per Host
==============================================
Host: esxi-01.lab.local
ESXi Version: VMware ESXi 7.0.3 build-18905247
Date: 2026-08-01 14:58:02
----------------------------------------------
Collecting Data
----------------------------------------------
----------------------------------------------
Building VM Name Lookup Tables
----------------------------------------------
VM lookup tables built: 42 names from vim-cmd, 45 from dvfilter
==============================================
DFW Rules Count - Per VM
==============================================
Virtual Machine VM UUID (Filter) DFW Rules Count
--------------------------------------------------------------------------------------------------------
web-01 550e8400-e29b-41d4-a716-446655440000 1247
app-02 550e8400-e29b-41d4-a716-446655440001 3892
db-01 550e8400-e29b-41d4-a716-446655440002 567
...
----------------------------------------------
VMs with >4000 DFW Rules
----------------------------------------------
app-02 550e8400-e29b-41d4-a716-446655440001 3892
Total VMs with >4000 rules: 1
==============================================
Summary Statistics
==============================================
Total VMs with DFW: 42
Total DFW Rules on Host: 89234
Average Rules per VM: 2124
----------------------------------------------
Distribution of VMs by Rule Count
----------------------------------------------
0-100 : 12 VMs ( 28.6%)
101-500 : 15 VMs ( 35.7%)
501-1000 : 5 VMs ( 11.9%)
1001-2000 : 4 VMs ( 9.5%)
2001-4000 : 5 VMs ( 11.9%)
>4000 : 1 VMs ( 2.4%)
----------------------------------------------
Top 5 VMs by Rule Count
----------------------------------------------
app-02 : 3892 rules
web-01 : 1247 rules
lb-01 : 987 rules
app-03 : 876 rules
db-01 : 567 rules
==============================================
Completed: 2026-08-01 14:58:15
When run with -v:
DEBUG: 550e8400-e29b-41d4-a716-446655440001 -> VIM_LOOKUP=app-02
--- Rules for 550e8400-e29b-41d4-a716-446655440001 ---
rule 1001: action=allow, src=any, dst=any, service=HTTP, ...
rule 1002: action=deny, src=10.0.0.0/8, dst=any, service=any, ...
...
Customization Options
The script can be easily customized for different environments:
- Adjust the high rule count threshold (default 4000) by modifying the comparison on line 174
- Modify distribution buckets in the
awkblock (lines 199-220) for different granularity - Change Top N VMs count (default 5) in the
head -5on line 229 - Extend verbose output by adjusting
head -30on line 162 - Add JSON/CSV export by appending formatted output to the results arrays
Troubleshooting
Common issues and solutions:
No NSX DFW Configured
- Script outputs:
WARNING: No NSX DFW configuredand exits with 0 - Verify NSX is installed and DFW is enabled on the host
Commands Not Found
- Error:
vsipioctl not found. Run on ESXi with NSX installed. - Ensure NSX VIBs are installed:
esxcli software vib list | grep -i nsx - Run directly on ESXi host, not vCenter or remote machine
VM Name Resolution Failures
- VM names show as filter UUIDs instead of friendly names
- Verify
vim-cmd vmsvc/get.config <world_id>works manually - Check
summarize-dvfilteroutput includesvmmdevice names
Permission Denied
- Ensure running as root or with appropriate ESXi shell privileges
vim-cmdrequires hostd access
Empty Results
- If
total_rules=0but DFW is enabled, checkvsipioctl getfiltersoutput manually - Verify filters are attached to running VMs (powered off VMs have no active filters)
Conclusion
This Bash script provides a lightweight, dependency-free way to audit DFW rule distribution across your NSX-on-ESXi environment. By running directly on the host and leveraging native CLI tools, it delivers immediate visibility into rule counts without requiring external APIs, collectors, or management plane connectivity.
The read-only design makes it safe for production use during maintenance windows or routine audits. The summary statistics and distribution buckets help identify outliers quickly, while the verbose mode supports deep-dive troubleshooting when specific VMs show abnormal rule counts.
Regular execution of this script as part of operational hygiene can prevent rule bloat from silently degrading DFW performance and help maintain compliance with NSX best practices for rule limits per vNIC.
- Download: DFW Rule Counter Script