miércoles, 28 de mayo de 2008

Ordenando Cuentas de Máquina en Grupos de Directorio Activo

A la hora de administrar un entorno de un número importante de PCs hay que tener siempre presente dos cosas.

La primera es el orden que tenemos que llevar a la hora de realizar ciertas tareas. Cuando trabajamos con un alto número de máquinas el desorden puede hacer que al cabo del tiempo nos podamos encontrar envueltos en una gran tela de araña de la cual no podamos escapar. La segunda es clara, para trabajar ya están las máquinas, porqué tenemos que hacer una serie de tareas repetitivas si puede hacerlo la máquina por nosotros.

El script que os muestro a continuación nos ayuda a asignar cuentas de máquina a una serie de grupos de forma equilibrada, supongamos que configuramos los PCs para conectarse a la red usando 802.1x y validación contra un IAS, hay motivos por los cuales configurar 802.1x, el principal el securizar el acceso a la red. También hay varios motivos para configurar un IAS, este en concreto es para comprobar que la cuenta de máquina pertenece a un grupo determinado y en función de esto le enviara el ID de VLAN al que va a pertenecer.

Para poneros en situación el caso es el siguiente, tenemos un edificio con 2500 PCs, para este edificio tengo 25 VLAN's por lo cual tendré un máximo de 100 máquinas por VLAN. En este articulo no quiero abordar ni la configuración del servicio IAS ni la configuración de 802.1x, nos vamos a ir directamente al problema y este es que tengo que asignar un grupo a mis máquinas para que el IAS les asigne un ID de VLAN.

El script asignara un grupo de Directorio Activo a cada una de las máquinas donde se ejecute y se asegurará que los grupos tengan el mismo numero de miembros. Para que el script funcione tenemos que tener en cuenta varias cosas:

  • El nombre de los grupos de VLAN ha de terminar en un numero, un ejemplo puede ser VLAN001, VLAN002, etc.
  • El usuario que ejecute el script tiene que tener permisos de "Leer todas las propiedades" y "Escribir todas las propiedades" sobre las cuentas de máquina, sobre los grupos de VLAN o sobre las OUs que los contienen.

Bien pues vamos al tajo, en primer lugar vamos a crear los objetos necesarios, creamos una instancia del del objeto ADSystemInfo, esto nos será de gran utilidad ya que podremos extraer bastante información sobre el usuario que inicio sesión o la máquina local para ser exactos vamos a obtener el distinguishedName de la máquina local con objADInfo.ComputerName.

Set objShell = CreateObject("WScript.Shell")
Set objADInfo = CreateObject("ADSystemInfo")
Set objMachine = GetObject("LDAP://" & objADInfo.ComputerName)

Se ha definido una función que comprueba la pertenencia a un grupo de Directorio Activo, esto nos servirá para comprobar si la máquina pertenece a algún grupo de VLAN, nos devolverá 1 si es miembro y 0 si no lo es. A la función le insertamos dos parámetros, el objeto máquina y el grupo que queremos comprobar. Se comprueba con la función isEmpty si la máquina es miembro de algún grupo, si no es así, la función devolverá 0 y no hará ningún tipo de comprobación. Se colocan los miembros en un array, y este array se convierte en una cadena separada por puntos y coma con la función Join(amembers,";") y se para a mayúsculas. A continuación se utiliza la función InStr(members, UCase(strTgtGroup)) para saber si el grupo objetivo esta en la cadena, si es así la función devolverá 1.

Function bMiembro (ByVal objMachine, ByVal strTgtGroup)
bMiembro = 0
If Not IsEmpty(objMachine.memberof) Then
   aMembers=objMachine.GetEx("memberOf")
   members=UCase(Join(amembers,";"))
   If InStr(members, UCase(strTgtGroup)) > 0 Then
      bMiembro = 1
   End If
End If
End Function

Bien, una vez hecho esto comenzamos con el script que añadirá la máquina a alguno de los grupos de VLAN, siempre y cuando esta no sea miembro de alguno de ellos. Creamos las variables iniciales que vamos a necesitar, son las siguientes:

  • strMaquina, almacena la variable de entorno COMPUTERNAME, usamos esto ya que objADInfo.ComputerName nos devuelve el distinguishedName y solo necesitamos el nombre de la máquina.
  • intContador, el contador que nos ayudara a recorrer los grupos de VLAN.
  • strPeqVlan, almacenara el nombre del grupo de VLAN con menos miembros.

