How to List All Listening Ports in Batch Script
A "Listening Port" is an open invitation for other computers to connect to your machine. While some listening ports are essential for things like Remote Desktop (RDP), Web Hosting, or File Sharing, unnecessary open ports are a significant security risk. A Batch script can query the network stack to identify exactly which ports are currently waiting for a connection, which protocol they are using (TCP/UDP), and which software is responsible for holding that port open.
This guide will explain how to perform a deep audit of listening ports.
Method 1: The "Listening-Only" Audit (Netstat)
By combining the -ano flags with a specific findstr filter, we can strip away active browser connections and focus only on the ports that are open for "Incoming" traffic.
@echo off
setlocal
echo [SECURITY AUDIT] Identifying all LISTENING ports...
echo.
:: -a = All active connections
:: -n = Numerical format (prevents slow DNS lookups)
:: -o = Includes the Process ID (PID)
echo === TCP LISTENING PORTS ===
echo.
echo PROTO LOCAL ADDRESS STATE PID
echo --------------------------------------------------
netstat -ano | findstr /i "LISTENING"
echo --------------------------------------------------
echo.
echo === UDP OPEN PORTS ===
echo.
echo PROTO LOCAL ADDRESS PID
echo --------------------------------------------------
netstat -ano | findstr /C:" UDP "
echo --------------------------------------------------
pause
endlocal
UDP is connectionless - it never enters a "LISTENING" state. If you only filter for LISTENING, you will miss every open UDP port on the system entirely. UDP ports that appear in netstat output are bound and actively waiting for datagrams, making them functionally equivalent to "listening."
Method 2: Matching Ports to Service Names
A port number and a Process ID (PID) aren't always enough to identify a service. We can use the -b flag (Binary) to see the actual .exe name associated with the port.
The -b flag for netstat requires elevated privileges. If you run this as a standard user, you will get an error about needing elevation.
@echo off
setlocal
:: Check for Administrator privileges before running
net session >nul 2>&1
if %errorlevel% neq 0 (
echo [ERROR] This script requires Administrator privileges.
echo Right-click the script and select "Run as administrator."
pause
endlocal
exit /b 1
)
echo [REPORT] Mapping open ports to executables...
echo (This may take a momen: deep inspection in progress^)
echo.
set "TempFile=%TEMP%\netstat_b_output.tmp"
:: Capture output to temp file for reliable handling
:: -b is slow because it performs deep process inspection
netstat -anob > "%TempFile%" 2>&1
:: Display only LISTENING entries and their associated executables
:: The -b output places the executable name on the line BELOW the port line
:: We need both lines, so we filter for LISTENING and bracket lines [process.exe]
findstr /i "LISTENING \[" "%TempFile%"
echo.
:: Clean up
del "%TempFile%" >nul 2>&1
pause
endlocal
\[ as well?The netstat -b output format places the executable name in square brackets (e.g., [svchost.exe]) on the line below the port information. Filtering only for LISTENING would strip out the process names, defeating the purpose of using -b in the first place.
Method 3: Finding the Service Behind the Port
If the "owner" of a port is svchost.exe, you still don't know which Windows service it is. The svchost.exe process hosts dozens of different services. You can use tasklist /svc to resolve the specific service name.
@echo off
setlocal enabledelayedexpansion
echo [AUDIT] Resolving svchost.exe listening ports to service names...
echo.
echo PORT PID SERVICE(S^)
echo ================================================================
set "found=0"
for /f "tokens=2,5" %%a in ('netstat -ano ^| findstr /i "LISTENING"') do (
set "addr=%%a"
set "pid=%%b"
if defined pid if "!pid!" neq "0" (
:: Check if PID belongs to svchost.exe
tasklist /fi "pid eq !pid!" /fo csv /nh 2>nul | findstr /i "svchost.exe" >nul
if !errorlevel! equ 0 (
:: Get services hosted by this svchost PID
for /f "usebackq tokens=3* delims=," %%s in (`tasklist /svc /fi "pid eq !pid!" /fo csv /nh 2^>nul`) do (
set "services=%%~s"
set "services=!services:"=!"
:: Format columns
set "port=%%a "
set "port=!port:~0,26!"
set "line= !port! !pid! !services!"
echo !line!
set "found=1"
)
)
)
)
echo ================================================================
if "!found!"=="0" (
echo.
echo [INFO] No svchost.exe listening ports found, or insufficient permissions.
echo [NOTE] Run as Administrator for complete results.
)
echo.
echo [TIP] Manual lookup: tasklist /svc /fi "pid eq 1234"
pause
endlocal
Method 4: Full Security Report with Risk Assessment
Combines all methods into a single comprehensive audit that flags high-risk ports.
@echo off
setlocal enabledelayedexpansion
echo ============================================
echo LISTENING PORT SECURITY AUDIT
echo %COMPUTERNAME% - %date% %time%
echo ============================================
echo.
set "TempFile=%TEMP%\port_audit.tmp"
set "Warnings=0"
:: Capture full listening port list
netstat -ano | findstr "LISTENING" > "%TempFile%" 2>&1
:: Check for high-risk ports
echo --- Risk Assessment ---
echo.
:: Port 3389 - Remote Desktop
findstr /R ":3389[^0-9]" "%TempFile%" >nul 2>&1
if %errorlevel% equ 0 (
echo [ HIGH RISK ] Port 3389 (RDP^) is LISTENING - remote access enabled.
set /a Warnings+=1
) else (
echo [ OK ] Port 3389 (RDP^) is closed.
)
:: Port 445 - SMB File Sharing
findstr /R ":445[^0-9]" "%TempFile%" >nul 2>&1
if %errorlevel% equ 0 (
echo [!! HIGH RISK] Port 445 (SMB^) is LISTENING - file sharing exposed.
set /a Warnings+=1
) else (
echo [ OK ] Port 445 (SMB^) is closed.
)
:: Port 23 - Telnet (unencrypted)
findstr /R ":23[^0-9]" "%TempFile%" >nul 2>&1
if %errorlevel% equ 0 (
echo [ CRITICAL ] Port 23 (Telnet^) is LISTENING - unencrypted remote access!
set /a Warnings+=1
) else (
echo [ OK ] Port 23 (Telnet^) is closed.
)
:: Port 21 - FTP (unencrypted)
findstr /R ":21[^0-9]" "%TempFile%" >nul 2>&1
if %errorlevel% equ 0 (
echo [! WARNING ] Port 21 (FTP^) is LISTENING - consider SFTP instead.
set /a Warnings+=1
) else (
echo [ OK ] Port 21 (FTP^) is closed.
)
:: Check for 0.0.0.0 bindings (exposed to all interfaces)
echo.
echo --- Externally Exposed Ports (0.0.0.0^) ---
echo.
findstr "0.0.0.0" "%TempFile%"
echo.
echo ============================================
echo AUDIT COMPLETE - !Warnings! warning(s^) found
echo ============================================
:: Clean up
del "%TempFile%" >nul 2>&1
pause
endlocal
How to Avoid Common Errors
Wrong Way: Searching for "0.0.0.0" Exclusively
A common mistake is thinking only 0.0.0.0 ports are a risk. A port listening on 192.168.1.15 is still exposed to your entire local network.
Correct Way: Filter for the word LISTENING regardless of the IP address. This catches ports bound to your local IP, your Wi-Fi IP, and the universal 0.0.0.0 address.
Wrong Way: Only Filtering for "LISTENING"
UDP is connectionless and never enters a LISTENING state. Filtering only for LISTENING will miss every open UDP port on the system.
Correct Way: Search for LISTENING for TCP and separately for UDP to get a complete picture:
:: TCP listening ports
netstat -ano | findstr "LISTENING"
:: UDP open ports
netstat -ano | findstr /C:" UDP "
Wrong Way: Using netstat -b Without Filtering for Process Lines
The -b flag places the executable name on the line below the port information in square brackets. If you only filter for LISTENING, you lose all the process names.
Correct Way: Filter for both LISTENING and the bracket pattern:
netstat -anob | findstr /i "LISTENING \["
Wrong Way: Searching for a Port Without Boundary Matching
Searching for :80 will also match :8080, :800, :8000, etc.
Correct Way: Use regex with a non-digit boundary:
findstr /R ":80[^0-9]"
Problem: Temporary "TIME_WAIT" Ports
Sometimes netstat shows hundreds of ports in TIME_WAIT state. These are not listening ports; they are closed connections waiting for a final packet to clear.
Solution: Use findstr /i "LISTENING" to ignore these temporary states and focus only on the permanent server-style ports.
Best Practices and Rules
1. Check for Unknown Ports
Any port over 49152 is likely a dynamic (ephemeral) port used for a temporary outgoing connection. Focus your security audit on "Well Known Ports" (0–1023) and "Registered Ports" (1024–49151).
2. Verify Port 3389
If Port 3389 is in a LISTENING state, your machine is open for Remote Desktop. If you don't use RDP, this port should be closed immediately via Windows Settings or Group Policy.
3. Save a Golden Baseline
When setting up a new server, run this script and save the result as a baseline. If you audit the server a month later and see a new listening port, you can immediately investigate:
netstat -ano | findstr "LISTENING" > "baseline_%COMPUTERNAME%.txt"
4. Identify svchost.exe Ports
svchost.exe is a host process for dozens of Windows services. A listening port owned by svchost.exe could be anything from Windows Update to a print spooler. Always use tasklist /svc /fi "pid eq <PID>" to identify the specific service.
5. 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.
6. Common Listening Ports Reference
| Port | Service | Risk Notes |
|---|---|---|
| 21 | FTP | Unencrypted - use SFTP instead |
| 22 | SSH | Generally safe if properly configured |
| 23 | Telnet | Unencrypted - should be disabled |
| 80 | HTTP | Only if intentionally hosting a web server |
| 135 | RPC | Windows internal - common attack target |
| 443 | HTTPS | Secure web traffic |
| 445 | SMB | File sharing - frequent malware target |
| 3389 | RDP | Remote Desktop - high risk if exposed |
Conclusions
Listening ports are the "front doors" to your machine's network security. By moving beyond standard web browsing and identifying which background processes are waiting for connections, you gain the power to harden your system against potential exploits. This proactive visibility ensures that only legitimate, secure services are exposed to the network, maintaining the integrity of your Windows environment.