Skip to main content

How to Create an Inbound Firewall Rule for a Program in Batch Script

When you install a new server application (like a Minecraft server, a web host, or a backup agent), it won't be able to receive data from other computers until a "hole" is punched through the Windows Firewall. Manually identifying the program path and creating an inbound rule is a repetitive task that can be easily automated. A Batch script can use the netsh advfirewall command to create a permanent exception for a specific .exe file, ensuring your application can communicate freely while keeping the rest of your system locked down.

This guide will explain how to programmatically authorize an application.

Method 1: Creating the Program-Based Exception

This method is safer than opening a generic port (like 8080) because it only allows traffic when your specific, trusted program is the one receiving it.

@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
)

set "RuleName=MyServerApp_Access"
set "AppPath=C:\Program Files\MyServer\engine.exe"
set "LogFile=%USERPROFILE%\firewall_changes.log"

echo [DEPLOY] Authorizing "%RuleName%"...
echo Program: %AppPath%
echo.

:: Verify the application exists
if not exist "%AppPath%" (
echo [WARN] Application not found at: %AppPath%
echo The rule will be created, but it won't activate until
echo the application is installed at this path.
echo.
)

:: Check if rule already exists
netsh advfirewall firewall show rule name="%RuleName%" >nul 2>&1
if !errorlevel! equ 0 (
echo [INFO] Rule "%RuleName%" already exists. No duplicate created.
echo.
echo Current rule details:
netsh advfirewall firewall show rule name="%RuleName%" | findstr /i "Rule Name: Enabled: Direction: Action: Program:"
pause
endlocal
exit /b 0
)

:: Create the inbound allow rule
:: dir=in = Inbound traffic
:: action=allow = Let it through
:: program = Path to the binary
:: enable=yes = Turn it on immediately
netsh advfirewall firewall add rule name="%RuleName%" dir=in action=allow program="%AppPath%" enable=yes >nul 2>&1

if !errorlevel! equ 0 (
echo [SUCCESS] Rule created. "%RuleName%" can now receive connections.
echo [%date% %time%] CREATED rule "%RuleName%" program="%AppPath%" by %USERNAME% >> "%LogFile%"

:: Show the created rule for verification
echo.
echo --- Rule Details ---
netsh advfirewall firewall show rule name="%RuleName%" | findstr /i "Rule Name: Enabled: Direction: Action: Profile: Program:"
echo --------------------
) else (
echo [ERROR] Failed to add rule. Check the application path and permissions.
)

pause
endlocal
Why program-based rules are safer than port-based rules:

A port rule (e.g., "allow port 8080") lets any application receive traffic on that port. A program rule ensures that only your specific .exe can accept connections, i.e. if malware tries to listen on the same port, the firewall blocks it because the binary doesn't match.

Method 2: Limiting to Specific Profiles

You might want to allow a program on your Private (home) and Domain (office) networks but block it when connected to Public Wi-Fi.

@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 "RuleName=Internal_Database"
set "AppPath=C:\SQL\db.exe"
set "Profiles=domain,private"
set "LogFile=%USERPROFILE%\firewall_changes.log"

echo [ACTION] Creating profile-restricted exception...
echo Rule: %RuleName%
echo Program: %AppPath%
echo Profiles: %Profiles%
echo.

:: Check for existing rule
netsh advfirewall firewall show rule name="%RuleName%" >nul 2>&1
if !errorlevel! equ 0 (
echo [INFO] Rule already exists. Skipping creation.
pause
endlocal
exit /b 0
)

:: Verify the application exists
if not exist "%AppPath%" (
echo [WARN] Application not found at: %AppPath%
echo Rule will be created but inactive until the application is installed.
echo.
)

:: Create with profile restriction
netsh advfirewall firewall add rule name="%RuleName%" dir=in action=allow program="%AppPath%" profile=%Profiles% enable=yes >nul 2>&1

