Cómo ver puertos abiertos en Windows con Get-NetTCPConnection

¿Sabes qué puertos está exponiendo tu Windows en este momento? Una conexión abierta que no autorizaste puede ser malware comunicándose con un servidor de comando, un servicio mal configurado o simplemente un programa que se olvidó de cerrar el socket. PowerShell tiene un cmdlet hecho para esto: Get-NetTCPConnection. Es más potente que el viejo netstat y permite filtrar, combinar y automatizar directo en el pipeline.
Get-NetTCPConnection vs netstat: ¿cuál es la diferencia?
netstat -ano existe desde el DOS y todavía funciona — pero la salida es texto plano, difícil de filtrar sin redirigir a findstr. Get-NetTCPConnection devuelve objetos de PowerShell, así que puedes usar Where-Object, Select-Object, Sort-Object e incluso exportar a CSV sin esfuerzo. La diferencia práctica: filtrar por proceso, estado y dirección remota al mismo tiempo — algo que en netstat exige dos comandos y regex a mano.
Comandos básicos para empezar
¿Cómo listar todas las conexiones activas en Windows?
Ejecuta Get-NetTCPConnection sin parámetros y verás todas las conexiones TCP del sistema, sin importar el estado. La columna State es el filtro más útil:
# Todas las conexiones, ordenadas por puerto local
Get-NetTCPConnection | Sort-Object LocalPort
# Solo lo que está escuchando (puertos abiertos esperando conexión)
Get-NetTCPConnection -State Listen | Select-Object LocalAddress, LocalPort, State | Sort-Object LocalPort
# Conexiones establecidas (alguien conectado ahora)
Get-NetTCPConnection -State Established | Select-Object LocalAddress, LocalPort, RemoteAddress, RemotePort
Los estados que más importan en el día a día:
- Listen — puerto abierto esperando conexión. Todo servicio activo tiene al menos uno.
- Established — conexión activa. Puede ser tu navegador, Teams, una actualización en segundo plano o malware.
- TimeWait / CloseWait — conexión cerrándose. Es normal que aparezca por algunos segundos después de cerrar un programa.
Descubrir qué proceso usa qué puerto
El campo OwningProcess devuelve el PID. Para llegar al nombre del ejecutable, crúzalo con Get-Process:
Get-NetTCPConnection -State Listen |
Select-Object LocalPort, OwningProcess |
Sort-Object LocalPort |
ForEach-Object {
$proc = Get-Process -Id $_.OwningProcess -ErrorAction SilentlyContinue
[PSCustomObject]@{
Puerto = $_.LocalPort
PID = $_.OwningProcess
Proceso = $proc.Name
Ejecutable = $proc.Path
}
}
La columna Ejecutable muestra la ruta completa del binario. Si aparece algo en %APPDATA%\Roaming o %TEMP% escuchando en un puerto inusual, es señal de alerta — un ejecutable legítimo de Windows rara vez corre desde esas carpetas.
Cómo detectar conexiones sospechosas
¿Cuál es la forma más rápida de ver conexiones externas activas?
Filtra por State Established y excluye direcciones locales — lo que quede son conexiones reales hacia servidores externos.
Get-NetTCPConnection -State Established |
Where-Object { $_.RemoteAddress -notmatch '^(127\.|::1|0\.0\.0\.0)' } |
Select-Object LocalPort, RemoteAddress, RemotePort, OwningProcess |
Sort-Object RemoteAddress
Para cada IP remota desconocida, resuelve el nombre:
[System.Net.Dns]::GetHostEntry("IP_AQUI").HostName
Mucho de lo que aparece es legítimo — telemetría de Windows, CDN, Office 365. Pero si aparece una IP de un país inusual con un proceso en una carpeta temporal, confirma la reputación en AbuseIPDB o VirusTotal antes de actuar. Este tipo de análisis encaja directamente con lo que tratamos en el post sobre auditoría de seguridad con PowerShell en Windows.
Para guardar una instantánea y comparar después de un incidente:
Get-NetTCPConnection | Export-Csv -Path "$env:USERPROFILE\Desktop\conexiones.csv" -NoTypeInformation
Verificando puertos UDP con Get-NetUDPEndpoint
TCP no es la única superficie. UDP aparece en DNS (puerto 53), VPN, juegos en línea y mucho más. El cmdlet equivalente es Get-NetUDPEndpoint:
# Todos los endpoints UDP activos
Get-NetUDPEndpoint | Select-Object LocalAddress, LocalPort, OwningProcess | Sort-Object LocalPort
La sintaxis es idéntica — mismos campos, misma lógica de cruce con Get-Process. La diferencia es que UDP no tiene estado (no existe "Established"), así que solo ves lo que está escuchando.
Automatizando una alerta simple
Si administras una máquina y quieres saber cuándo aparece un puerto nuevo en Listen, puedes correr este snippet vía tarea programada con schtasks:
$puertos_esperados = @(80, 443, 445, 135, 5040)
$nuevos = Get-NetTCPConnection -State Listen |
Where-Object { $_.LocalPort -notin $puertos_esperados }
if ($nuevos) {
$nuevos | Out-File "$env:TEMP\puertos_nuevos.txt"
# Aquí puedes agregar: envío de correo, escritura en el Event Log, etc.
}
Define $puertos_esperados con lo que es normal en tu entorno — todo lo que esté fuera de la lista se vuelve una alerta. Para registrar el evento en el log de Windows y cruzarlo con otra información de diagnóstico, combínalo con lo que vimos en el tutorial de investigación de errores con Get-WinEvent.
Conclusión
Get-NetTCPConnection es una herramienta de diagnóstico que todo administrador de Windows debería tener en su repertorio. Combinarla con Get-Process lleva menos de 10 líneas de PowerShell y entrega información que netstat solo daría con pipes y regex. Si estás empezando ahora, el post de introducción a PowerShell para principiantes cubre los conceptos de pipeline y filtrado que hacen posibles estos comandos.




Comentarios