🔍 Monitorización de logins en Windows con PowerShell: detecta intrusiones antes de que sea tarde

hace 5 meses

monitorización de logins en Windows

Monitoriza logins en Windows con PowerShell

Monitorización de logins en Windows es la capa defensiva que convierte el registro de seguridad —activo pero ignorado en la mayoría de los equipos— en una alarma real. El tiempo medio que un atacante permanece dentro de un sistema comprometido sin ser detectado se mide en meses, no en horas, y la causa casi siempre es la misma: nadie revisa ese registro.

Este artículo documenta un único script de PowerShell que automatiza el análisis de los eventos 4624, 4625, 4672 y 4740 mediante tres tareas programadas, detectando fuerza bruta, password spraying, Pass-the-Hash y logins fuera de horario sin instalar herramientas externas. Según los informes de referencia sobre tiempo de permanencia de atacantes, la mediana de detección sin monitorización activa asciende a semanas o meses. Incluye además el mapeo completo a MITRE ATT&CK y la integración con SIEM y Sysmon. Para profundizar en el resto de medidas de bastionado del sistema operativo, conviene revisar también la recopilación de guías de seguridad en Windows para blindar el equipo frente a accesos no autorizados.

⚡ Respuesta rápida

Sí, con un único script de PowerShell puedes monitorizar los logins de Windows en minutos: activa la auditoría de Logon, Special Logon y Account Lockout por GUID, y analiza cuatro eventos clave — 4625 (login fallido), 4624 (login exitoso), 4672 (privilegios especiales) y 4740 (cuenta bloqueada). Tres tareas programadas (inicio, logon y cada hora) automatizan el análisis y detectan fuerza bruta, password spraying y campañas lentas repartidas en semanas, dejando constancia en un CSV histórico. El script es de solo lectura: no modifica cuentas, firewall ni servicios.

💡 Definición rápida

Monitorización de logins en Windows: Práctica de activar la política de auditoría de Windows y analizar de forma continua los eventos de autenticación registrados en el log Security (4624, 4625, 4672 y 4740) para detectar fuerza bruta, password spraying, escalación de privilegios y accesos anómalos, reduciendo el tiempo de detección de un ataque de semanas o meses a horas.

💡 Resumen rápido

🔍 Monitorización de logins en Windows: detecta intrusos con PowerShell

Sin esta vigilancia, un atacante con credenciales válidas puede pasar meses dentro del sistema sin dejar rastro visible.

  • 4 eventos clave: 4624, 4625, 4672 y 4740
  • 5 ataques detectables: fuerza bruta, password spraying, credential stuffing, escalación y movimiento lateral
  • Script con 3 tareas programadas: inicio, logon y cada hora
  • CSV histórico para detectar campañas lentas repartidas en semanas
  • Solo lectura: no modifica cuentas, firewall ni servicios
🔍 ¿Cómo monitorizar los logins de Windows con PowerShell? Guarda un script como archivo .ps1 en C:\Scripts y ejecútalo como administrador. Activa la auditoría de Logon, Special Logon y Account Lockout por GUID (evita el error 0x00000057 de auditpol en Windows en español) y analiza cuatro eventos clave: 4625 (login fallido), 4624 (login exitoso), 4672 (privilegios especiales) y 4740 (cuenta bloqueada). Tres tareas programadas automatizan el análisis dejando constancia en un CSV histórico que detecta campañas lentas repartidas en semanas. Tras la primera ejecución hay que reiniciar el equipo una vez para que las tareas queden visibles y activas.

📅 Publicado: 26 de febrero de 2026 · 🕒 Tiempo de lectura: 19 minutos

Monitorización de logins Windows

📌 ¿Qué es la monitorización de logins en Windows?

🔍 ¿Qué es la monitorización de logins en Windows y qué detecta?

La monitorización de logins en Windows consiste en activar la política de auditoría y analizar de forma continua los eventos del log Security. Con un script PowerShell detecta:

  • Fuerza bruta y password spraying contra cuentas locales o de dominio (eventos 4625)
  • Accesos exitosos en horarios anómalos (evento 4624 entre 00:00 y 06:00)
  • Escalaciones de privilegios mediante el evento 4672
  • Cuentas bloqueadas (4740) tras superar el umbral de intentos
  • Campañas lentas de credential stuffing gracias al CSV histórico ilimitado

El dwell time medio sin monitorización activa asciende a semanas o meses según M-Trends. Con este script se reduce a horas.

La monitorización de logins en Windows consiste en activar la política de auditoría y analizar de forma continua los eventos que el sistema registra cada vez que un usuario intenta autenticarse. Windows escribe esta información en el log Security, accesible desde PowerShell con Get-WinEvent.

  • ✔ Detecta fuerza bruta y password spraying contra cuentas locales o de dominio.
  • ✔ Identifica accesos exitosos en horarios anómalos.
  • ✔ Registra escalaciones de privilegios mediante el evento 4672.
  • ✔ Captura cuentas bloqueadas (4740) tras superar el umbral de intentos.
  • ✔ Convierte el análisis puntual en serie histórica con CSV.
  • ✔ Sienta la base para integración con SIEM (Splunk, Elastic, Wazuh, Sentinel).