if !errorlevel! equ 0 (
echo [SUCCESS] Rule created for %Profiles% profiles only.
echo.
echo [SECURITY] This program is BLOCKED on Public networks.
echo It will only accept connections on Domain and Private networks.
echo [%date% %time%] CREATED rule "%RuleName%" profiles=%Profiles% by %USERNAME% >> "%LogFile%"
) else (
echo [ERROR] Failed to create rule.
)

pause
endlocal
Why restrict profiles?

A database server should never accept connections on a public coffee shop network. By specifying profile=domain,private, the rule automatically deactivates when you connect to an untrusted network. By default, netsh adds rules to all profiles, so always specify the profile for server applications.

Method 3: Combining Program and Port

For maximum security, tell the firewall: "Only allow traffic if it's going to this specific program AND using this specific port AND using this protocol."

@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 "RuleName=Secure_Web_Server"
set "AppPath=C:\Server\web.exe"
set "Port=443"
set "Protocol=TCP"
set "Profiles=domain,private"
set "LogFile=%USERPROFILE%\firewall_changes.log"

echo [DEPLOY] Creating multi-layer firewall rule...
echo Rule: %RuleName%
echo Program: %AppPath%
echo Port: %Port%/%Protocol%
echo Profiles: %Profiles%
echo.

:: Check for existing rule
netsh advfirewall firewall show rule name="%RuleName%" >nul 2>&1
if !errorlevel! equ 0 (
echo [INFO] Rule already exists. Skipping creation.
pause
endlocal
exit /b 0
)

:: Create the multi-layer rule
netsh advfirewall firewall add rule name="%RuleName%" dir=in action=allow program="%AppPath%" localport=%Port% protocol=%Protocol% profile=%Profiles% enable=yes >nul 2>&1

if !errorlevel! equ 0 (
echo [SUCCESS] Multi-layer rule created.
echo.
echo Traffic is allowed ONLY when ALL conditions are met:
echo - Program is: %AppPath%
echo - Port is: %Port%
echo - Protocol: %Protocol%
echo - Network: %Profiles%
echo.
echo [%date% %time%] CREATED rule "%RuleName%" program="%AppPath%" port=%Port%/%Protocol% profiles=%Profiles% by %USERNAME% >> "%LogFile%"

:: Verify
echo --- Verification ---
netsh advfirewall firewall show rule name="%RuleName%" | findstr /i "Rule Name: Enabled: Direction: Action: Profile: Program: LocalPort: Protocol:"
echo --------------------
) else (
echo [ERROR] Failed to create rule. Check path and parameters.
)

pause
endlocal
Defense in depth

This rule requires three conditions to be true simultaneously: correct program, correct port, and correct protocol. Even if an attacker compromises port 443, they can't receive traffic through this rule unless they're also running from C:\Server\web.exe on a Domain or Private network.

Method 4: Bulk Deployment from Configuration File

Deploy firewall rules for multiple applications at once using a configuration 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.
pause
endlocal
exit /b 1
)

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

:: Create sample config if it doesn't exist
if not exist "%ConfigFile%" (
echo # Firewall Rule Configuration > "%ConfigFile%"
echo # Format: RuleName^|ProgramPath^|Port^|Protocol^|Profiles >> "%ConfigFile%"
echo # Use 'any' for Port/Protocol to allow all >> "%ConfigFile%"
echo # Profiles: domain,private,public or any combination >> "%ConfigFile%"
echo WebServer^|C:\Server\web.exe^|443^|TCP^|domain,private >> "%ConfigFile%"
echo DatabaseServer^|C:\SQL\db.exe^|1433^|TCP^|domain >> "%ConfigFile%"
echo BackupAgent^|C:\Backup\agent.exe^|any^|any^|domain,private >> "%ConfigFile%"
echo [INFO] Created sample %ConfigFile% - edit before running again.
pause
endlocal
exit /b 0
)

echo [BULK DEPLOY] Processing firewall rules from %ConfigFile%...
echo.

set "CreatedCount=0"
set "SkippedCount=0"
set "ErrorCount=0"

for /f "usebackq tokens=1-5 delims=| eol=#" %%a in ("%ConfigFile%") do (
set "rName=%%a"
set "rPath=%%b"
set "rPort=%%c"
set "rProto=%%d"
set "rProfile=%%e"

:: Check if rule already exists
netsh advfirewall firewall show rule name="!rName!" >nul 2>&1
if !errorlevel! equ 0 (
echo [SKIP] !rName! - already exists
set /a SkippedCount+=1
) else (
:: Build the netsh command based on parameters
set "cmd=netsh advfirewall firewall add rule name="!rName!" dir=in action=allow program="!rPath!" enable=yes"

if /i "!rPort!" neq "any" (
set "cmd=!cmd! localport=!rPort!"
)
if /i "!rProto!" neq "any" (
set "cmd=!cmd! protocol=!rProto!"
)
if defined rProfile (
set "cmd=!cmd! profile=!rProfile!"
)

:: Execute
!cmd! >nul 2>&1
if !errorlevel! equ 0 (
echo [OK] !rName! - created
set /a CreatedCount+=1
echo [%date% %time%] CREATED "!rName!" program="!rPath!" port=!rPort!/!rProto! by %USERNAME% >> "%LogFile%"
) else (
echo [FAIL] !rName! - creation failed
set /a ErrorCount+=1
)
)
)

echo.
echo ==========================================
echo Created: !CreatedCount!
echo Skipped: !SkippedCount! (already existed)
echo Errors: !ErrorCount!
echo ==========================================

pause
endlocal

Configuration file format: Each line defines one rule with pipe-separated fields:

RuleName|ProgramPath|Port|Protocol|Profiles
WebServer|C:\Server\web.exe|443|TCP|domain,private

Use any for Port or Protocol to allow all ports/protocols for that program.

Method 5: Create and Verify (Installer Pattern)

A complete installer pattern that creates the rule, verifies it, and provides rollback instructions.

@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 "RuleName=MyApp_Inbound"
set "AppPath=C:\Program Files\MyApp\myapp.exe"
set "Port=8443"
set "Protocol=TCP"
set "Profiles=domain,private"
set "LogFile=%USERPROFILE%\firewall_changes.log"

echo ==========================================
echo FIREWALL RULE INSTALLER
echo ==========================================
echo.
echo Rule: %RuleName%
echo Program: %AppPath%
echo Port: %Port%/%Protocol% (Inbound, Allow)
echo Profiles: %Profiles%
echo.
echo ==========================================
echo.

:: Step 1: Check prerequisites
echo [1/4] Checking prerequisites...

if not exist "%AppPath%" (
echo [WARN] Program not found at specified path.
echo Rule will be created for future installation.
)

netsh advfirewall firewall show rule name="%RuleName%" >nul 2>&1
if !errorlevel! equ 0 (
echo [INFO] Rule already exists - no changes needed.
echo.
netsh advfirewall firewall show rule name="%RuleName%" | findstr /i "Rule Name: Enabled: Direction: Action: Profile: Program: LocalPort:"
pause
endlocal
exit /b 0
)

echo [OK] Prerequisites met.
echo.

:: Step 2: Create the rule
echo [2/4] Creating firewall rule...
netsh advfirewall firewall add rule name="%RuleName%" dir=in action=allow program="%AppPath%" localport=%Port% protocol=%Protocol% profile=%Profiles% enable=yes >nul 2>&1

if !errorlevel! neq 0 (
echo [ERROR] Failed to create rule.
pause
endlocal
exit /b 1
)

echo [OK] Rule created.
echo.

