Skip to main content

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
Why list UDP separately?

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.

Administrator Rights Required

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
Why filter for \[ 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

PortServiceRisk Notes
21FTPUnencrypted - use SFTP instead
22SSHGenerally safe if properly configured
23TelnetUnencrypted - should be disabled
80HTTPOnly if intentionally hosting a web server
135RPCWindows internal - common attack target
443HTTPSSecure web traffic
445SMBFile sharing - frequent malware target
3389RDPRemote 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.