Skip to main content

How to Export and Import Firewall Rules in Batch Script

Manually configuring the Windows Firewall on twenty different servers is a tedious and error-prone process. To ensure consistency and speed across your infrastructure, you need the ability to "clone" your security configuration. By exporting your complex web of rules into a single configuration file and importing it onto another machine, you can guarantee that every system in your fleet follows the same security standard. A Batch script can use the netsh advfirewall command as a powerful backup and deployment engine for your entire firewall state.

This guide will explain how to migrate firewall configurations using Batch.

Method 1: Exporting the Configuration (Backup)

The export command saves all rules, profile states (On/Off), and global settings into a .wfw file.

@echo off
setlocal enabledelayedexpansion

:: Check for Administrator privileges
net session >nul 2>&1
if !errorlevel! neq 0 (
echo [ERROR] This script requires Administrator privileges.
echo Right-click and select "Run as administrator."
pause
endlocal
exit /b 1
)

:: Use a reliable date format via wmic (locale-independent)
set "DateStamp="
for /f "tokens=2 delims==" %%d in ('wmic os get localdatetime /value 2^>nul') do (
for /f "delims=" %%e in ("%%d") do set "DateStamp=%%e"
)

if defined DateStamp (
set "FileDate=!DateStamp:~0,8!_!DateStamp:~8,4!"
) else (
set "FileDate=unknown"
)

set "BackupDir=%USERPROFILE%\FirewallBackups"
set "BackupFile=%BackupDir%\Firewall_%COMPUTERNAME%_%FileDate%.wfw"
set "LogFile=%USERPROFILE%\firewall_changes.log"

echo [BACKUP] Exporting firewall configuration...
echo Computer: %COMPUTERNAME%
echo.

:: Ensure the backup directory exists
if not exist "%BackupDir%" mkdir "%BackupDir%"

:: Export the full state
netsh advfirewall export "%BackupFile%" >nul 2>&1

if !errorlevel! equ 0 (
echo [SUCCESS] Firewall state saved to:
echo %BackupFile%
echo.

:: Show file size as confirmation
for %%F in ("%BackupFile%") do (
echo [INFO] File size: %%~zF bytes
)

:: Also export a human-readable rule list alongside
set "TextFile=%BackupDir%\Firewall_%COMPUTERNAME%_%FileDate%_rules.txt"
(
echo ==========================================
echo Firewall Rules Export - %COMPUTERNAME%
echo Date: %date% %time%
echo ==========================================
echo.
netsh advfirewall firewall show rule name=all
) > "!TextFile!"

echo [INFO] Human-readable rule list saved to:
echo !TextFile!

:: Count rules for reference
set "RuleCount=0"
for /f %%n in ('findstr /c:"Rule Name:" "!TextFile!" ^| find /c /v ""') do set "RuleCount=%%n"
echo [INFO] Total rules exported: !RuleCount!

echo [%date% %time%] EXPORTED firewall (%RuleCount% rules^) to "%BackupFile%" by %USERNAME% >> "%LogFile%"
) else (
echo [ERROR] Export failed. Check permissions and disk space.
)

pause
endlocal

:::note[Why also export a text file?] The .wfw binary file can only be read by netsh advfirewall import. By also saving a human-readable text dump, you can review, compare, and document the rules without needing to import them first. This is invaluable for auditing and troubleshooting. :::

:::note[Why not use %DATE% in filenames?] The %DATE% format varies by locale, it might be Mon 01/15/2025 on one machine and 2025-01-15 on another. Slashes in filenames cause errors. Using WMIC's localdatetime provides a consistent YYYYMMDD format that works everywhere. :::

Method 2: Importing the Configuration (Restore/Deploy)

Importing a firewall state overwrites ALL existing rules on the target machine. This script includes safety checks and backup before importing.

@echo off
setlocal enabledelayedexpansion

:: Check for Administrator privileges
net session >nul 2>&1
if !errorlevel! neq 0 (
echo [ERROR] This script requires Administrator privileges.
pause
endlocal
exit /b 1
)

set "ConfigFile="
set "LogFile=%USERPROFILE%\firewall_changes.log"

:: Accept config file as argument or prompt
if "%~1" neq "" (
set "ConfigFile=%~1"
) else (
set /p "ConfigFile=Enter path to .wfw file: "
)

:: Validate the file exists
if not defined ConfigFile (
echo [ERROR] No file specified.
pause
endlocal
exit /b 1
)

if not exist "!ConfigFile!" (
echo [ERROR] Configuration file not found: !ConfigFile!
pause
endlocal
exit /b 1
)