strMaquina= objShell.ExpandEnvironmentStrings("%COMPUTERNAME%")
intContador=1
strPeqVlan=""

El resto del script se mueve dentro de un bucle donde realizaremos varias acciones, el bucle utiliza el contador para recorrer el total de grupos de VLAN que tengamos.

do
   acciones
Loop Until intContador = 25

A continuación y ya dentro del bucle utilizaremos una variable strGrupo para almacenar el nombre de cada uno de los grupos de VLAN, como veis se ha utilizado un pequeño if para ajustar el nombre del grupo de VLAN ya que el contador no permite ceros a la izquierda. Una vez que se ha conformado el nombre del grupo uniendo la cadena al contador podemos incrementar este. Si el contador es 5, la cadena resultante ser VLAN005, si este es 15 el resultado será VLAN015.

Dentro del bucle

If intContador<10 Then
   strGrupo = "VLAN00"
Else
   strGrupo = "VLAN0"
End If
strGrupo= strGrupo & intContador
intContador = intContador + 1

Comprobamos la si la máquina pertenece al grupo de VLAN que hay en la variable strGrupo y si es así, finalizamos la ejecución del script mostrando un mensaje de aviso.

Dentro del bucle

If bMiembro(objMachine, strGrupo) Then
   MsgBox("La máquina esta en el grupo " & strGrupo & ", no se realizara ninguna acción")
   WScript.Quit
End If

Ahora vamos a contar los miembros del Grupo de VLAN en el que nos encontramos ubicados dentro del bucle, colocamos todos los miembros de ese grupo en un array y los contamos con intMiembros, esta variable es la que va a contener el numero de miembros total del grupo.

Dentro del bucle

Set objGroup = GetObject ("LDAP://CN=" & strGrupo & ",OU=Grupos de VLAN,DC=dominio,DC=local")

objGroup.GetInfo
arrMemberOf = objGroup.GetEx("member")
intMiembros = "0"
For Each strMember in arrMemberOf
   intMiembros = intMiembros + 1
Next

La ultima acción dentro del bucle será almacenar en dos variables el nombre del grupo de VLAN que tiene el menor numero de miembros (strPeqVlan) y este numero (intPeqVlan). Al finalizar el bucle, estas variables indicaran el Grupo al que se ha de añadir la máquina en el caso de ser necesario.

Dentro del bucle

If strPeqVlan = "" Then
   strPeqVlan = strGrupo
   intPeqVlan = intMiembros
Else
   If intMiembros < intPeqVlan Then
      strPeqVlan = strGrupo
      intPeqVlan = intMiembros
   End If
End If

Ya sabemos cual es el grupo al que se ha de agregar la máquina por lo cual vamos a ello. Tenemos que indicar la ruta completa de la OU donde esta el grupo y utilizar la variable strPeqVlan para establecer el grupo elegido.

Const ADS_PROPERTY_APPEND = 3
Set objGroup = GetObject ("LDAP://CN=" & strPeqVlan & ",OU=Grupos de VLAN,DC=dominio,DC=local")
objGroup.PutEx ADS_PROPERTY_APPEND, "member", Array(objADInfo.ComputerName)
objGroup.SetInfo

Por ultimo para finalizar es script se realiza un pequeño control de errores, personalmente creo que esta parte es mejorable ya que en el inicio del script he usado un On Error Resume Next y esto no es muy recomendado. Lo suyo seria utilizar On Error GoTo ETIQUETA. El control de errores simplemente chequea si se ha producido algún error, si es así mostrara un mensaje indicando cual fue el error, si no, indicara que la máquina se ha agregado al grupo y cual es el numero de miembros de este.

If Err.Number <> 0 Then
   MsgBox("No se ha agregado la Máquina al grupo porque se genero el siguiente error: " & Err.Description)
Else
   MsgBox("El equipo " & strMaquina & " se agrego al grupo " & strPeqVlan & " con " & intPeqVlan & " intMiembros")
End If

Bueno, pues creo que ha sido suficiente por hoy, seguramente sea mejorable pero personalmente me ha sido muy practico, se podría añadir un control de numero máximo de usuarios por grupo, lo cual seria muy útil para no agotar el ámbito DHCP asignado a cada VLAN y seguramente alguna cosa mas.

Espero que os sea de utilidad. Como siempre se agradecerá cualquier tipo de comentario que queráis hacer.

No hay comentarios: