¡Hola, chicos del scripting!Respuesta a sus preguntas acerca de las unidades organizativas... por solo 5 centavos

Los chicos del scripting de Microsoft

Descargar el código de este artículo: HeyScriptingGuy2007_03.exe (151KB)

P ¿Cómo puedo mostrar un cuadro de diálogo que me permita seleccionar una unidad organizativa desde Active Directory?

¿Sabe? Si a los chicos del scripting nos dieran un centavo por cada vez que nos han formulado esta pregunta, tendríamos... Bueno, realmente, sólo tendríamos 37,15 dólares, ¿no? Bueno, pero si nos dieran un centavo por cada persona que nos ha querido formular esta pregunta pero nunca ha llegado a hacerlo, tendríamos... Bueno, la cantidad no importa. A fin de cuentas, no nos hicimos chicos del scripting por el dinero. Nos hicimos chicos del scripting por la satisfacción que nos produce ayudar a la gente a realizar sus tareas de administración del sistema con mayor rapidez y facilidad.

Nota: correcto, así que técnicamente nos hicimos chicos del scripting por el dinero. Pero, luego, el jefe nos dijo, "Podríais llegar a ganar mucho dinero, pero sólo si estáis dispuestos a trabajar duro y a no producir nada que no sea material de gran calidad". En ese momento decidimos que el dinero no lo era todo.

No importa. La verdad es que a muchas personas les gustaría saber cómo mostrar un cuadro de diálogo que les permita seleccionar una unidad organizativa y, a continuación, conectarse a ella mediante una secuencia de comandos. "Nos habéis enseñado cómo mostrar un cuadro de diálogo que nos permita seleccionar carpetas", dice un mensaje de correo electrónico reciente, "y nos habéis mostrado cómo mostrar un cuadro de diálogo que nos permita seleccionar archivos. ¿Por qué no nos habéis enseñado nunca cómo mostrar un cuadro de diálogo que nos permita seleccionar una unidad organizativa de Active Directory®?"

Bien, para empezar, es cierto que hemos enseñado a la gente a mostrar un cuadro de diálogo que permita seleccionar carpetas, y justo aquípuede encontrar un ejemplo de ello. También hemos enseñado a la gente a mostrar un cuadro de diálogo que permita seleccionar archivos; si no nos cree, visite microsoft.com/technet/scriptcenter/resources/qanda/jan05/hey0128.mspx (en inglés). Estos dos artículos fueron bien recibidos, y sabemos que los usuarios están empleando esas técnicas en sus secuencias de comandos. Entonces, ¿por qué no hemos enseñado a la gente a mostrar un cuadro de diálogo que permita seleccionar unidades organizativas de Active Directory? ¿Se trata de algún tipo de conspiración de Microsoft o algo así?

Por supuesto que no. (Vaya, aguarde un minuto: eso es exactamente lo que diría alguien implicado en una conspiración, ¿no?) La verdad es que existe una buena razón para no enseñar a la gente a mostrar un cuadro de diálogo que permita seleccionar unidades organizativas de Active Directory: y es que ese cuadro de diálogo no existe. Como dicen en el béisbol, no se puede golpear lo que no se ve. Y como decimos en scripting, no se puede mostrar lo que no existe.

Así que suponemos que aquí acaba la columna de este mes. Hasta la próxima.

¡Ojalá! Según los editores de TechNet Magazine, aquí no acaba la columna de este mes. "¿Y qué, si no existe ese cuadro de diálogo como ese?", dicen. "Sois los chicos del scripting, ¿no? ¿No podéis crear un cuadro de diálogo para solucionar el tema? Pensábamos que podíais hacer cualquier cosa con secuencias de comandos."

No hace falta decir que los editores de TechNet Magazine tienen una idea equivocada de la situación. ¿Cualquier cosa con secuencias de comandos? No exactamente. La verdad es que nosotros, los chicos del scripting, sólo sabemos hacer una cosa con secuencias de comandos.

Afortunadamente, esa cosa es precisamente crear un cuadro de diálogo que permita seleccionar una unidad organizativa de Active Directory. Eche un vistazo a la figura 1.

Sí, es una secuencia de comandos bastante larga, ¿verdad? Pero, ya conoce el dicho: no se puede hacer una tortilla sin romper unos cuantos huevos. Igualmente, no se puede crear un cuadro de diálogo personalizado sin romper unos cuantos huevos (a mitad de esta columna nos entró hambre y tuvimos que hacer una pausa para tomar un aperitivo). Ahora que nuestro apetito está saciado, veamos si podemos explicar cómo funciona todo esto.

Lo que hacemos con la secuencia de comandos es usar el modelo de objetos de Internet Explorer® para crear un pseudocuadro de diálogo. Crearemos una instancia de Internet Explorer, tomaremos una recopilación de unidades organizativas de Active Directory, y luego mostraremos estas unidades organizativas en un cuadro de lista en una ventana de Internet Explorer. Esperaremos hasta que el usuario seleccione una unidad organizativa, luego tomaremos el ADsPath del elemento seleccionado, descartaremos el "cuadro de diálogo" y continuaremos desde ahí.

Nota: ¿Será el cuadro de diálogo más elaborado y bonito jamás creado? Sí, si por "elaborado y bonito" se entiende algo muy simple que ni siquiera tiene los botones de Aceptar o Cancelar. Pero, en nuestra defensa, la idea aquí es proporcionarle simplemente la estructura básica. Si desea engalanar o modificar el cuadro de diálogo, es cosa suya.

(Chico, si nos dieran un centavo por cada vez que decimos "Lo sentimos, es cosa suya", seríamos ricos. Envíe sus donativos a los chicos del scripting, a la dirección de TechNet Magazine.)

Para que la explicación de nuestra técnica quepa en el espacio que nos han asignado, tendremos que tratar superficialmente unas cuantas cosas. Por ejemplo, lo único que vamos a decir acerca del siguiente bloque de código es que crea una instancia de Internet Explorer de 350 x 400 píxeles, y que, al hacerlo, se ocultan cosas como las barras de dirección y de estado:

Set objExplorer = CreateObject( _
    "InternetExplorer.Application")

objExplorer.Navigate "about:blank"   
objExplorer.ToolBar = 0
objExplorer.StatusBar = 0
objExplorer.Width= 350
objExplorer.Height = 400 
objExplorer.Left = 400
objExplorer.Top = 400
objExplorer.Visible = 1             

Por supuesto, todo lo que esto hace es darnos una ventana en blanco de Internet Explorer. Para obtener la lista de unidades organizativas de nuestro dominio, necesitamos realizar una búsqueda de Active Directory. Hoy no podemos explicar los pormenores de la búsqueda de Active Directory; para obtener información al respecto, eche un vistazo a nuestra serie de dos partes en el Script Center, en microsoft.com/technet/scriptcenter/resources/tales/sg0405.mspx (en inglés). Lo que podemos hacer es decirle que se trata del código que usamos para recuperar los atributos Name y ADsPath de cada unidad organizativa del dominio fabrikam.com:

objCommand.CommandText = _
    "SELECT Name, ADsPath FROM 'LDAP://DC=fabrikam,DC=com' WHERE objectCategory=
    'organizationalUnit' ORDER BY Name"

Ah, y para facilitarle las cosas, también hemos clasificado las unidades organizativas alfabéticamente por nombre. Para eso precisamente sirve la cláusula ORDER BY Name. No importa; a fin de cuentas, estamos aquí para servirle.

Cuando llamamos al método Execute, recuperamos un conjunto de registros formado por todas las unidades organizativas encontradas en fabrikam.com. Eso significa que nuestro siguiente paso es mostrar cada una de estas unidades organizativas en un cuadro de lista.

¿Cómo lo hacemos? Bien, primero necesitamos crear el cuadro de lista entero en la memoria. Para empezar, eso significa usar esta línea de código para almacenar la etiqueta <SELECT> en una variable denominada strHTML:

strHTML = "<select size = '20' name='OUList' style='width:300px'>"

¿Qué vamos a hacer con esta línea de código? Simplemente, vamos a crear un cuadro de lista HTML estándar (algo que se hace mediante la etiqueta <SELECT>). En el proceso, asignamos al cuadro de lista el nombre OUList y lo configuramos para mostrar 20 elementos a la vez y con un ancho de 300 píxeles (300px). Si sabe algo acerca de HTML, el código anterior le resultará bastante familiar.

A continuación, necesitamos agregar algunos elementos (es decir, algunas unidades organizativas) al cuadro de lista. Por una sorprendente coincidencia, sucede que nuestro conjunto de registros consta de información acerca de las unidades organizativas de nuestro dominio. Como consecuencia, podemos configurar un bucle Do Until que enlace el conjunto de registros entero, capture la información y agregue cada unidad organizativa al cuadro de lista. Dentro de este bucle, usamos el código siguiente (de nuevo, HTML estándar para agregar elementos a un cuadro de lista) para agregar cada unidad organizativa, y configurar el elemento para que el nombre de la unidad organizativa se muestre en la lista y, al hacer clic en la unidad en el cuadro de lista, el ADsPath se transmita a la secuencia de comandos:

strHTML = strHTML & "<option value= " & _
    Chr(34) & objRecordSet.Fields
    ("AdsPath").Value & Chr(34)
strHTML = strHTML & ">" & objRecordSet.
    Fields("Name").Value

¿Por qué se transmite el ADsPath a la secuencia de comandos? Muy fácil. Suponga que, en su lugar, transmitimos el nombre de la unidad organizativa. Si el nombre es Finanzas, por ejemplo, será difícil enlazar con esa unidad organizativa; a fin de cuentas, "Finanzas" por sí solo no es una cadena de enlace ADSI válida. Sin embargo, si recuperamos el ADsPath (LDAP://ou=Finance,dc=fabrikam,dc=com), entonces el enlace es pan comido. El motivo es que el ADsPath es exactamente lo que necesitamos para encontrar y conectar con un objeto de Active Directory.

Por cierto, mostramos el nombre en el cuadro de lista porque presuponemos que sus unidades organizativas tienen nombres únicos. Claro que ese podría no ser el caso; por ejemplo, las unidades organizativas Norteamérica/Investigación y Europa/Investigación tienen el mismo nombre (Investigación). Si sus unidades organizativas tienen nombres duplicados, quizás desee usar una propiedad diferente, por ejemplo, ADsPath o distinguisedName, en el cuadro de lista. Eso es algo que tendrá que decidir por sí mismo. ¡Ka-ching! ¡Otro centavo!

A propósito, observe que todavía estamos creando el cuadro de lista en la memoria: cada elemento agregado al cuadro se agrega a la variable strHTML. Todo esto es parte del plan: guardamos el código entero del cuadro de lista en la variable strHTML, luego usamos el valor de esta variable para agregar el cuadro de lista a nuestra instancia de Internet Explorer.

Una vez agregadas las unidades organizativas, usamos esta línea de código para indicar el final del cuadro de lista:

strHTML = strHTML & "</select>"

en este momento, strHTML contiene todas las etiquetas HTML necesarias para crear un cuadro de lista y, lo mejor de todo, un cuadro de lista en el que cada elemento representa una unidad organizativa en Active Directory. Eso significa que ahora podemos asignar el valor de strHTML a la propiedad InnerHTML de nuestro documento de Internet Explorer:

objExplorer.Document.Body.InnerHTML = strHTML

a su vez, eso nos proporciona un cuadro de lista en el que se muestran todas las unidades organizativas de un dominio.

Espere, espere, no se vaya; todavía no hemos terminado. Por ejemplo, necesitamos código que nos permita pausar nuestra secuencia de comandos hasta que el usuario haya seleccionado una unidad organizativa en el cuadro de diálogo; sin ello, el cuadro de lista se mostraría pero la secuencia de comandos seguiría ejecutándose, independientemente de que el usuario realice una selección. ¡Vaya! Para evitar que suceda esto, usamos este bloque de código:

Do While objExplorer.Document.Body.All.OUList.Value = ""
    Wscript.Sleep 300
Loop

Lo que estamos haciendo aquí es comprobar de manera repetida el valor de nuestro cuadro de lista (que, como quizás recuerde, hemos denominado OUList, el mismo nombre que uno de los chicos del scripting puso a su hija). Si el valor es una cadena vacía (lo que significa que no se ha seleccionado ningún elemento), pausamos simplemente la secuencia de comandos durante 300 milisegundos, luego volvemos a aplicar el bucle y comprobamos de nuevo. Esto continúa: a) para siempre, b) hasta que el usuario seleccione un elemento en el cuadro de lista, o c) hasta que el usuario cierre la ventana de Internet Explorer.

Supongamos que el usuario selecciona una unidad organizativa en el cuadro de lista. En ese caso, tomamos el valor (que, como recuerda, es el ADsPath de la unidad organizativa) y lo asignamos a una variable llamada strTargetOU:

strTargetOU = objExplorer.Document.Body.All.OUList.Value

luego, usamos el método Quit para descartar nuestra instancia de Internet Explorer, como se ilustra a continuación:

objExplorer.Quit

En este momento, casi hemos terminado. Primero miramos a ver si strTargetOU es igual a una cadena vacía:

If strTargetOU = "" Then
    Wscript.Quit
End If

en caso afirmativo, eso significa que el usuario ha cerrado Internet Explorer sin seleccionar una unidad organizativa; así, usamos el método Wscript.Quit para finalizar la secuencia de comandos. Suponemos que si el usuario no ha seleccionado una unidad organizativa, no está realmente interesado en ejecutar la secuencia de comandos. Sin embargo, si strTargetOU no es igual a una cadena vacía, devolvemos un eco del valor de la variable:

Wscript.Echo strTargetOU

naturalmente, en una secuencia de comandos real probablemente seguiría adelante y enlazaría con la unidad organizativa en Active Directory, en lugar de simplemente devolver un eco del ADsPath. Pero ya sabe lo que dicen o, al menos, lo que decimos nosotros: eso es cosa suya.

Como dijimos y, como puede ver en la figura 2, no es el cuadro de diálogo más elaborado y bonito jamás creado, pero funciona, y es más fácil que escribir un ADsPath (suponiendo que conozca el ADsPath). Además, le da la oportunidad de personalizar el código y el cuadro de diálogo según sus necesidades.

Figura 2 Cuadro de diálogo sencillo basado en una secuencia de comandos

Figura 2** Cuadro de diálogo sencillo basado en una secuencia de comandos **

Si nos dieran un centavo por cada columna que hemos escrito acerca de cómo mostrar un cuadro de diálogo que permita seleccionar una unidad organizativa de Active Directory... A fin de cuentas, serían 5 centavos más de lo que nos suele pagar TechNet Magazine.

Que conste que no nos estamos quejando.

Los chicos del scripting de Microsoft trabajan para (bueno, son empleados de) Microsoft. Cuando no juegan al béisbol, ni entrenan ni lo ven (u otras actividades varias), dirigen el TechNet Script Center. Visite la página web www.scriptingguys.com (en inglés).

© 2008 Microsoft Corporation and CMP Media, LLC. Reservados todos los derechos; queda prohibida la reproducción parcial o total sin previa autorización.