:: Validate file extension
echo "!ConfigFile!" | findstr /i "\.wfw" >nul 2>&1
if !errorlevel! neq 0 (
echo [WARN] File does not have .wfw extension.
echo Are you sure this is a firewall export file?
echo.
)

echo =====================================================
echo FIREWALL IMPORT - CONFIGURATION DEPLOYMENT
echo =====================================================
echo.
echo Source file: !ConfigFile!
echo Target: %COMPUTERNAME%
echo.
echo [!! WARNING !!]
echo Importing will OVERWRITE all existing firewall rules
echo on this machine. This cannot be undone without a backup.
echo.
echo =====================================================
echo.

:: Backup current configuration before overwriting
set "PreImportBackup=%USERPROFILE%\FirewallBackups\PreImport_%COMPUTERNAME%.wfw"
if not exist "%USERPROFILE%\FirewallBackups" mkdir "%USERPROFILE%\FirewallBackups"

echo [SAFETY] Backing up current configuration first...
netsh advfirewall export "%PreImportBackup%" >nul 2>&1
if !errorlevel! equ 0 (
echo [OK] Backup saved to: %PreImportBackup%
echo [OK] To undo: netsh advfirewall import "%PreImportBackup%"
) else (
echo [WARN] Backup failed - proceeding may be risky.
)

echo.

:: Confirm import
set /p "confirm=Type IMPORT to proceed: "
if /i "!confirm!" neq "IMPORT" (
echo [CANCELLED] No changes made.
pause
endlocal
exit /b 0
)

echo.
echo [ACTION] Importing firewall configuration...

netsh advfirewall import "!ConfigFile!" >nul 2>&1

if !errorlevel! equ 0 (
echo [SUCCESS] Configuration applied successfully.
echo.

:: Verify by showing current state
echo [VERIFY] Current firewall state:
netsh advfirewall show allprofiles state 2>nul | findstr /i "State"
netsh advfirewall show allprofiles firewallpolicy 2>nul | findstr /i "Policy"

:: Count imported rules
set "RuleCount=0"
for /f %%n in ('netsh advfirewall firewall show rule name^=all 2^>nul ^| findstr /c:"Rule Name:" ^| find /c /v ""') do set "RuleCount=%%n"
echo.
echo [INFO] Active rules: !RuleCount!

echo [%date% %time%] IMPORTED "!ConfigFile!" onto %COMPUTERNAME% (!RuleCount! rules^) by %USERNAME% >> "%LogFile%"
) else (
echo [ERROR] Import failed.
echo.
echo [RECOVERY] To restore the previous configuration:
echo netsh advfirewall import "%PreImportBackup%"
)

pause
endlocal

Method 3: The "Gold Image" Deployment Pattern

Use this in your deployment script to clear all default Windows rules and apply your hardened corporate security policy. Includes remote session protection and pre-deployment validation.

@echo off
setlocal enabledelayedexpansion

:: Check for Administrator privileges
net session >nul 2>&1
if !errorlevel! neq 0 (
echo [ERROR] This script requires Administrator privileges.
pause
endlocal
exit /b 1
)

set "PolicyFile=\\fileserver\configs\corporate.wfw"
set "LogFile=%USERPROFILE%\firewall_changes.log"

echo =====================================================
echo CORPORATE SECURITY PROFILE DEPLOYMENT
echo =====================================================
echo Target: %COMPUTERNAME%
echo Policy: %PolicyFile%
echo =====================================================
echo.

:: Verify the policy file is accessible
if not exist "%PolicyFile%" (
echo [ERROR] Corporate policy file not found:
echo %PolicyFile%
echo.
echo Check network connectivity and file share permissions.
pause
endlocal
exit /b 1
)

:: Detect RDP session
set "IsRDP=0"
netstat -ano | findstr ":3389.*ESTABLISHED" >nul 2>&1
if !errorlevel! equ 0 set "IsRDP=1"

if !IsRDP! equ 1 (
echo [!! WARNING !!] You are connected via Remote Desktop.
echo Ensure the corporate policy includes an RDP rule,
echo or you will be disconnected permanently.
echo.
)

:: Confirm
set /p "confirm=Deploy corporate policy? (Y/N): "
if /i "!confirm!" neq "Y" (
echo [CANCELLED] No changes made.
pause
endlocal
exit /b 0
)

echo.

:: Step 1: Backup current state
echo [1/3] Backing up current configuration...
set "Backup=%USERPROFILE%\FirewallBackups\PreDeploy_%COMPUTERNAME%.wfw"
if not exist "%USERPROFILE%\FirewallBackups" mkdir "%USERPROFILE%\FirewallBackups"
netsh advfirewall export "%Backup%" >nul 2>&1
echo [OK] Backup: %Backup%

