Control KPI de AD via PowerShell
 

Toda red de datos basada en dominios de Windows, tiende a lo largo del tiempo a expandirse, por lo que es necesario comenzar a monitorizar ciertos aspectos que le permitan a los administradores obtener indices mensurables que les proporcionen indicaciones de posibles problemas o vulnerabilidades.

Estos indices se conocen como KPI (Key Perfomance Indicators), no son un estandard, sino que se generan y utilizan para cada tipo de red, sin embargo, ciertos indicadores pueden considerarse como básicos, como por ej.

  • Miembros Administradores de Dominio
  • Usuarios cuya contraseña no caduda
  • Grupos Vacios
  • Cuentas de Equipos fuera de uso
  • Cuentas de usuario fuera de uso

Introduccion

Estos controles deberían aplicarse en todos los ambientes donde se utilizan dominios, y son de gran ayuda para los administradores, asi como para el control por parte de las autoridades de sistemas.

Para aquellos que vienen administrando servidores desde la época de nuestro buen amigo NT4 (jubilado hace rato...), no será novedad, sin embargo y seguramente tendrán sus scripts en VB, pero para ponernos a tono con los deseos de MSFT, veremos como realizar estas consultas via PowerShell

El script powershell a continuación es válido para Windows Server 2008 R2, 2012 y 2012 R2, y requiere el módulo de powershell para Active Directory.

Script

Bien.. el script en powershell que mencionaba, es as aslgo asi como el siguiente...

La mayoría de las líneas de este script son autoexplicativas, y algunas utilizan diferentes mecanismos porque es necesario y otras solo para mostrar que lo mismo puede hacerse de diferentes formas, pero aqui va la explicación...

Lo primero que hacemos en el script es la declaración de variables

  • $strDomain: Dominio para el cual se realizarán las consultas.
  • $intInactiveDays: Cantidad de días que deben transcurrir sin un logon para considerar una cuenta como inactiva (aplica a usuarios y equipos).
  • $timediff: Calculo de tiempo de "Inactive Days" contra el día de la ejecución del script.
  • $strCuando: Fecha en formato de texto para asignarla al nombre de los archivos.

Si, si, si, ya se... la nomenclatura del tipo de variables es innecesaria... vicios heredados de otros lenguajes.. sepan disculpar....