:: Step 3: Verify
echo [3/4] Verifying rule...
netsh advfirewall firewall show rule name="%RuleName%" >nul 2>&1
if !errorlevel! equ 0 (
echo [OK] Rule verified in firewall.
netsh advfirewall firewall show rule name="%RuleName%" | findstr /i "Rule Name: Enabled: Direction: Action: Profile: Program: LocalPort: Protocol:"
) else (
echo [ERROR] Verification failed - rule may not have been saved.
pause
endlocal
exit /b 1
)

echo.

:: Step 4: Log and provide rollback
echo [4/4] Logging and rollback information...
echo [OK] Logged to: %LogFile%
echo.
echo [%date% %time%] INSTALLED rule "%RuleName%" program="%AppPath%" port=%Port%/%Protocol% profiles=%Profiles% by %USERNAME% >> "%LogFile%"

echo ==========================================
echo INSTALLATION COMPLETE
echo ==========================================
echo.
echo To REMOVE this rule later:
echo netsh advfirewall firewall delete rule name="%RuleName%"
echo.
echo ==========================================

pause
endlocal

How to Avoid Common Errors

Wrong Way: Not Quoting Paths with Spaces

If your application is in C:\Program Files\MyApp\app.exe, omitting quotes causes the firewall to interpret C:\Program as the program path and Files\MyApp\app.exe as an invalid parameter.

Correct Way: Always wrap the program path in quotes:

:: Correct
program="C:\Program Files\MyApp\app.exe"

:: Wrong - breaks on spaces
program=C:\Program Files\MyApp\app.exe

Wrong Way: Using action=allow for All Profiles

By default, netsh adds rules to all profiles (Domain, Private, and Public). A database server rule active on a Public café network is a serious security risk.

Correct Way: Always specify the profile for server applications:

:: Correct - only trusted networks
profile=domain,private

:: Risky - includes public networks
(no profile specified = all profiles)

Wrong Way: Creating Duplicate Rules

Running the script twice creates two identical rules. Over time, this clutters the firewall with redundant entries.

Correct Way: Check if the rule exists before creating it:

netsh advfirewall firewall show rule name="%RuleName%" >nul 2>&1
if %errorlevel% equ 0 (
echo Rule already exists.
exit /b 0
)

Wrong Way: Running Without Administrator Privileges

Modifying the firewall's inbound security policy requires system-level permission. Without elevation, the command fails with confusing error messages.

Correct Way: Always check for elevation at the start:

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

Problem: Dynamic or Per-User Application Paths

If your app is installed in %AppData% or %LocalAppData%, netsh needs the fully resolved literal path because it doesn't expand environment variables.

Solution: Batch automatically expands %AppData% before passing it to netsh, so using the variable directly works:

:: This works - Batch resolves the variable first
set "AppPath=%LocalAppData%\MyApp\app.exe"
netsh ... program="%AppPath%"

However, be aware that the rule will be specific to the current user's path. On a multi-user system, each user would need their own rule.

Best Practices and Rules

1. Unique Naming Convention

Give your rules descriptive, searchable names with a consistent prefix:

CORP_WebServer_443_IN
CORP_Database_1433_IN
CORP_BackupAgent_IN

This makes it easy to find, audit, and delete rules later.

2. Always Check for Duplicates

Before adding a rule, verify it doesn't already exist. All methods above include this check automatically.

3. Specify the Profile

Always include profile=domain,private (or whichever profiles are appropriate) for server applications. Never leave server rules active on the Public profile unless absolutely necessary.

4. Prefer Program+Port Over Port-Only

A program-only rule allows the application on any port. A port-only rule allows any application on that port. Combining both (Method 3) provides the strongest security: only the specified program can receive traffic on the specified port.

5. Provide Rollback Instructions

Always document how to remove the rule if it's no longer needed. Method 5 includes rollback instructions in the output.

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

Creating inbound firewall rules for specific programs via Batch script is a professional way to manage application connectivity.

By moving from generic port-opening to targeted program authorization, you maintain a high standard of system security while ensuring your applications run without interruption.

This automated deployment is essential for setting up servers, development environments, and networked tools across your infrastructure.