:: Step 2: Reset to clean slate
echo [2/3] Resetting firewall to clean state...
netsh advfirewall reset >nul 2>&1
echo [OK] All rules cleared.

:: Step 3: Import corporate policy
echo [3/3] Importing corporate policy...
netsh advfirewall import "%PolicyFile%" >nul 2>&1

if !errorlevel! equ 0 (
echo [OK] Policy applied.
echo.
echo =====================================================
echo DEPLOYMENT COMPLETE
echo =====================================================
echo.
echo Firewall state:
netsh advfirewall show allprofiles state 2>nul | findstr /i "State"
netsh advfirewall show allprofiles firewallpolicy 2>nul | findstr /i "Policy"
echo.
echo To rollback: netsh advfirewall import "%Backup%"
echo.
echo =====================================================

echo [%date% %time%] DEPLOYED corporate policy to %COMPUTERNAME% by %USERNAME% >> "%LogFile%"
) else (
echo [ERROR] Import failed!
echo.
echo [RECOVERY] Restoring previous configuration...
netsh advfirewall import "%Backup%" >nul 2>&1
if !errorlevel! equ 0 (
echo [OK] Previous configuration restored.
) else (
echo [ERROR] Restore also failed. Manual intervention required.
)
)

pause
endlocal
Why reset before importing?

While import overwrites all rules, some edge cases with corrupted or conflicting rule states can cause unexpected behavior. A netsh advfirewall reset first ensures a truly clean slate, making the import more predictable and reliable.

Method 4: Selective Rule Export (PowerShell CSV)

Sometimes you don't want to clone the entire firewall, just export specific rules for documentation or selective deployment.

@echo off
setlocal

:: Check for Administrator privileges
net session >nul 2>&1
if %errorlevel% neq 0 (
echo [ERROR] This script requires Administrator privileges.
pause
endlocal
exit /b 1
)

set "OutputCSV=%USERPROFILE%\firewall_rules_export.csv"

echo [EXPORT] Exporting firewall rules to CSV...
echo File: %OutputCSV%
echo.

powershell -NoProfile -Command ^
"try {"^
" $rules = Get-NetFirewallRule -ErrorAction Stop;"^
" $results = @();"^
" $count = 0;"^
" foreach ($rule in $rules) {"^
" $count++;"^
" if ($count %% 50 -eq 0) { Write-Host (' Processing {0} of {1}...' -f $count, $rules.Count) };"^
" $port = $rule | Get-NetFirewallPortFilter -EA SilentlyContinue;"^
" $app = $rule | Get-NetFirewallApplicationFilter -EA SilentlyContinue;"^
" $addr = $rule | Get-NetFirewallAddressFilter -EA SilentlyContinue;"^
" $results += [PSCustomObject]@{"^
" Name = $rule.DisplayName;"^
" Direction = $rule.Direction;"^
" Action = $rule.Action;"^
" Enabled = $rule.Enabled;"^
" Profile = $rule.Profile;"^
" Protocol = $port.Protocol;"^
" LocalPort = $port.LocalPort -join ',';"^
" RemotePort = $port.RemotePort -join ',';"^
" RemoteAddress = $addr.RemoteAddress -join ',';"^
" Program = $app.Program;"^
" }"^
" };"^
" $results | Export-Csv -Path '%OutputCSV%' -NoTypeInformation;"^
" Write-Host '';"^
" Write-Host ('[OK] Exported {0} rules to: %OutputCSV%' -f $results.Count)"^
"} catch {"^
" Write-Host ('[ERROR] ' + $_.Exception.Message)"^
"}"

echo.
echo [TIP] Open the CSV in Excel to review, filter, and compare rules
echo between machines.

pause
endlocal
Why CSV alongside WFW?

The .wfw binary file is for machine-to-machine deployment. The CSV export is for humans, you can open it in Excel, sort by Direction or Action, compare two servers' rules side by side, and build compliance documentation.

Method 5: Compare Two Machines' Firewall Rules

Verify that two servers have identical firewall configurations.

@echo off
setlocal

echo [COMPARE] Firewall Rule Comparison Tool
echo.

set "File1="
set "File2="

if "%~1" neq "" if "%~2" neq "" (
set "File1=%~1"
set "File2=%~2"
) else (
set /p "File1=Path to first text export: "
set /p "File2=Path to second text export: "
)

if not exist "%File1%" (
echo [ERROR] File not found: %File1%
pause
endlocal
exit /b 1
)