⏱️ ¿Qué es el dwell time y por qué importa? El dwell time mide cuánto tarda un equipo defensivo en detectar a un atacante. Los informes de M-Trends sitúan la mediana entre 11 y 21 días sin SIEM, pero asciende a meses en endpoints sin monitorización activa. Una correcta monitorización de logins en Windows reduce el MTTD (Mean Time To Detect) de meses a horas.

El credential stuffing que detecta este script explota credenciales previamente filtradas en brechas de datos. Activa las alertas de Dark Web Monitoring para saber si tus credenciales ya circulan en mercados clandestinos antes de que un atacante las use contra tu sistema.


🔢 Los cuatro eventos clave

🔍 ¿Qué eventos de Windows hay que monitorizar para detectar intrusiones?

Los cuatro Event IDs críticos del log Security para detectar intrusiones en Windows:

  • 4624 — Login exitoso (MITRE T1078): detecta accesos en horario inhabitual o desde IP desconocida
  • 4625 — Login fallido (MITRE T1110): decenas de fallos seguidos indican fuerza bruta; fallos distribuidos en muchas cuentas indican password spraying
  • 4672 — Privilegios especiales asignados (T1078/T1068): cuenta normal con derechos sensibles = escalación de privilegios
  • 4740 — Cuenta bloqueada (T1110): la política de bloqueo ha actuado — investiga la causa inmediatamente

Cada Event ID de esta tabla está mapeado a su técnica correspondiente en el framework MITRE ATT&CK, la referencia estándar del sector para clasificar tácticas y técnicas de ataque. Para la configuración detallada de las subcategorías de auditoría por GPO en entornos de dominio, consulta la documentación oficial de Microsoft sobre políticas de auditoría.

Event IDSignificadoQué indica un volumen anómaloMITRE
4624Login exitosoLogin en horario inhabitual o IP desconocidaT1078
4625Login fallidoDecenas de fallos seguidos = fuerza brutaT1110
4672Privilegios especiales asignadosCuenta normal con derechos sensibles = escalaciónT1078/T1068
4740Cuenta bloqueadaPolítica de bloqueo activadaT1110

🔐 Logon Types: qué significa cada tipo en el evento 4624

TypeNombreCuándo apareceRiesgo
2InteractiveLogin en consola física🟡 Acceso físico no autorizado
3NetworkSMB, recurso compartido🔴 Movimiento lateral, Pass-the-Hash
4BatchTareas programadas con credenciales🟠 Persistencia (T1053)
5ServiceInicio de servicios🟠 Servicios maliciosos (T1543.003)
7UnlockDesbloqueo de sesión🟡 Acceso físico tras ausencia
8NetworkCleartextCredenciales en claro (IIS Basic Auth)🔴 Credenciales expuestas
10RemoteInteractiveRDP, Terminal Services🔴 RDP brute force
11CachedInteractiveLogin con credenciales cacheadas🟡 Pass-the-Hash en cache
🚨 Los tres Logon Types más sospechosos: Type 3 sin justificación = Pass-the-Hash; Type 8 = credenciales en claro; Type 10 desde IP externa = RDP no autorizado. Investiga inmediatamente cualquiera de estos tres en cuentas sin acceso remoto autorizado.

🚨 5 ataques que detecta la monitorización de logins en Windows

AtaquePatrón en el logVentanaMITRE
Fuerza brutaDecenas de 4625 desde la misma IP en minutosInmediataT1110.001
Password sprayingPocos 4625 contra muchos usuarios distintosHora a díaT1110.003
Credential stuffing4624 exitoso desde IP nueva sin 4625 previosInmediataT1078.004
Escalación de privilegios4672 en cuenta sin derechos especiales habitualesInmediataT1068
Movimiento lateral4624 con LogonType 3 entre equipos sin justificaciónDía a semanaT1021

Para cerrar el vector de fuerza bruta y password spraying que detecta este script, aplica la guía técnica de hardening de cuentas Windows: política de contraseñas, bloqueo y auditoría con PowerShell — ambos scripts son complementarios: el hardening bloquea el ataque y este script lo detecta y lo registra.


Script completo de monitorización de logins Windows con 3 tareas programadas

⚙️ Script completo de monitorización de logins en Windows con 3 tareas programadas

⚠️ Antes de ejecutar: No modifica contraseñas, cuentas, firewall ni servicios. Solo lee el registro de seguridad y amplía su tamaño. Genera log en C:\Logs\monitor-logins.log y CSV en C:\Logs\monitor-logins-historico.csv.

📅 Las 3 tareas programadas de la monitorización de logins en Windows

