Get-LocalUser: auditar cuentas locales en Windows con PowerShell

¿Sabes exactamente cuántas cuentas de usuario existen en tu Windows en este momento? Mucha gente no lo sabe — y esa es justamente la brecha que un atacante con acceso inicial va a explotar: crear una cuenta oculta con nombre genérico, habilitarla con contraseña y mantener persistencia silenciosa. Get-LocalUser es el cmdlet que expone todo esto en una sola línea.
Qué es Get-LocalUser
El Get-LocalUser forma parte del módulo Microsoft.PowerShell.LocalAccounts, disponible de forma nativa desde PowerShell 5.1 (Windows 10 / Server 2016 en adelante). Devuelve todos los usuarios locales de la máquina — cuentas creadas manualmente, cuentas integradas del sistema (Administrator, Guest, DefaultAccount, WDAGUtilityAccount) y cuentas vinculadas a una cuenta Microsoft.
A diferencia de net user, Get-LocalUser devuelve objetos estructurados que puedes filtrar, comparar y exportar con facilidad.
Listando todas las cuentas locales
Abre PowerShell como administrador y ejecuta:
Get-LocalUserLa salida incluye las columnas más importantes para una auditoría inmediata:
Name Enabled Description
---- ------- -----------
Administrador False Cuenta interna para administrar el equipo
DefaultAccount False Cuenta de usuario gestionada por el sistema
Guest False Cuenta interna para acceso de invitado
juan True
WDAGUtilityAccount False Cuenta usada por Windows Defender...Cualquier cuenta con Enabled: True y nombre no reconocido — o el propio Guest habilitado — merece investigación.
Filtrando por estado y propiedades
El cmdlet acepta filtro por nombre, o puedes usar Where-Object para condiciones más específicas:
# Solo cuentas habilitadas
Get-LocalUser | Where-Object { $_.Enabled -eq $true }
# Cuentas sin fecha de expiración (riesgo: sin ciclo de vida definido)
Get-LocalUser | Where-Object { $_.AccountExpires -eq $null -and $_.Enabled -eq $true }
# Cuentas que nunca iniciaron sesión
Get-LocalUser | Where-Object { $_.LastLogon -eq $null }Las cuentas habilitadas sin expiración y sin historial de inicio de sesión son una señal clara de una cuenta creada para persistencia o de una cuenta olvidada — ambas deberían desactivarse o eliminarse.
Verificando miembros de grupos locales
¿Quién está en el grupo Administradores?
Cualquier cuenta no autorizada en el grupo Administradores es un compromiso en curso — no una sospecha, una certeza.
Get-LocalGroupMember -Group "Administradores"En inglés (Administrators), dependiendo de la versión de Windows:
Get-LocalGroupMember -Group "Administrators"La salida muestra nombre, tipo (User/Group) y SID (Security Identifier). Compara el SID con el esperado cuando encuentres nombres desconocidos — a veces los atacantes crean cuentas con nombres similares a las existentes (admn en lugar de admin).
# Listar todos los grupos locales y sus miembros
Get-LocalGroup | ForEach-Object {
$group = $_.Name
Get-LocalGroupMember -Group $group | Select-Object @{n="Grupo";e={$group}}, Name, ObjectClass
}Detalles completos de una cuenta específica
Get-LocalUser -Name "juan" | Select-Object *Esto expone propiedades que no aparecen en el listado estándar:
- PasswordLastSet — cuándo se cambió la contraseña por última vez
- PasswordExpires — si la contraseña expira (las cuentas de servicio suelen tener esto deshabilitado)
- UserMayChangePassword — si el usuario puede cambiar su propia contraseña
- AccountExpires — fecha de expiración de la cuenta
- LastLogon — fecha del último inicio de sesión exitoso
Exportando a CSV: informe de auditoría completo
Para documentación o análisis posterior, exporta todo de una vez:
Get-LocalUser | Select-Object Name, Enabled, LastLogon, PasswordLastSet, AccountExpires, Description |
Export-Csv -Path "$env:USERPROFILE\Desktop\auditoria-cuentas-$(Get-Date -Format 'yyyyMMdd').csv" -NoTypeInformation -Encoding UTF8El archivo generado en el escritorio incluye la fecha en el nombre — útil para comparar capturas semanales e identificar cuentas nuevas entre un periodo y otro.
¿Cómo identificar cuentas creadas recientemente?
Get-LocalUser no expone directamente la fecha de creación de la cuenta, pero puedes cruzarlo con el registro de eventos de seguridad. El evento 4720 registra la creación de cuentas locales:
Get-WinEvent -FilterHashtable @{LogName="Security"; Id=4720} |
Select-Object TimeCreated, Message | Format-ListCombinado con Get-WinEvent para investigar eventos en Windows, puedes rastrear exactamente cuándo se creó cada cuenta y por qué proceso — un dato esencial en la respuesta a incidentes.
Desactivar o eliminar una cuenta sospechosa
¿Encontraste algo raro? Desactívala antes de investigar (es menos destructivo que eliminarla):
# Desactivar
Disable-LocalUser -Name "cuenta-sospechosa"
# Eliminar (irreversible)
Remove-LocalUser -Name "cuenta-sospechosa"Desactivar preserva el SID y el historial para análisis forense; eliminar borra el rastro. En un escenario de respuesta a incidentes, desactiva siempre primero.
Verificación rápida de cuentas integradas problemáticas
Tres verificaciones que todo sysadmin debería ejecutar en cualquier máquina nueva:
# ¿Guest habilitado? (nunca debería estarlo)
Get-LocalUser -Name "Guest" | Select-Object Name, Enabled
# ¿La cuenta Administrator integrada está activa?
Get-LocalUser -Name "Administrator" | Select-Object Name, Enabled, LastLogon
# Cuentas con la contraseña configurada para no expirar nunca
Get-LocalUser | Where-Object { $_.PasswordExpires -eq $null -and $_.Enabled -eq $true } |
Select-Object Name, PasswordLastSetGuest habilitado, la cuenta Administrator integrada activa sin motivo aparente y cuentas con contraseña permanente son hallazgos clásicos en auditorías de hardening. Para la lista completa de configuraciones que refuerzan Windows, revisa el post sobre Windows 11 más seguro: 10 configuraciones para activar hoy.
Get-LocalUser en red: auditando varias máquinas
El cmdlet no tiene parámetro -ComputerName (a diferencia de cmdlets más antiguos), pero funciona vía PowerShell Remoting:
$equipos = @("PC-01", "PC-02", "PC-03")
$resultado = Invoke-Command -ComputerName $equipos -ScriptBlock {
Get-LocalUser | Where-Object { $_.Enabled -eq $true } |
Select-Object Name, Enabled, LastLogon, @{n="Equipo";e={$env:COMPUTERNAME}}
}
$resultado | Export-Csv -Path "auditoria-red.csv" -NoTypeInformation -Encoding UTF8Esto genera un inventario consolidado de todas las cuentas habilitadas en varias estaciones — el punto de partida de cualquier auditoría de identidades en un entorno corporativo.
Para monitorear conexiones de red sospechosas en esas mismas máquinas, complementa con Get-NetTCPConnection para monitorear puertos abiertos en Windows. Y si necesitas revisar los registros de autenticación cruzándolos con eventos de seguridad, la guía de auditoría de registros de seguridad con PowerShell cubre ese flujo completo.
Auditar cuentas locales no es una tarea de una sola vez — debería ser rutina mensual en cualquier entorno. Una cuenta huérfana o creada por malware puede pasar desapercibida durante meses si nadie la verifica. Get-LocalUser tarda menos de un minuto en ejecutarse y puede mostrar exactamente lo que está esperando a ser encontrado.




Comentarios