How to Block an IP Address in Windows Firewall in Batch Script
If your server is experiencing a "Brute Force" attack or you notice suspicious traffic from a specific country or data center, you need to respond immediately. Blocking an IP address manually through the Windows Firewall GUI is slow and prone to human error during a crisis. A Batch script can use the netsh advfirewall command to instantly create a new firewall rule that drops all traffic from a specific IP. This allows you to respond to security threats in seconds and even automate your defense by feeding a list of malicious IPs into a script.
This guide will explain how to programmatically block IPs.
Method 1: The "Instant Block" Rule
This command creates a new inbound rule that explicitly blocks all traffic from a single remote IP.
@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 "TargetIP=103.45.12.9"
set "RuleName=BLOCK_%TargetIP%"
set "LogFile=%USERPROFILE%\firewall_block_log.txt"
echo [SECURITY] Blocking IP address: %TargetIP%...
echo.
:: Validate IP format - basic check for numbers and dots
set "ValidIP=0"
echo %TargetIP%| findstr /R "^[0-9][0-9]*\.[0-9][0-9]*\.[0-9][0-9]*\.[0-9][0-9]*$" >nul 2>&1
if !errorlevel! equ 0 set "ValidIP=1"
:: Also allow CIDR notation - e.g., 45.33.0.0/16
echo %TargetIP%| findstr /R "/[0-9]" >nul 2>&1
if !errorlevel! equ 0 set "ValidIP=1"
if "!ValidIP!"=="0" (
echo [ERROR] "%TargetIP%" does not appear to be a valid IP address
pause
endlocal
exit /b 1
)
:: 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. IP is already blocked.
pause
endlocal
exit /b 0
)
:: Create the blocking rule (both inbound AND outbound for full isolation)
:: Inbound: Stops the IP from connecting to us
netsh advfirewall firewall add rule name="%RuleName%_IN" dir=in action=block remoteip=%TargetIP% >nul 2>&1
set "InResult=!errorlevel!"
:: Outbound: Stops our machine from talking to the IP (prevents malware callbacks)
netsh advfirewall firewall add rule name="%RuleName%_OUT" dir=out action=block remoteip=%TargetIP% >nul 2>&1
set "OutResult=!errorlevel!"
if !InResult! equ 0 if !OutResult! equ 0 (
echo [SUCCESS] %TargetIP% is now BLOCKED (inbound + outbound).
) else (
echo [WARN] Partial failure - check rule creation manually.
if !InResult! neq 0 echo Inbound rule failed.
if !OutResult! neq 0 echo Outbound rule failed.
)
:: Log the action
echo [%date% %time%] BLOCKED %TargetIP% (inbound+outbound) by %USERNAME% >> "%LogFile%"
echo [LOGGED] Action recorded in: %LogFile%
pause
endlocal
Blocking only inbound stops the attacker from connecting to you, but if your machine is already compromised, malware could still phone home to the attacker's IP via outbound connections. Blocking both directions provides complete isolation.
Method 2: Blocking a Whole Range (Subnet)
If the attack is coming from an entire network (e.g., a data center), you can block the whole range using CIDR notation.
@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 "Subnet=45.33.0.0/16"
set "RuleName=BLOCK_SUBNET_45.33.x.x"
set "Reason=Suspicious data center traffic"
set "LogFile=%USERPROFILE%\firewall_block_log.txt"
echo [ACTION] Blocking entire subnet: %Subnet%
echo Reason: %Reason%
echo.
:: Check for existing rule
netsh advfirewall firewall show rule name="%RuleName%_IN" >nul 2>&1
if !errorlevel! equ 0 (
echo [INFO] Rule already exists. Subnet is already blocked.
pause
endlocal
exit /b 0
)
:: Block inbound
netsh advfirewall firewall add rule name="%RuleName%_IN" dir=in action=block remoteip=%Subnet% >nul 2>&1
if !errorlevel! equ 0 (
echo [OK] Inbound blocked.
) else (
echo [ERROR] Failed to create inbound rule.
)
:: Block outbound
netsh advfirewall firewall add rule name="%RuleName%_OUT" dir=out action=block remoteip=%Subnet% >nul 2>&1
if !errorlevel! equ 0 (
echo [OK] Outbound blocked.
) else (
echo [ERROR] Failed to create outbound rule.
)
:: Log
echo [%date% %time%] BLOCKED subnet %Subnet% - Reason: %Reason% - by %USERNAME% >> "%LogFile%"
echo.
echo [DONE] Subnet %Subnet% is now blocked.
pause
endlocal
/16blocks 65,536 addresses (e.g.,45.33.0.0through45.33.255.255).- Common masks:
/8= 16 million IPs,/16= 65,536 IPs,/24= 256 IPs,/32= single IP.
Method 3: Bulk Block from a File
Feed a list of malicious IPs into the script to block them all at once.
@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 "InputFile=blocklist.txt"
set "LogFile=%USERPROFILE%\firewall_block_log.txt"
:: Create sample blocklist if it doesn't exist
if not exist "%InputFile%" (
echo # Malicious IPs - one per line > "%InputFile%"
echo # Lines starting with # are comments >> "%InputFile%"
echo 103.45.12.9 >> "%InputFile%"
echo 45.33.0.0/16 >> "%InputFile%"
echo [INFO] Created sample %InputFile% - edit it with your target IPs.
echo.
)
echo [SECURITY] Bulk IP Blocking
echo Input: %InputFile%
echo.
set "BlockCount=0"
set "SkipCount=0"
set "ErrorCount=0"
for /f "usebackq tokens=* eol=#" %%i in ("%InputFile%") do (
set "ip=%%i"
:: Skip blank lines
if "!ip!" neq "" (
:: Remove any trailing spaces
for /f "tokens=*" %%t in ("!ip!") do set "ip=%%t"
:: Check if rule already exists
set "RuleName=BLOCK_!ip!_IN"
netsh advfirewall firewall show rule name="!RuleName!" >nul 2>&1
if !errorlevel! equ 0 (
echo [SKIP] !ip! - already blocked
set /a SkipCount+=1
) else (
:: Create block rules
netsh advfirewall firewall add rule name="BLOCK_!ip!_IN" dir=in action=block remoteip=!ip! >nul 2>&1
netsh advfirewall firewall add rule name="BLOCK_!ip!_OUT" dir=out action=block remoteip=!ip! >nul 2>&1
if !errorlevel! equ 0 (
echo [BLOCKED] !ip!
set /a BlockCount+=1
echo [%date% %time%] BLOCKED !ip! (bulk) by %USERNAME% >> "%LogFile%"
) else (
echo [ERROR] Failed to block !ip!
set /a ErrorCount+=1
)
)
)
)
echo.
echo ==========================================
echo Blocked: !BlockCount!
echo Skipped: !SkipCount! (already blocked)
echo Errors: !ErrorCount!
echo ==========================================
pause
endlocal
Tip: Maintain your blocklist.txt with comments explaining why each IP was added:
# SSH brute force - 2025-01-15
103.45.12.9
# Spam relay - 2025-01-20
45.33.0.0/16
Method 4: Removing Blocks (Unblock)
Once the threat has passed, remove the rules to restore access.
@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 "TargetIP=103.45.12.9"
set "LogFile=%USERPROFILE%\firewall_block_log.txt"
echo [ACTION] Unblocking %TargetIP%...
echo.
set "Removed=0"
:: Remove inbound rule
netsh advfirewall firewall delete rule name="BLOCK_%TargetIP%_IN" >nul 2>&1
if !errorlevel! equ 0 (
echo [OK] Inbound block removed.
set /a Removed+=1
) else (
echo [INFO] No inbound block rule found for %TargetIP%.
)
:: Remove outbound rule
netsh advfirewall firewall delete rule name="BLOCK_%TargetIP%_OUT" >nul 2>&1
if !errorlevel! equ 0 (
echo [OK] Outbound block removed.
set /a Removed+=1
) else (
echo [INFO] No outbound block rule found for %TargetIP%.
)
:: Also try the original single-rule naming convention
netsh advfirewall firewall delete rule name="BLOCK_MALICIOUS_IP_%TargetIP%" >nul 2>&1
if !errorlevel! equ 0 (
echo [OK] Legacy block rule removed.
set /a Removed+=1
)
echo.
if !Removed! gtr 0 (
echo [SUCCESS] %TargetIP% has been unblocked. !Removed! rules removed.
echo [%date% %time%] UNBLOCKED %TargetIP% by %USERNAME% >> "%LogFile%"
) else (
echo [INFO] No block rules found for %TargetIP%. It may not have been blocked.
)
pause
endlocal
Method 5: List All Currently Blocked IPs
View all block rules you've created to audit your current defenses.
@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
)
echo [AUDIT] All firewall BLOCK rules
echo.
echo RULE NAME REMOTE IP
echo ================================================================
set "BlockCount=0"
for /f "tokens=2 delims=:" %%a in ('netsh advfirewall firewall show rule name^=all dir^=in ^| findstr /i "Rule Name:" ^| findstr /i "BLOCK"') do (
echo %%a
set /a BlockCount+=1
)
echo ================================================================
echo.
echo Total block rules found: %BlockCount%
echo.
echo [TIP] To see full details of a specific rule:
echo netsh advfirewall firewall show rule name="RULE_NAME"
pause
endlocal
How to Avoid Common Errors
Wrong Way: Using action=allow by Mistake
A common copy-paste error is creating a rule that "allows" an IP when you intended to "block" it. This is especially dangerous because it creates a permanent hole in your firewall.
Correct Way: Double-check the action=block parameter. Consider adding a confirmation prompt in your script:
echo About to BLOCK %TargetIP% - this will drop ALL traffic.
set /p "confirm=Continue? (Y/N): "
if /i "%confirm%" neq "Y" exit /b 0
Wrong Way: Creating Duplicate Rules
If you run the script twice for the same IP, you create two identical rules. Over time, this clutters your firewall with hundreds of duplicates.
Correct Way: Check if the rule already 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: Blocking Only Inbound
An inbound-only block stops the attacker from reaching you, but if malware on your machine is already communicating with that IP, outbound traffic continues freely.
Correct Way: Block both directions for complete isolation:
netsh advfirewall firewall add rule name="BLOCK_IN" dir=in action=block remoteip=%IP%
netsh advfirewall firewall add rule name="BLOCK_OUT" dir=out action=block remoteip=%IP%
Wrong Way: Not Logging the Reason for the Block
A year from now, you'll see a rule called "BLOCK_103.45.12.9" and have no idea why it was created. Was it a legitimate threat or a false positive?
Correct Way: Log every block with a timestamp, reason, and username:
echo [%date% %time%] BLOCKED %IP% - Reason: SSH brute force - by %USERNAME% >> firewall_log.txt
Wrong Way: Running Without Administrator Privileges
Modifying firewall rules is a restricted system action. Without elevation, commands fail 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
)
Best Practices and Rules
1. Unified Blocking
If you are blocking multiple IPs from the same attack, you can create a single rule with multiple addresses instead of one rule per IP:
netsh advfirewall firewall add rule name="BLOCK_ATTACK_WAVE" dir=in action=block remoteip=192.168.1.1,192.168.1.2,10.0.0.5
This keeps your firewall rule list cleaner. However, individual rules per IP (Method 1) make it easier to unblock a specific address later.
2. Understand Direction
| Direction | Purpose | Use When |
|---|---|---|
dir=in | Blocks incoming connections from the IP | Stopping external attacks |
dir=out | Blocks outgoing connections to the IP | Preventing malware callbacks |
| Both | Complete isolation | Recommended for most blocks |
3. Log Everything
Always record the reason for every block in a log file. Include the date, IP, reason, and who created the rule. All methods above include automatic logging.
4. Review Blocks Periodically
Stale block rules accumulate over time. Set a reminder to review your block list monthly using Method 5. Remove rules for threats that are no longer relevant.
5. Use Descriptive Rule Names
Include the IP address in the rule name so you can quickly identify and manage rules:
BLOCK_103.45.12.9_IN
BLOCK_103.45.12.9_OUT
BLOCK_SUBNET_45.33.x.x_IN
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
Blocking an IP address via Batch script is a critical tool for rapid incident response. By moving beyond manual GUI interactions and utilizing the speed of netsh, you gain the ability to harden your network perimeter in real-time. This automated defense ensures that your Windows environment remains resilient against attacks and that you have the tools needed to maintain a high level of security across your infrastructure.