TareaDisparadorFrecuenciaPropósito
Monitor-Logins-InicioAl iniciar WindowsCada arranqueReaplica la auditoría y analiza las últimas 24h tras reinicio o actualización
Monitor-Logins-LogonAl iniciar sesiónCada loginAnaliza eventos inmediatamente tras el logon
Monitor-Logins-HorariaCada hora24 veces/díaVigilancia continua; detecta campañas lentas

La misma metodología de script + tareas programadas está documentada en el script completo para endurecer Windows 11 con 7 tareas programadas — ambos scripts son complementarios y pueden ejecutarse juntos para un hardening y monitorización integral.

📥 Cómo guardar y ejecutar el script paso a paso

📁 ¿Por qué este script va en C:\Scripts y no en el Escritorio? Este script crea tres tareas programadas que guardan, dentro de sí mismas, la ruta exacta desde la que se ejecuta un script auxiliar de análisis. Si ese script auxiliar no está siempre en el mismo sitio, las tareas dejan de encontrarlo y fallan en silencio. Por eso, cualquier script de esta guía que cree tareas programadas se guarda siempre en C:\Scripts, una carpeta fija que no se mueve ni se borra por accidente.

1. Cómo guardar el script de monitorización de logins en Windows como .ps1 en C:\Scripts

  1. Si no la tienes ya, crea la carpeta C:\Scripts: abre el Explorador de archivos, ve a C:\, clic derecho → Nuevo → Carpeta, y ponle de nombre Scripts.
  2. Abre el Bloc de notas (tecla Windows → escribe "Bloc de notas" → Enter).
  3. Pega dentro el código del script completo (lo tienes al final de esta sección).
  4. Ve a Archivo → Guardar como. Rellena estos tres campos:
    • Dónde guardarlo: navega hasta C:\Scripts (no el Escritorio).
    • Nombre de archivo: escribe monitor-logins.ps1 (con el .ps1 al final, escrito por ti).
    • Tipo: cambia el desplegable de "Documentos de texto (*.txt)" a "Todos los archivos (*.*)". Si no lo cambias, el archivo se guarda como monitor-logins.ps1.txt aunque hayas escrito ".ps1".
  5. Pulsa Guardar.
  6. Comprueba que salió bien: en C:\Scripts, el icono del archivo debe verse como una pantalla de consola azul, no como una hoja de papel.

2. Cómo se ejecuta

Nunca hagas doble clic sobre el archivo ni pegues el código directamente en la consola de PowerShell.

  1. Pulsa la tecla Windows, escribe PowerShell.
  2. Haz clic derecho sobre "Windows PowerShell" y elige "Ejecutar como administrador". Confirma si te lo pide.
  3. En la ventana azul que se abre, escribe estas tres líneas una a una, pulsando Enter después de cada una:
    Set-ExecutionPolicy -Scope Process -ExecutionPolicy Bypass
    cd C:\Scripts
    dir *.ps1
    Con dir *.ps1 confirmas el nombre exacto del archivo tal como quedó guardado.
  4. Ejecuta el script con este comando:
    powershell -NoExit -ExecutionPolicy Bypass -File "monitor-logins.ps1"
  5. Apenas verás texto en pantalla al principio, mientras se activa la auditoría y se amplía el log Security: el script usa Start-Transcript, que captura esa salida en C:\Logs\monitor-logins.log. Es normal, espera a que continúe.
  6. Después sí verás en pantalla las 3 líneas de confirmación de las tareas programadas ([OK] Tarea '...' creada).
  7. Al terminar te pedirá pulsar Enter para cerrar.

3. Reiniciar el equipo (obligatorio)

Reinicia el equipo una vez tras la primera ejecución. El Programador de tareas de Windows tarda en sincronizar visualmente las tareas recién creadas: hasta que reinicias, es posible que Get-ScheduledTask y el Programador de tareas gráfico no muestren las 3 tareas nuevas, aunque ya existan y estén correctamente registradas. Es un comportamiento normal, no un fallo del script. La tarea Monitor-Logins-Inicio se ejecutará automáticamente en ese mismo reinicio y generará la primera fila del CSV histórico.

Tras reiniciar, verifica:

Get-ScheduledTask -TaskName "Monitor-Logins-*" | Select-Object TaskName, TaskPath, State

Deben aparecer las 3 tareas, todas con TaskPath = \SeguridadEnMiPC\Monitor-Logins\ y State = Ready.

Si algo falla

  • El script no muestra nada en pantalla al principio: normal, esa parte se registra en el log. Revisa con Get-Content C:\Logs\monitor-logins.log -Tail 30.
  • Dice que la ejecución de scripts está deshabilitada: ejecuta primero Set-ExecutionPolicy -Scope Process -ExecutionPolicy Bypass.
  • "El término 'finally' no se reconoce..." o errores de try/catch: pegaste el código directo en la consola en vez de guardarlo como archivo. Guárdalo como .ps1 (paso 1) y ejecútalo con -File (paso 2).
  • "El argumento '...' para el parámetro -File no existe": el nombre no coincide con el archivo guardado. Ejecuta dir *.ps1 en C:\Scripts y usa el nombre exacto que aparece ahí.
  • Errores 0x00000057 en auditpol: ya resuelto en este script — usa GUIDs de subcategoría ({0CCE9215-...}, {0CCE921B-...}, {0CCE9217-...}) en vez de nombres como "Logon" o "Special Logon", que en Windows en español no siempre coinciden exactamente y provocan ese error.
  • Las 3 tareas no aparecen en Get-ScheduledTask ni en el Programador de tareas gráfico, aunque el log confirme que se crearon: problema de caché del Programador de tareas tras crear/recrear carpetas de tareas en la misma sesión. Reinicia el equipo (paso 3) — el servicio Schedule no se puede reiniciar manualmente, Windows lo bloquea por ser un servicio crítico.
  • Los contadores del CSV muestran 0: la auditoría estaba desactivada antes de ejecutar el script y solo registra eventos a partir de ese momento. Espera a que se dispare la tarea horaria o de logon y vuelve a revisar.
  • Si al hacer clic derecho no aparece "Ejecutar como administrador": asegúrate de buscar "Windows PowerShell" (la app), no dentro de una carpeta. Prueba también "Terminal" en Windows 11.
# ============================================
# Monitorizacion de logins Windows
# Eventos 4624, 4625, 4672 y 4740
# y mantenimiento con tres tareas programadas
# Requiere: PowerShell como Administrador
# Ruta fija: C:\Scripts\monitor-logins.ps1
# ============================================
try {
# 0. Verificar privilegios de administrador
if (-not ([Security.Principal.WindowsPrincipal] `
[Security.Principal.WindowsIdentity]::GetCurrent()).IsInRole(`
[Security.Principal.WindowsBuiltInRole]::Administrator)) {
Write-Host "[X] Ejecuta este script como Administrador." -ForegroundColor Red
exit
}
# 1. Asegurar que el script vive en C:\Scripts (ruta que usaran las tareas programadas)
$carpetaScripts = "C:\Scripts"
if (-not (Test-Path $carpetaScripts)) {
New-Item -ItemType Directory -Path $carpetaScripts -Force | Out-Null
}
$rutaFinal = "$carpetaScripts\monitor-logins.ps1"
if ($PSCommandPath -and ($PSCommandPath -ne $rutaFinal)) {
Copy-Item -Path $PSCommandPath -Destination $rutaFinal -Force
Write-Host "[i] Copia del script guardada en $rutaFinal para uso de las tareas programadas." -ForegroundColor Cyan
}
$carpetaLogs = "C:\Logs"
if (-not (Test-Path $carpetaLogs)) {
New-Item -ItemType Directory -Path $carpetaLogs -Force | Out-Null
}
Start-Transcript -Path "$carpetaLogs\monitor-logins.log" -Append | Out-Null
# 2. Habilitar auditoria: Logon (4624/4625), Special Logon (4672) y Account Lockout (4740)
# GUID en vez de nombre de subcategoria: evita el error 0x00000057 en Windows en espanol
auditpol /set /subcategory:"{0CCE9215-69AE-11D9-BED3-505054503030}" /success:enable /failure:enable | Out-Null
auditpol /set /subcategory:"{0CCE921B-69AE-11D9-BED3-505054503030}" /success:enable /failure:enable | Out-Null
auditpol /set /subcategory:"{0CCE9217-69AE-11D9-BED3-505054503030}" /success:enable /failure:enable | Out-Null
Write-Host "[OK] Auditoria habilitada: Logon, Special Logon y Account Lockout (eventos 4624/4625/4672/4740)." -ForegroundColor Green
# 3. Ampliar el log Security a 200 MB para no perder historico por rotacion
wevtutil sl Security /ms:209715200
Write-Host "[OK] Log Security ampliado a 200 MB." -ForegroundColor Green
# 4. Registrar esta ejecucion en el CSV historico
# Export-Csv -Append crea el archivo con su fila de encabezado real si aun no existe,
# asi que no hace falta escribir a mano una fila-encabezado de relleno.
$csvHistorico = "$carpetaLogs\monitor-logins-historico.csv"
if (-not (Test-Path $csvHistorico)) {
Write-Host "[i] El CSV historico se creara en la primera ejecucion del script de analisis." -ForegroundColor Yellow
} else {
Write-Host "[i] El CSV historico ya existia." -ForegroundColor Yellow
}
# 5. Crear script auxiliar de analisis (usado por Inicio/Logon/Horaria)
$carpetaAuxiliar = "C:\ProgramData\SeguridadEnMiPC\MonitorLogins"
if (-not (Test-Path $carpetaAuxiliar)) { New-Item -ItemType Directory -Path $carpetaAuxiliar -Force | Out-Null }
$scriptAnalizar = "$carpetaAuxiliar\analizar-logins.ps1"
$contenidoAnalizar = @'
# Reaplicar auditoria por si se reseteo (actualizacion, GPO, etc.)
auditpol /set /subcategory:"{0CCE9215-69AE-11D9-BED3-505054503030}" /success:enable /failure:enable | Out-Null
auditpol /set /subcategory:"{0CCE921B-69AE-11D9-BED3-505054503030}" /success:enable /failure:enable | Out-Null
auditpol /set /subcategory:"{0CCE9217-69AE-11D9-BED3-505054503030}" /success:enable /failure:enable | Out-Null
$csvHistorico = "C:\Logs\monitor-logins-historico.csv"
$ventana = (Get-Date).AddHours(-24)
$e4624 = Get-WinEvent -FilterHashtable @{LogName='Security'; Id=4624; StartTime=$ventana} -ErrorAction SilentlyContinue
$e4625 = Get-WinEvent -FilterHashtable @{LogName='Security'; Id=4625; StartTime=$ventana} -ErrorAction SilentlyContinue
$e4672 = Get-WinEvent -FilterHashtable @{LogName='Security'; Id=4672; StartTime=$ventana} -ErrorAction SilentlyContinue
$e4740 = Get-WinEvent -FilterHashtable @{LogName='Security'; Id=4740; StartTime=$ventana} -ErrorAction SilentlyContinue
$ipsFallidas = @()
$cuentasFallidas = @()
$fueraHorario = 0
# LogonType 2 = interactivo, 10 = RDP/interactivo remoto.
# Excluye tipos 3 (red), 4 (batch), 5 (servicio), etc. para que el contador
# refleje accesos humanos reales y no las tareas programadas de SYSTEM.
$tiposLogonHumano = @('2', '10')
foreach ($evento in $e4625) {
[xml]$xml = $evento.ToXml()
$datos = $xml.Event.EventData.Data
$ip = ($datos | Where-Object { $_.Name -eq 'IpAddress' }).'#text'
$cuenta = ($datos | Where-Object { $_.Name -eq 'TargetUserName' }).'#text'
if ($ip -and $ip -ne '-') { $ipsFallidas += $ip }
if ($cuenta -and $cuenta -notmatch '\$$') { $cuentasFallidas += $cuenta }
}
foreach ($evento in $e4624) {
[xml]$xml = $evento.ToXml()
$datos = $xml.Event.EventData.Data
$tipoLogon = ($datos | Where-Object { $_.Name -eq 'LogonType' }).'#text'
if ($tipoLogon -in $tiposLogonHumano) {
$hora = $evento.TimeCreated.Hour
if ($hora -ge 0 -and $hora -lt 6) { $fueraHorario++ }
}
}
$ipsUnicas = ($ipsFallidas | Select-Object -Unique).Count
$cuentasUnicas = ($cuentasFallidas | Select-Object -Unique).Count
# Fuerza bruta: 20+ fallos en 24h desde la misma IP
$alertaFuerzaBruta = $false
$ipsFallidas | Group-Object | Where-Object { $_.Count -ge 20 } | ForEach-Object { $alertaFuerzaBruta = $true }
# Password spraying: 5+ cuentas distintas con fallos en la misma ventana
$alertaSpraying = ($cuentasUnicas -ge 5)
$fila = [PSCustomObject]@{
Fecha = Get-Date
LoginsExitosos = ($e4624 | Measure-Object).Count
LoginsFallidos = ($e4625 | Measure-Object).Count
PrivilegiosEspeciales = ($e4672 | Measure-Object).Count
CuentasBloqueadas = ($e4740 | Measure-Object).Count
IPsUnicasFallidas = $ipsUnicas
CuentasUnicasFallidas = $cuentasUnicas
AlertaFuerzaBruta = $alertaFuerzaBruta
AlertaSpraying = $alertaSpraying
LoginsFueraHorario = $fueraHorario
}
$fila | Export-Csv -Path $csvHistorico -NoTypeInformation -Encoding UTF8 -Append
Add-Content -Path "C:\Logs\monitor-logins.log" -Value "$(Get-Date) - [OK] Analisis completado: $($fila.LoginsExitosos) exitos, $($fila.LoginsFallidos) fallos, $($fila.CuentasBloqueadas) bloqueos"
if ($alertaFuerzaBruta) {
Add-Content -Path "C:\Logs\monitor-logins.log" -Value "$(Get-Date) - [ALERTA] Posible fuerza bruta: 20+ fallos en 24h desde una misma IP"
}
if ($alertaSpraying) {
Add-Content -Path "C:\Logs\monitor-logins.log" -Value "$(Get-Date) - [ALERTA] Posible password spraying: $cuentasUnicas cuentas distintas con fallos en 24h"
}
'@
Set-Content -Path $scriptAnalizar -Encoding UTF8 -Value $contenidoAnalizar
Write-Host "[OK] Script de analisis creado en $scriptAnalizar" -ForegroundColor Green
# 6. Carpeta de tareas programadas
$carpetaTareas = "\SeguridadEnMiPC\Monitor-Logins\"
# 7. Tarea: verificar auditoria y analizar en cada arranque
if (-not (Get-ScheduledTask -TaskName "Monitor-Logins-Inicio" -TaskPath $carpetaTareas -ErrorAction SilentlyContinue)) {
$a1 = New-ScheduledTaskAction -Execute "powershell.exe" -Argument "-ExecutionPolicy Bypass -WindowStyle Hidden -File `"$scriptAnalizar`""
$t1 = New-ScheduledTaskTrigger -AtStartup
Register-ScheduledTask -TaskName "Monitor-Logins-Inicio" -TaskPath $carpetaTareas -Action $a1 -Trigger $t1 -RunLevel Highest -User "SYSTEM" -Force | Out-Null
Write-Host "[OK] Tarea 'Monitor-Logins-Inicio' creada (al arrancar Windows)." -ForegroundColor Green
} else { Write-Host "[i] La tarea 'Monitor-Logins-Inicio' ya existia." -ForegroundColor Yellow }
# 8. Tarea: analizar en cada inicio de sesion
if (-not (Get-ScheduledTask -TaskName "Monitor-Logins-Logon" -TaskPath $carpetaTareas -ErrorAction SilentlyContinue)) {
$a2 = New-ScheduledTaskAction -Execute "powershell.exe" -Argument "-ExecutionPolicy Bypass -WindowStyle Hidden -File `"$scriptAnalizar`""
$t2 = New-ScheduledTaskTrigger -AtLogOn
Register-ScheduledTask -TaskName "Monitor-Logins-Logon" -TaskPath $carpetaTareas -Action $a2 -Trigger $t2 -RunLevel Highest -User "SYSTEM" -Force | Out-Null
Write-Host "[OK] Tarea 'Monitor-Logins-Logon' creada (al iniciar sesion)." -ForegroundColor Green
} else { Write-Host "[i] La tarea 'Monitor-Logins-Logon' ya existia." -ForegroundColor Yellow }
# 9. Tarea: analizar cada hora
if (-not (Get-ScheduledTask -TaskName "Monitor-Logins-Horaria" -TaskPath $carpetaTareas -ErrorAction SilentlyContinue)) {
$a3 = New-ScheduledTaskAction -Execute "powershell.exe" -Argument "-ExecutionPolicy Bypass -WindowStyle Hidden -File `"$scriptAnalizar`""
$t3 = New-ScheduledTaskTrigger -Once -At (Get-Date) -RepetitionInterval (New-TimeSpan -Hours 1) -RepetitionDuration (New-TimeSpan -Days 3650)
Register-ScheduledTask -TaskName "Monitor-Logins-Horaria" -TaskPath $carpetaTareas -Action $a3 -Trigger $t3 -RunLevel Highest -User "SYSTEM" -Force | Out-Null
Write-Host "[OK] Tarea 'Monitor-Logins-Horaria' creada (cada hora)." -ForegroundColor Green
} else { Write-Host "[i] La tarea 'Monitor-Logins-Horaria' ya existia." -ForegroundColor Yellow }
# 10. Verificacion final (busqueda por nombre, mas fiable que por TaskPath si el cache no esta sincronizado)
Write-Host "`n=== Tareas programadas activas ===" -ForegroundColor Cyan
Get-ScheduledTask -TaskName "Monitor-Logins-*" | Select-Object TaskName, TaskPath, State | Format-Table -AutoSize
Write-Host "[OK] Monitorizacion de logins activada y protegida con 3 tareas programadas." -ForegroundColor Green
Write-Host " Script principal: $rutaFinal" -ForegroundColor Gray
Write-Host " Script de analisis: $scriptAnalizar" -ForegroundColor Gray
Write-Host " Log: C:\Logs\monitor-logins.log" -ForegroundColor Gray
Write-Host " CSV historico: C:\Logs\monitor-logins-historico.csv" -ForegroundColor Gray
Write-Host "`n[i] Reinicia el equipo. Tras reiniciar, verifica con:" -ForegroundColor Yellow
Write-Host " Get-ScheduledTask -TaskName 'Monitor-Logins-*' | Select-Object TaskName, TaskPath, State" -ForegroundColor Gray
}
catch {
Write-Host "`n[X] Error: $($_.Exception.Message)" -ForegroundColor Red
}
finally {
Stop-Transcript | Out-Null
Read-Host "`nPulsa Enter para salir"
}

🔎 Cómo verificar que la monitorización está funcionando

🔍 ¿Cómo verificar que la monitorización de logins en Windows está funcionando?

Tres comprobaciones para confirmar que el script está activo:

  1. Log de instalación: Get-Content C:\Logs\monitor-logins.log -Tail 30 debe mostrar [OK] Auditoria habilitada y [OK] Log Security ampliado. La línea [OK] Analisis completado solo aparece tras la primera ejecución de una tarea programada (típicamente al reiniciar el equipo), no durante la instalación manual.
  2. 3 tareas en estado Ready: Get-ScheduledTask -TaskName "Monitor-Logins-*" | Select-Object TaskName, TaskPath, State (fiable solo después de reiniciar el equipo tras instalar)
  3. Auditoría activa: auditpol /get /subcategory:"{0CCE9215-69AE-11D9-BED3-505054503030}" debe mostrar Success and Failure

Si el CSV muestra AlertaFuerzaBruta = True o AlertaSpraying = True tras la primera fila de datos, investiga inmediatamente con el protocolo de respuesta.

💡 Comandos de verificación (PowerShell como administrador):

Get-Content C:\Logs\monitor-logins.log -Tail 30
Get-ScheduledTask -TaskName "Monitor-Logins-*" | Select-Object TaskName, TaskPath, State
auditpol /get /subcategory:"{0CCE9215-69AE-11D9-BED3-505054503030}"
Import-Csv C:\Logs\monitor-logins-historico.csv | Select-Object -Last 5

Las 3 tareas deben estar en estado Ready. El CSV solo tendrá filas de datos después de que se dispare al menos una tarea (arranque, logon u horaria).


✅ Checklist post-instalación

Verifica estos 6 puntos para confirmar que la monitorización está activa (después de reiniciar):

  • 3 tareas en estado Ready, sin duplicados, en taskschd.msc → SeguridadEnMiPC → Monitor-Logins
  • auditpol /get /subcategory:"{0CCE9215-69AE-11D9-BED3-505054503030}" muestra Success and Failure
  • Log Security con capacidad ≥ 200 MB
  • Log en C:\Logs\monitor-logins.log sin errores críticos
  • CSV en C:\Logs\monitor-logins-historico.csv con al menos una fila de datos
  • Revisas el CSV semanalmente

✔ 6/6 = monitorización activa y operativa · ✘ menos de 4 = revisar log e instalación · si las tareas no aparecen justo tras instalar, reinicia el equipo antes de dar la instalación por fallida


🚨 Protocolo de respuesta ante una alerta de la monitorización de logins en Windows

Si el CSV muestra AlertaFuerzaBruta = True o AlertaSpraying = True:

  • Identifica la IP: Get-WinEvent -FilterHashtable @{LogName='Security';Id=4625} -MaxEvents 50 | Select-Object TimeCreated, Message
  • Si IP externa: bloquea en firewall: New-NetFirewallRule -DisplayName "Block IP" -Direction Inbound -RemoteAddress IP -Action Block
  • Si IP interna: aísla el equipo y comprueba si está comprometido
  • Cambia la contraseña de la cuenta atacada desde un equipo limpio
  • Comprueba si hay 4624 exitosos posteriores desde la misma IP
  • Exporta evidencias: wevtutil epl Security C:\Backup\security-$(Get-Date -f yyyyMMdd).evtx
  • Refuerza política de bloqueo: net accounts /lockoutthreshold:5 /lockoutduration:30

Si la IP atacante se repite en distintas ventanas de 24 horas, un bloqueo puntual con New-NetFirewallRule no es suficiente. Consulta la guía para restringir el acceso por IP en Windows y convertir ese bloqueo reactivo en una política de firewall permanente y auditable.


⚠️ Riesgos y efectos de la monitorización de logins en Windows

Función¿Afectada?Detalle
Inicio de sesión local🟢 NoNo toca cuentas ni contraseñas
Inicio de Windows🟢 NoLa tarea se ejecuta en background tras el arranque
Banca online y web🟢 NoNo toca DNS, hosts ni la pila de red
Política de auditoría🟡 Sí (positivo)Se activan tres subcategorías; más eventos en el log
Tamaño del log Security🟡 AumentaAmpliado a 200 MB automáticamente por el script
Carga de CPU (3 tareas)🟡 MínimaMenos de 5 segundos por ejecución; menos de 2 min/día

🛠️ Integración de la monitorización de logins en Windows con SIEM y herramientas avanzadas

La monitorización de logins en Windows con este script cubre el análisis local; para entornos con varios equipos, conviene centralizarla en una de estas plataformas de gestión de eventos de seguridad, que agregan y correlacionan los registros de autenticación de todos los sistemas:

Plataforma SIEMTipoCosteIdeal para
Microsoft SentinelCloud (Azure)💰 Pago por consumoEntornos Microsoft 365 / Azure AD
Splunk Enterprise SecurityOn-prem / Cloud💰💰 ComercialGrandes empresas
Elastic Stack (ELK)Open source + Enterprise🟢 Free / 💰 PaidEquipos técnicos
WazuhOpen source HIDS+SIEM🟢 100% gratisPymes y autoalojamiento
Graylog OpenOpen source🟢 Free / 💰 EnterpriseCentralización de logs

🛠️ Herramientas complementarias a la monitorización de logins en Windows

  • 🔬 Sysmon — telemetría detallada de procesos, red y registro. Complemento esencial al log Security.
  • 📊 Chainsaw — análisis rápido de .evtx con reglas Sigma preconfiguradas.
  • 🔍 DeepBlueCLIPowerShell de SANS para análisis forense del log Security.
  • 📋 Hayabusa — threat hunting sobre logs .evtx con reglas Sigma.
  • 📡 Windows Event Forwarding (WEF) — centralización nativa sin agentes adicionales.
  • 🔐 Sigma Rules — reglas de detección traducibles a cualquier SIEM.

🆚 Sistema sin monitorización de logins en Windows vs con monitorización activa

CaracterísticaSin monitorizaciónCon monitorización
Política de auditoría🔴 Parcialmente activa🟢 Logon, Special Logon y Account Lockout activas
Detección de fuerza bruta🔴 Ninguna🟢 Alerta automática al superar 20 fallos en 24h
Detección de password spraying🔴 Ninguna🟢 Alerta al detectar 5+ cuentas distintas con fallos
Logins en horario anómalo🔴 Sin distinción🟢 Marcados entre 00:00 y 06:00
Historia para análisis🔴 Solo el tamaño del log🟢 CSV histórico ilimitado
Dwell time del atacante🔴 Semanas a meses🟢 Horas a días
Persistencia tras actualizaciones🔴 auditpol puede resetearse🟢 3 tareas reactivan la auditoría automáticamente

🏁 Conclusión

La diferencia entre un equipo que detecta a un atacante en 24 horas y otro que tarda meses no está en el antivirus ni en el firewall: está en si alguien ha implementado la monitorización de logins en Windows o no. Activar tres subcategorías con auditpol, ampliar el log a 200 MB y dejar tres tareas programadas vigilando los cuatro Event IDs críticos cuesta diez minutos la primera vez y cero a partir de la segunda. La vigilancia de accesos es solo una capa más: complétala con la guía completa de ciberseguridad para detectar y frenar intrusiones antes de que causen daño, que abarca también malware, phishing y exposición de credenciales.

🔐 Resumen de acciones recomendadas

  • Guarda el script como monitor-logins.ps1 en C:\Scripts y ejecútalo como administrador con -File
  • Reinicia el equipo (obligatorio) para que el Programador de tareas sincronice las 3 tareas
  • Verifica con Get-Content C:\Logs\monitor-logins.log -Tail 30
  • Confirma las 3 tareas con Get-ScheduledTask -TaskName "Monitor-Logins-*"
  • Revisa el CSV histórico cada semana
  • Investiga inmediatamente cualquier alerta de fuerza bruta o spraying

❓ Preguntas frecuentes

¿Qué diferencia hay entre 4624 y 4625?

👉 El 4624 registra un login exitoso; el 4625 registra un intento fallido. Ambos son necesarios para correlacionar fuerza bruta (muchos 4625) con compromiso exitoso (un 4624 tras los 4625).

¿Qué es el evento 4672 y por qué es crítico?

👉 Se dispara cuando Windows asigna privilegios especiales (SeDebugPrivilege, SeTakeOwnershipPrivilege) tras un login. Un 4672 inesperado en una cuenta normal es la firma típica de una escalación reciente.

¿Las 3 tareas ralentizan el equipo?

👉 No. Cada ejecución dura menos de 5 segundos en background como SYSTEM. La carga combinada suma menos de 2 minutos de CPU al día. La monitorización de logins en Windows con este método tiene un impacto prácticamente nulo en el rendimiento.

¿Cómo consulto las tareas programadas?

👉 PowerShell: Get-ScheduledTask -TaskName "Monitor-Logins-*" | Select-Object TaskName, TaskPath, State. GUI: Win+R → taskschd.msc → Biblioteca del Programador de tareas → SeguridadEnMiPC → Monitor-Logins.

¿Qué hago si veo una alerta de fuerza bruta?

👉 Identifica la IP con Get-WinEvent -FilterHashtable @{LogName='Security';Id=4625} -MaxEvents 50 | Select-Object TimeCreated, Message. Bloquea si es externa, aísla si es interna, y cambia la contraseña de la cuenta atacada.

¿Este script sustituye a un EDR?

👉 No. Un EDR cubre telemetría de procesos, integridad de memoria y análisis de comportamiento. La monitorización de logins en Windows con este script cubre la capa de autenticación, el punto ciego más común. Para un equipo doméstico es suficiente; para una empresa, es complementaria.

¿Cómo envío los eventos a un SIEM?

👉 Para escalar la monitorización de logins en Windows más allá de un solo equipo, la forma nativa es Windows Event Forwarding (WEF): ejecuta winrm quickconfig en el cliente y configura la suscripción con wecutil cs. Alternativamente, usa agentes como Winlogbeat (Elastic) o Splunk Universal Forwarder para reenviar el log Security a una plataforma SIEM centralizada.

Autor

Entusiasta de la seguridad informática con años de experiencia en protección de sistemas Windows y defensa contra amenazas digitales. Apasionado por la tecnología y la privacidad, comparto en este blog consejos prácticos, análisis detallados y guías paso a paso para que cualquier usuario pueda fortalecer la seguridad de su PC y su vida digital

Deja una respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *

Tu puntuación: Útil

Subir