Por diferentes motivos las cuentas de nuestros usuarios del AD se bloquean, ya sea de manera automática, por culpa del propio usuario o cualquier otra circunstancia.
Esto al final acaba en tiempo de gestión para los administradores y poca visibilidad e información para los usuarios.
El script que voy a pegar podría hacerse de muchas maneras, en las que aportarían más información, pero he querido que sea sencillo y que no necesite mirar el visor de eventos (que tendría que ir a cada uno de nuestros DC si no están centralizados) y sin crear ningún fichero en el disco.
Al final acaba enviando un email al usuario e informándole que ha sido bloqueado. Te puedes preguntar ¿cómo lo va a leer si tiene el usuario del AD bloqueado?.. buena pregunta. En mi caso las cuentas de correo no están gestionadas por el AD, en otras cuentas de proveedor pongo la externa (no tienen cuenta de correo interna), hay muchos casos.
Esta claro que para que funcione la cuenta del usuario del AD debe tener documentado el email. Otra opción es que siempre que se bloquee, se envíe email solo a IT o con copia a IT.
La idea es que solo envíe una alerta por hora, para no ser muy pesado. Con lo que es importante configurar bien el programador de tareas.
Esto va muy bien sobre todo con proveedores, se dejan sesiones abiertas en los servidores durante mucho tiempo y cuando van a conectar porque les necesitamos no pueden. Con esta medida les llega un email para que cierren las sesiones y eviten este tipo de bloqueo.
En mi caso a los proveedores les caduca la contraseña automáticamente cada 24h, así que si no cierran sesión de un día para otro, esto les supone un bloqueo ya que tienen la sesión abierta con una contraseña caducada.
El resultado sería el siguiente email:
Pasos
El Script :
# ============================================================ # SCRIPT: AD-Lockout-UserNotify.ps1 # ============================================================ # FUNCION: # Detecta usuarios bloqueados en Active Directory usando # el atributo lockoutTime, consultando directamente contra # el PDC Emulator para garantizar consistencia. # # ============================================================ Import-Module ActiveDirectory # ========================== # VARIABLES DEL USUARIO # ========================== $SMTPServer = "smtp.MiDominio.com" $SMTPPort = 25 $From = "Servodorenvio@MiDominio.com" # ========================== # OBTENCION DEL PDC # ========================== $domain = Get-ADDomain $PDC = $domain.PDCEmulator # ========================== # CONFIGURACION # ========================== $now = Get-Date $startWindow = $now.AddMinutes(-65) $endWindow = $now.AddMinutes(-2) $lockoutDuration = 60 $startFileTime = $startWindow.ToFileTime() $endFileTime = $endWindow.ToFileTime() # ========================== # BUSQUEDA # ========================== $lockedUsers = Get-ADUser -Server $PDC ` -Filter {lockoutTime -gt 0} ` -Properties lockoutTime,mail,displayName,lastLogonDate,lastBadPasswordAttempt,passwordLastSet foreach ($user in $lockedUsers) { if ($user.lockoutTime -gt 0 -and $user.mail) { $lockoutDate = [DateTime]::FromFileTime($user.lockoutTime) if ($user.lockoutTime -ge $startFileTime -and $user.lockoutTime -le $endFileTime) { if ($lockoutDate.AddMinutes($lockoutDuration) -gt $now) { # ========================== # CONVERSIONES SEGURAS # ========================== $LastLogon = if ($user.LastLogonDate) { $user.LastLogonDate } else { "No disponible" } $LastBadPwd = if ($user.LastBadPasswordAttempt) { $user.LastBadPasswordAttempt } else { "No disponible" } $PwdLastSet = if ($user.PasswordLastSet) { $user.PasswordLastSet } else { "No disponible" } $remaining = [math]::Round(($lockoutDate.AddMinutes($lockoutDuration) - $now).TotalMinutes) if ($remaining -lt 0) { $remaining = 0 } # ========================== # ASUNTO CORPORATIVO # ========================== $fecha = Get-Date -Format "yyyyMMdd - HH:mm" $Subject = "$fecha. SE. SEGURIDAD. Cuenta bloqueada: $($user.SamAccountName)" $mail = $($user.mail) # ========================== # EMAIL HTML # ========================== $html = @" <html> <body style='font-family:Calibri;font-size:14px'> <p>Hola $($user.displayName),</p> <p><b>Su cuenta ha sido bloqueada por un proceso automatico.</b></p> <p>Motivos habituales:</p> <ul> <li>Cambio de password reciente</li> <li>Password caducado</li> <li>Sesion activa con credenciales antiguas (muy probable)</li> <li>Servicios o aplicaciones con password antiguo</li> </ul> <p>Revise los equipos donde haya iniciado sesion y vuelva a autenticarse.</p> <p><b>Datos del bloqueo:</b></p> <ul> <li>Usuario: $($user.SamAccountName)</li> <li>Fecha bloqueo: $lockoutDate</li> <li>Tiempo restante bloqueo: $remaining minutos</li> </ul> <p><b>Informacion adicional:</b></p> <ul> <li>Ultimo logon: $LastLogon</li> <li>Ultimo intento fallido: $LastBadPwd</li> <li>Password cambiado: $PwdLastSet</li> </ul> <p>Contacte con IT de soporte@MiDominio.com si persiste.</p> </body> </html> "@ Send-MailMessage ` -SmtpServer $SMTPServer ` -Port $SMTPPort ` -From $From ` -To $mail ` -Subject $Subject ` -Body $html ` -BodyAsHtml } } } } |
|
Import-Module ActiveDirectory
$pdc = (Get-ADDomain).PDCEmulator
$lockedUsers = Search-ADAccount -LockedOut -Server $pdc
if ($lockedUsers) {
Write-Host "Hay usuarios bloqueados"
$lockedUsers | ForEach-Object {
Write-Host $_.SamAccountName
}
} else {
Write-Host "No hay usuarios bloqueados"
}
|











