Buscar Cuentas de Usuario Inactivas En Su Dominio
Active Directory es un servicio de directorio que mantiene información sobre usuarios, equipos y objetos relacionados. Así es como puedes encontrar cuentas de usuario inactivas.
Es una base de datos de información relacional que necesita mantenimiento a lo largo del tiempo para ser útil y relevante. Un directorio dejará de utilizar cuentas. Encontrar esas cuentas en Active Directory no es tan fácil como parece a primera vista. Vamos a buscar cuentas de usuario inactivas y a automatizarlas para eliminarlas.
Definir Criterios de búsqueda
Definamos lo que se necesita para este proceso. Nuestro objetivo es localizar las cuentas de los empleados que no han iniciado sesión en la red durante un período prolongado. Siempre he utilizado 90 o 120 días como una buena medida para consultar la inactividad, pero ese número puede ser tan bajo como 14 días. Debe decidir qué es lo correcto para su organización. 90 días proporciona un colchón lo suficientemente grande como para permitir que las personas salgan de la oficina por vacaciones, emergencias familiares o bajas médicas prolongadas. Una vez que las cuentas alcancen los 90 días de inactividad, queremos deshabilitar esas cuentas y moverlas a una unidad organizativa independiente.
Definir lo que buscamos primero nos permite construir un conjunto de reglas simple a seguir. Nuestro conjunto de reglas se ve así:
- Busque y deshabilite cuentas activas que no tengan actividad de inicio de sesión durante 90 días.
- Mueva cada cuenta deshabilitada a la unidad organizativa de Usuarios deshabilitados
- Marque cada usuario deshabilitado con un comentario de que un proceso automatizado lo deshabilitó.
Buscar propiedades de inactividad de la cuenta
Cada cuenta de usuario tiene varios atributos que contienen información de inicio de sesión. Queremos encontrar atributos que muestren la última hora de inicio de sesión. Si podemos encontrar esos atributos, podemos usarlos para consultar cuentas que no han iniciado sesión desde una fecha determinada. Podemos usar PowerShell para mostrar todo el conjunto de reglas y elegir un atributo con el que trabajar.
Get-ADUser es el cmdlet más utilizado para mostrar información de usuario. Puede usar Get-ADObject y Search-ADAccount, pero Get-ADUser es el mejor cmdlet para nuestra tarea. Para mostrar todas las propiedades de usuario, necesitamos agregar-properties * a la sintaxis del cmdlet. Si omitimos esa sintaxis, solo veremos las propiedades predeterminadas, que son solo 10 propiedades.
Get-ADUser Michael_Kanakos -Properties *
volvemos una larga lista de campos de nuestra consulta (más de 150!). Podemos buscar atributos que contengan palabras particulares usando comodines. Esto nos ayuda a localizar atributos que pueden ser útiles para nuestra tarea. Queremos encontrar información de inicio de sesión, así que busquemos atributos que contengan la palabra Inicio de sesión.
Una vez que le digamos a PowerShell que obtenga todas las propiedades, sería útil si pudiéramos limitar la lista de propiedades para mostrar solo las propiedades que coinciden con el inicio de sesión de word. Seleccionar objeto proporciona la capacidad de hacer una coincidencia de comodín y limitar nuestros resultados. El carácter / (llamado «la tubería») toma los resultados a la izquierda y los pasa a Select-Object. A continuación, Select-Object realiza la coincidencia de comodines y, a continuación, limita los resultados en función de nuestros criterios de comodines.
Get-ADUser username -Properties * | Select-Object *logon*
BadLogonCount : 0
lastLogon : 132181280348543735
LastLogonDate : 11/11/2019 9:08:45 PM
lastLogonTimestamp : 132179981259860013
logonCount : 328
LogonWorkstations :
MNSLogonAccount : False
SmartcardLogonRequired : False
Los resultados variarán un poco en función del nivel funcional del dominio de Active Directory. Mi búsqueda devuelve ocho atributos. Tres parecen prometedores: LastLogon, LastLogonDate y LastLogonTimeStamp. Algunos de los valores pueden parecer un poco extraños si no está familiarizado con la forma en que Active Directory almacena información de fecha/hora en ciertos atributos. Algunos datos de fecha son información tradicional de fecha y hora, y algunos se guardan como «ticks».»
Los valores de fecha y hora de PowerShell y. NET Framework representan las fechas como el número de marcas desde las 12:00 a.M. del 1 de enero de 0001. Las garrapatas equivalen a una diezmillonésima de segundo, lo que significa que hay 10.000 garrapatas por milisegundo. Hay cmdlets matemáticos que pueden convertir las marcas en un formato de fecha estándar.
PowerShell muestra la marca de verificación real que representa la fecha / hora. Si se siente cómodo convirtiendo garrapatas al formato de fecha, puede ver esos campos en Usuarios y Equipos de Active Directory o en el Centro de Administración de Active Directory. En ambas aplicaciones, las marcas se representan como un formato de fecha y hora.
ADUser-Logon-Properties
Atributos de inicio de sesión explicados
Nuestra búsqueda encontró varias propiedades que muestran información de inicio de sesión de fecha/hora. Dos propiedades tienen la misma fecha y hora y una no. ¿Qué está pasando aquí?
La variación en la información de fecha y hora es por diseño y está en su lugar para proteger los DC de ser aplastados por el tráfico de replicación que intenta mantener toda la información de inicio de sesión sincronizada. La propiedad LastLogon se actualiza cada vez que se autentica, pero los datos se almacenan en el DC con el que se autenticó y no se replican en los otros DC. Las propiedades LastLogonTimeStamp y LastLogonDate se replican en todos los DC, pero la replicación solo ocurre con poca frecuencia.
Si miramos las fechas, podemos ver cómo la replicación retrasada podría afectar nuestra consulta. Observe que LastLogonTimeStamp está en realidad dos días atrasado en este ejemplo. Cada vez que un usuario inicia sesión de forma interactiva, toca un recurso compartido de archivos de red o realiza otras actividades que requieren que la red autentique la cuenta, almacena información de inicio de sesión en Active Directory. Si el DC replicara esos datos CADA VEZ QUE alguien tocara algo en la red, el DC podría verse abrumado en un entorno grande. El resultado es que parte de la información de inicio de sesión es precisa pero no se replica, y parte de la información de inicio de sesión se replica, pero solo ocasionalmente.
Para nuestros requisitos, no necesitamos la marca de tiempo de inicio de sesión EXACTA. Solo necesitamos encontrar cuentas que no hayan iniciado sesión en mucho tiempo (más de 90 días). Cualquier valor puede ser útil, incluso si la fecha está desactivada por unos días. Si usamos mis fechas de inicio de sesión como ejemplo, la hora consultada podría ser 11/11 o 11/13, dependiendo del valor que utilicemos. Avance rápido tres meses y asumo que nunca volví a conectarme. Una fecha se marcaría como inactiva por tener más de 90 días, y un campo no. Pero si configurara este proceso para que se ejecute mensualmente, cogería la cuenta la próxima vez que la comprobáramos. Esa es la parte crítica. Si hacemos esto regularmente, podemos usar cualquiera de los campos siempre y cuando revisemos constantemente.
Utilicé la propiedad LastLogonDate por dos razones. Primero, ya es un valor de fecha, por lo que no tengo que lidiar con convertir el valor. Segundo, es un valor replicado, y eso me hace la vida más fácil. Si usara LastLogon, tendría fechas que no están actualizadas para las personas que se autentican con otros controladores de dominio en mi red. Tendría que consultar el DC local para cada usuario para obtener la última marca de tiempo, y eso es mucho trabajo por hacer y no es muy eficiente.
Para obtener la información de una sola cuenta, el código es simple.
get-aduser Michael_Kanakos -properties LastLogonDate | Select-Object Name, LastLogonDate
Name LastLogonDate
---- -------------
mkanakos 11/11/2019 9:08:45 PM
Hacer esto para todos mis usuarios solo requiere un poco más de código. Necesitamos usar un filtro para consultar todas las cuentas de usuario.
Get-ADUser -filter * -properties LastLogonDate | Select-Object Name, LastLogonDate
Ahora vamos a encontrar solo las cuentas con una fecha de inicio de sesión anterior a 90 días. Necesitamos la fecha actual guardada para usarla como operador de comparación.
$date = (get-date).AddDays(-90)
Get-ADUser -Filter {LastLogonDate -lt $date} -properties LastLogonDate | Select-Object Name, LastLogonDate
Este código recupera a todos los usuarios que no han iniciado sesión durante 90 días. Guardamos la fecha de hace 90 días en una variable. Podemos crear un filtro de anuncios para encontrar inicios de sesión menores a esa fecha. A continuación, necesitamos agregar el requisito de consultar solo cuentas activas. En este ejemplo, estoy usando splatting para hacer que el código sea más legible porque la sintaxis es muy larga. Salpicar cmdlets de anuncios puede ser complicado, por lo que también he mostrado la versión de formato largo de la sintaxis debajo del ejemplo de salpicaduras.
$date = (get-date).AddDays(-90)
$paramhash = @{
Filter = "LastLogonDate -lt $date -and Enabled -eq $true"
Properties = 'LastLogonDate'
}
$SelectProps = 'Name','LastLogonDate','Enabled','DistinguishedName'
$InactiveUsers = Get-Aduser @paramhash | Select-Object $SelectProps
$InactiveUsers = Get-ADUser -Filter {LastLogonDate -lt $date -and Enabled -eq $true} -properties LastLogonDate, DistinguishedName | Select-Object Name, LastLogonDate, Enabled, DistinguishedName
Esto nos da a nuestros usuarios inactivos que están habilitados. Guardamos los resultados en una variable para su reutilización. La propiedad distinguishedName se necesita más adelante. Una vez que encontremos a los usuarios, podemos trabajar en nuestro siguiente paso: deshabilitar las cuentas. Utilizamos el cmdlet Set-ADUser para realizar cambios en la cuenta de usuario de AD.
$Today = Get-Date
$DisabledUsers = (
$InactiveUsers | Foreach-object {
Set-User $_.DistinguishedName -Enabled $false -Description "Acct disabled on $Today via Inactive Users script"}
)
Hemos deshabilitado nuestras cuentas de usuario. Es hora de trasladarlos a una nueva unidad organizativa. Para nuestro ejemplo, usaremos la unidad organizativa denominada Disabled-Users. El nombre distintivo de esta unidad organizativa es «OU=Disabled-Users,DC=Contoso,DC=Com» Usamos el cmdlet Move-ADObject para mover usuarios a la unidad organizativa de destino.
$DisabledUsers | ForEach-Object {
Move-ADObject $_.DistinguishedName -TargetPath "OU=Disabled-Users,DC=Contoso,DC=Com"}
En nuestro paso final, utilizamos Move-ADObject para mover usuarios a una nueva unidad organizativa. Ahora tenemos el código básico necesario para realizar una tarea automatizada fiable y repetible. Entonces, ¿qué sigue? Eso depende de sus necesidades individuales. Este código puede y debe configurarse para que se ejecute automáticamente a la misma hora cada mes. Una forma fácil de hacerlo es crear un Trabajo programado para ejecutar el código mensualmente.
Hay más que podríamos agregar a este código para mejorarlo. El código para la comprobación de errores y los campos de información de usuario adicionales serían dos adiciones útiles. La mayoría de los equipos que ejecutan este tipo de tareas generan un informe de lo que se deshabilitó para que alguien lo revise, por lo que los campos adicionales variarán. Puede incluir más campos de Active Directory para que un informe sea más útil. Podríamos llevar esta tarea un paso más allá creando otra tarea para eliminar a los usuarios discapacitados después de 6 meses.
Resolver solicitudes de automatización desafiantes es mucho más fácil cuando las tareas se dividen en piezas manejables. Comenzamos con los requisitos y construimos nuestra sintaxis en pequeños pasos; confirmando que cada paso funciona antes de intentar agregar otra variable. Al hacer esto, hicimos que esta tarea fuera fácil de entender y, con suerte, una gran experiencia de aprendizaje.