Windows PowerShell
Trucos de canalización geniales, nueva edición
Don Jones
El mes pasado, le mostré un excelente truco de canalización que aprovecha el enlace de parámetros de canalización para convertir una tarea algo compleja en una sencilla frase de una línea de Windows PowerShell.
Ésta es una pequeña recapitulación: Creé un archivo de valores separados por comas (CSV) que contiene información acerca de usuarios nuevos que necesitaba para crear un dominio de Active Directory. Me aseguré de que los encabezados de la columna del archivo CSV coincidiera con los nombres de parámetro del cmdlet New-ADUser (el cual viene con Windows Server 2008 R2 y se puede usar con los dominios de Windows Server 2003 también). De manera que los encabezados de las columnas eran elementos como “Department”, “City”, “Name”, “GivenName”, “Surname” y así sucesivamente. Como New-ADUser enlaza la entrada de la canalización por nombre de propiedad, seleccionar esos nombres de columna me permitió crear los usuarios con tan sólo dos cmdlets:
Import-CSV c:\new-users.csv | New-ADUser
El cmdlet Import-CSV proporciona un objeto para cada línea del archivo CSV y esos objetos tienen propiedades que corresponden a los nombres de las columnas de CSV. Como mi archivo CSV contenía todos los therequiredparameters de New-ADUser, no tuve necesidad de especificar manualmente ningún parámetro, aunque podría haberlo hecho no en el archivo que sería válido para cada nuevo usuario (una organización, por ejemplo):
Import-CSV c:\new-users.csv | New-ADUser –organization "OurCompany"
Creo que este ejemplo realmente destaca la eficacia de Windows PowerShell: En los días de VBScript, esta tarea habría requerido un script de varias líneas (y podría hacerlo así en Windows PowerShell, también). Pero al tomarse el tiempo de comprender cómo funciona la canalización y con la ayuda de un par de cmdlets bien escritos, este “script” se convierte en un par de comandos sencillos.
Entonces, ¿cuál es el problema?
Un par de astutos lectores publicó preguntas en mi sitio web enwww.ConcentratedTech.com, señalando que mi genial truco sólo funcionaba si los nombres de las columnas del archivo CSV coincidían exactamente con los nombres de los parámetros en New-ADUser. Si un administrador está creando el archivo CSV, probablemente puede confiar en esa coincidencia exacta; ahora, si el archivo proviene de alguien de Recursos Humanos, es más probable que los nombres de las columnas sean cosas como “First Name”, “Last Name”, y no la coincidencia exacta que necesitamos para New-ADUser para enlazar esas propiedades a sus parámetros.
Desde luego, siempre podría editar cualquier archivo o base de datos que los tipos de Recursos Humanos le enviaran, pero ¿no es ese tipo de cosas precisamente el motivo por el que se inventaron los equipos? Windows PowerShell, desde luego, ofrece una manera rápida y fácil para “cambiar el nombre” a las propiedades: el cmdlet Select-Object.
Select-Object es uno de esos cmdlets que puede ser un poco complicado de aprender a usar, porque hace muchas cosas. Por ejemplo, una de sus tareas principales es simplificar objetos mediante la eliminación de las propiedades que no necesita en ese momento. Simplemente especifique las propiedades que sí desea y el cmdlet dará como resultado un objeto reducido. Esto puede ser útil para clarificar un poco pantallas de resultados y archivos de texto, por ejemplo.
Get-WmiObject Win32_OperatingSystem | Select-Object BuildNumber,ServicePackMajorVersion
Otro uso de Select-Object es seleccionar un subconjunto de los objetos de la canalización, mediante el uso de los parámetros**–first** o –last:
Get-Process | Sort VM –desc | Select –first 10
Nótese que cambié al alias Select en lugar del nombre completo del cmdlet.
Ésta es la solución
Otra función que a menudo se pasa por alto de Select-Object es su capacidad no sólo de seleccionar las propiedades que desea, sino de cambiarles el nombre. Si alguna vez leyera la ayuda completa para el cmdlet (Help Select –full, algo que de todas maneras le recomiendo hacer con cada cmdlet), descubriría esta capacidad y hasta vería ejemplos de cómo usarla. Aquí se muestra un ejemplo:
Import-CSV c:\new-users.csv | Select @{Name="Surname";Expression={$_."Last Name"}}
Si el archivo CSV de entrada tiene una columna “Last Name”, esto le cambiará el nombre a “Surname,” permitiendo así que la propiedad de salida coincida con el nombre del parámetro de New-ADUser. Lo que hice fue crear una tabla hash, también llamada diccionario o matriz asociativa. El signo @ es un operador de matriz en Windows PowerShell; la tabla hash es una matriz que consta de pares de valores clave. En este caso, la clave es el nombre de la propiedad que deseo crear y el valor es el contenido que deseo asignado para esa propiedad. Dentro de la porción de expresión de la tabla hash, puedo usar la variable $_ v para referirme al objeto de canalización actual; en este ejemplo, recuperé su propiedad “Last Name” (tuve que usar comillas alrededor del nombre de la propiedad porque éste contiene un espacio).
Puede enviar todas la variables de este tipo que desee a Select-Object:
Import-CSV c:\new-users.csv | Select @{Name="Surname";Expression={$_."Last Name"}}, @{Name="GivenName";Expression={$_."First Name"}}
El asunto es que Select-Object arrojará como resultado exactamente lo que le diga que arroje, así que no puede decirle simplemente que cambie el nombre a una o dos columnas y que arroje el resultado de estas dos más todo lo que no tuvo que cambiar. Generalmente debe especificar cada propiedad que desea enviar al siguiente cmdlet. Desde luego, si no necesita cambiar el nombre a cada columna de su archivo CSV, simplemente las puede colocar en una lista de la siguiente manera:
Import-CSV c:\new-users.csv | Select @{Name="Surname";Expression={$_."Last Name"}}, @{Name="GivenName";Expression={$_."First Name"}},Department,Organization,Name
En este caso, “Department”, “Organization” y“Name” pasarían sin que tuviera que cambiarles el nombre, lo cual está bien (coinciden exactamente con los parámetros asociados deNew-ADUser).
Esto podría parecer complicado si tiene muchas columnas por especificar, así que éste es el método abreviado:
Import-CSV c:\new-users.csv | Select @{Name="Surname";Expression={$_."Last Name"}}, @{Name="GivenName";Expression={$_."First Name"}},*
El “*” arrojará como resultado todas las propiedades desde el objeto de entrada, además de las propiedades “Surname” y “GivenName” que creé. Así que digamos que tengo un archivo CSV parecido a éste:
First Name,Last Name,Department,Name
Don,Jones,IT,DonJ
Greg,Shields,Janitorial,GregS
Jeff,Hicks,IT,JeffH
Entonces puedo usar estos dos cmdlets:
Import-CSV c:\new-users.csv | Select @{Name="Surname";Expression={$_."Last Name"}}, @{Name="GivenName";Expression={$_."First Name"}},*
Y cada uno de mis objetos de salida tendrá seis propiedades: “First Name”, “Last Name”, “Department”, “Name”, “Surname” y “GivenName.” En otras palabras, todas las propiedades originales, más lo que he agregado. Y entonces simplemente agrego el cmdlet New-ADUser:
Import-CSV c:\new-users.csv | Select @{Name="Surname";Expression={$_."Last Name"}}, @{Name="GivenName";Expression={$_."First Name"}},* | New-ADUser
El cmdlet New-ADUser no podrá hacer nada con las propiedades“First Name” y “Last Name”, ya que no coinciden con ninguno de sus parámetros. No hay problema, el cmdlet simplemente ignorará cualquier propiedad que no pueda enlazar. Sin embargo, enlazará las cuatro restantes (“Surname”, “GivenName”, “Department” y “Name” en este caso) y creará las cuentas del nuevo usuario por mí.
Cambio de mentalidad
Considero que uno de los mayores desafíos al usar Windows PowerShell es no darse nunca por vencido. En otras palabras, si no puede usar un archivo CSV proporcionado simplemente porque los nombres de las columnas no coinciden con lo que necesita, no presuma que la respuesta es cambiar el archivo CSV. Windows PowerShell casi siempre puede hacer lo que necesita, con sólo un poco de investigación de su parte.
¿Así que con qué desafíos complicados se ha topado al trabajar con Windows PowerShell? Me encantaría saber (y quizás basar un futuro artículo en la respuesta). Publique sus preguntas en www.ConcentratedTech.com, donde podré responder de inmediato en línea, reunir detalles adicionales de su parte y posiblemente crear un futuro artículo para Microsoft TechNet Magazine.
Don Jones es uno de los instructores y escritores de Windows PowerShell más experimentados del país. Publica semanalmente en un blog consejos acerca de Windows PowerShell enConcentratedTech.com; también puede ponerse en contacto con él o hacerle preguntas allí.