if not exist "%File2%" (
echo [ERROR] File not found: %File2%
pause
endlocal
exit /b 1
)

echo.
echo [COMPARE] Comparing:
echo A: %File1%
echo B: %File2%
echo.

:: Count rules in each file
set "Count1=0"
set "Count2=0"
for /f %%n in ('findstr /c:"Rule Name:" "%File1%" ^| find /c /v ""') do set "Count1=%%n"
for /f %%n in ('findstr /c:"Rule Name:" "%File2%" ^| find /c /v ""') do set "Count2=%%n"

echo File A rules: %Count1%
echo File B rules: %Count2%
echo.

:: Use fc to compare
fc "%File1%" "%File2%" >nul 2>&1
if %errorlevel% equ 0 (
echo [MATCH] Files are identical, configurations match perfectly.
) else (
echo [DIFF] Differences found:
echo.
fc "%File1%" "%File2%" | more
)

pause
endlocal

Usage: First export text rule lists from both machines (Method 1 creates these automatically), then compare them:

compare_fw.bat server1_rules.txt server2_rules.txt

How to Avoid Common Errors

Wrong Way: Thinking Import "Adds" Rules

netsh advfirewall import is a total state swap. It deletes everything currently in the firewall and replaces it with the contents of the .wfw file. It is not an "add" or "merge" operation.

Correct Way: If you only want to add specific rules, use netsh advfirewall firewall add rule. Use import only when you want a complete, identical configuration.

Wrong Way: Importing Without Backing Up First

If the imported configuration is wrong (missing RDP rules, blocking critical services), you have no way to restore the previous working state.

Correct Way: Always export the current configuration before importing:

:: Backup before import
netsh advfirewall export "%USERPROFILE%\firewall_pre_import.wfw"

:: Then import
netsh advfirewall import "new_config.wfw"

:: If something breaks, restore
netsh advfirewall import "%USERPROFILE%\firewall_pre_import.wfw"

Wrong Way: Using %DATE% in Filenames

The %DATE% format varies by locale, 01/15/2025 contains slashes that are invalid in filenames. On different machines, the format may be completely different.

Correct Way: Use WMIC for a consistent, filename-safe date:

for /f "tokens=2 delims==" %%d in ('wmic os get localdatetime /value') do (
for /f "delims=" %%e in ("%%d") do set "DateStamp=%%e"
)
set "FileDate=%DateStamp:~0,8%"

Wrong Way: Not Quoting File Paths

If your backup path contains spaces (e.g., C:\My Backups\file.wfw), the command fails without quotes.

Correct Way: Always wrap file paths in double quotes:

netsh advfirewall export "%BackupFile%"
netsh advfirewall import "%ConfigFile%"

Wrong Way: Running Without Administrator Privileges

Accessing the binary firewall state requires system-level permissions. Without elevation, commands fail silently.

Correct Way: Always check for elevation:

net session >nul 2>&1
if %errorlevel% neq 0 (
echo [ERROR] Run as Administrator.
exit /b 1
)

Best Practices and Rules

1. Test Before Global Deploy

Never import a policy onto a production server without testing it on a lab machine first. If your .wfw file blocks Port 3389 (RDP) and you import it onto a remote server, you've effectively locked yourself out and will need physical access to fix it.

2. Version Control

Store your .wfw files in a secure folder with timestamps and machine names. This allows you to roll back security settings to a known good state:

FirewallBackups/
├── Firewall_SERVER01_20250115_0930.wfw
├── Firewall_SERVER01_20250115_0930_rules.txt
├── Firewall_SERVER02_20250115_1045.wfw
└── corporate_gold_image_v2.1.wfw

3. Include Human-Readable Exports

Always save a text dump alongside the binary .wfw file. The binary can only be read by netsh import, but the text file can be reviewed, compared, and documented without importing.

4. Verify After Import

Always confirm the import succeeded by checking the firewall state and rule count:

netsh advfirewall show allprofiles state
netsh advfirewall show allprofiles firewallpolicy

5. Clean Slate Before Import

For the most predictable results, run netsh advfirewall reset before importing. This clears any corrupted or conflicting rule states.

6. Always Use setlocal / endlocal

Without setlocal, every variable your script creates persists in the parent shell session, causing potential conflicts when running multiple scripts in sequence.

Conclusions

Exporting and importing firewall rules via Batch script is the gold standard for managing multi-server security. By moving from manual, per-machine configuration to a centralized, file-based deployment system, you ensure that your security standards are absolute and reproducible. This precision is essential for maintaining a hardened infrastructure and responding effectively to configuration drifts across your environment.