Luego declaramos los archivos ( que vamos a genear como salida de información, esto también puede obviase, pero en este caso yo prefiero tener los archivos testigos de la ejecución (de ahi que se le ponga la fecha dentro del nombre del archivo), para estadística futura.

Consultas

Dentro del script, se realizan diferentes consultas a AD, explicaremos aquí cada una de ellas.

Get-ADGroupMember "Domain ADmins" | Get-AdUser -Property LastLogonDate | select name,samAccountName,distinguishedName,LastLogonDate > $strFile1 Consultamos por los miembros del grupo "Domain Admins" (ojo, si la versión de AD no está en inglés cambien el nombre del grupo...), luego para cada objeto-usuario que se retorna, consultamos la propiedad de última fecha de logon, y por último hacemos la consulta de los campos que queremos informar en el archivo, en este caso, name,samAccountName,distinguishedName,LastLogonDate. Esta información nos permitirá saber las cuentas miembro del grupo de administradores de dominio y también su última fecha de logon, para ver si la misma está en desuso.

Search-ADAccount -PasswordNeverExpires | FT Name,UserPrincipalName,LastLogonDate -A > $strFile2: Aqui se consulta directamente a AD usando Search-ADAccount, ya que permite incluir el parámetros -PasswordNeverExpires lo que retorna exactamente eso.. las cuentas cuya contraseña nunca caduca.. Luego solicitamos los campos Name,UserPrincipalName,LastLogonDate en formato de tabla y los dirigimos al archivo $strFile2

Get-ADGroup -Filter {GroupCategory -eq 'Security'} | ?{@(Get-ADGroupMember $_).Length -eq 0} | FT samAccountName,distinguishedName, GroupScope > $strFile3 : La tercer consulta que hacemos, obtiene los grupos de AD aplicando un filtro a los efectos de obtener solo aquellos grupos que son grupos de "seguridad", luego, de cada uno de esos grupos obtenidos, filtra aquellos que tienen 0 (cero) miembros, y finalmente solicita en formato de tabla los campos samAccountName,distinguishedName, GroupScope incorporando aqui GroupScope pues puede resultar importante a la hora del análisis.

Luego, las 2 consultas siguientes se refieren a cuentas de usuario o de equipo que no se utilizaron por x tiempo. Como indicamos más arriba $intInactiveDays es la variable que indica el x tiempo, y es la que se utiliza para calcular $timediff que marca la fecha limite para considerar el equipo fuera de uso o la cuenta del usuario fuera de uso. Para ello entonces la sentencia Get-ADComputer -Filter {LastLogonTimeStamp -lt $timediff} utiliza el -Filter contra la fecha de último logon, LastLogonTimeStamp a los efectos de obtener las cuentas cuyo dato sea inferior (-lt) a $timediff. La consulta a nivel usuario es similar, sin embargo, agregamos en el filtro de la cuenta de usuario {LastLogonTimeStamp -lt $timediff -and enabled -eq $true} otra condición, y es que la cuenta está habilitada (-and enabled -eq $true).

Por último, consultamos los equipos con sistemas operativos viejos, en este caso, XP o 2003. Get-ADComputer -Filter {OperatingSystem -like "*XP*" -or OperatingSystem -like "*2003*"} -Properties Name,OperatingSystem,lastLogonTimestamp | select-object Name,OperatingSystem,@{Name="Stamp"; Expression={[DateTime]::FromFileTime($_.lastLogonTimestamp)}} > $strFile6 Específicamente la el filtro de sistema operativo consulta por nombres similares a XP o 2003 {OperatingSystem -like "*XP*" -or OperatingSystem -like "*2003*"}, de esta forma, el archivo strFile6 que generamos, contendrá la lista de los equipos con sistemas operativos obsoletos.

Correo

Una vez que recolectamos la información en los archivos del 1 al 6, podemos meterlos todos en 1 correo y enviarlo a la cuenta o grupo deseado.

En este caso utilizamos Send-MailMessage y enviamos la información a un SMTP Relay en el propio servidor donde se ejecuta el script a los efectos que el ejemplo sea más claro, sin embargo, puede utilizarse cualquier server SMTP, los parémtros completos de Send-MailMessage permiten la inclusion de SSL y autenticación.

Send-MailMessage
[-To]
[-Subject]
[[-Body] ]
[[-SmtpServer] ]
[-Attachments ]
[-Bcc ]
[-BodyAsHtml]
[-Cc ]
[-Credential ]
[-DeliveryNotificationOption ]
[-Encoding ]
-From
[-Port ]
[-Priority ]
[-UseSsl]
[]

Previsiones

No debería haber problemas para ejecutar este script, sin embargo, algunas pocas previsiones deben tomarse en cuenta.

  • Set-ExecutionPolicy La ejecución de scripts debe estar permitida en powershell, para ello ejecute Set-ExecutionPolicy Unrestricted en PowerShell.
  • Ruta: Si ejecuta el script desde SheduleServices, recuerde llamar a powershell e invocar el script con su ruta completa, por ej. powershell.exe c:\scripts\admonitor.ps1.
  • Active Directory Module: Si el equipo que ejecuta el script no es un DC (server member o estación de trabajo), debe incorporar las "Remote Server Administration Tools" y dentro de ellas seleccionar Active Directory Module for PowerShell.
  • Permisos: Si ejecuta el script desde SheduleServices, recuerde ejecutar con los permisos más elevados posibles y con una cuenta miembro de "Domain Admins", o sea con privilegios de administrador.

Conclusiones

Copiar y pegar el script arriba indicado, cambiando las variables debería ser suficiente para poder obtener los mínimos KPIs de AD.

La potencia que otrora ofrecía VBA para la adminitración de servidores, fue pasando a PowerShell y en scripts como este se ve su potencial y ductilidad. Tal vez hoy no sea la panacea utilizar powershell en todos los casos, pero cierto es que MSFT a apuntado sus cañones hacia alli y no ha retrocedido, por lo que tarde o temprano los administradores más viejos, deberemos ir pasando nuestro bagage de herramientas VBscript a powershell, en algunos casos, o para ser honestos, en la mayoría de los casos, escribiremos menos código, en algunos, aún deberemos recurrir a VB o bien escribir varios renglones adicionales de PowerShell.

 

 

Volver a lista de Notas