← Volver al blog

Cómo auditar cuentas inactivas en Active Directory con PowerShell

Un script sencillo para detectar usuarios y equipos que llevan meses sin iniciar sesión, exportarlos a CSV y deshabilitarlos con control.

Consola de PowerShell con un listado de cuentas de Active Directory

Las cuentas que nadie usa son una de las superficies de ataque más fáciles de reducir. Un antiguo empleado, un equipo retirado que nunca se sacó del dominio, una cuenta de servicio de un proyecto que terminó… Todas siguen siendo credenciales válidas.

Esta es la rutina que aplico para mantener el directorio limpio.

1. Encontrar las cuentas inactivas

Search-ADAccount ya hace el trabajo pesado. Con -AccountInactive y un -TimeSpan obtenemos las cuentas sin inicio de sesión en ese periodo:

Import-Module ActiveDirectory

$dias = 90
$usuarios = Search-ADAccount -AccountInactive -UsersOnly -TimeSpan "$dias.00:00:00" |
    Where-Object { $_.Enabled } |
    Get-ADUser -Properties LastLogonDate, Description, Department |
    Select-Object Name, SamAccountName, Department, LastLogonDate, DistinguishedName

$usuarios | Sort-Object LastLogonDate |
    Export-Csv ".\usuarios-inactivos-$(Get-Date -Format yyyyMMdd).csv" -NoTypeInformation -Encoding UTF8

Para equipos, basta con cambiar -UsersOnly por -ComputersOnly.

Ojo: LastLogonDate se basa en el atributo lastLogonTimestamp, que se replica con un retraso de hasta 14 días. Para una auditoría de 90 días es más que suficiente; para decisiones al día, consulta lastLogon en cada controlador de dominio.

2. Revisar antes de tocar nada

Nunca deshabilito directamente desde el script. El CSV pasa por una revisión rápida con RR. HH. o con el responsable de cada departamento, porque siempre aparecen casos especiales: bajas largas, cuentas de servicio que se autentican de otra forma, etc.

3. Deshabilitar y mover a una OU de cuarentena

Con el listado validado:

$ouCuarentena = "OU=Deshabilitados,DC=empresa,DC=local"

Import-Csv .\usuarios-validados.csv | ForEach-Object {
    Disable-ADAccount -Identity $_.SamAccountName
    Set-ADUser -Identity $_.SamAccountName -Description "Deshabilitada $(Get-Date -Format yyyy-MM-dd) por inactividad"
    Move-ADObject -Identity $_.DistinguishedName -TargetPath $ouCuarentena
}

Deshabilitar en lugar de borrar permite revertir el cambio en segundos. La eliminación definitiva la dejo para pasados 30 días en cuarentena.

Resumen

Paso Frecuencia Responsable
Informe de inactivas Mensual IT
Validación Mensual Responsable de área
Borrado definitivo Tras 30 días IT

Programado como tarea mensual, este proceso tarda cinco minutos y deja el directorio mucho más limpio y auditable.