Windows PowerShellProfundización

Don Jones

Windows PowerShell está repleto de características que a muchos administradores se les suelen pasar por alto. Si profundiza un poco, encontrará algunas capacidades que le sorprenderán. De hecho, yo mismo descubro a menudo nuevas características asociadas a un cmdlet determinado que ya creía conocer al dedillo.

En las clases de Windows PowerShellTM que imparto, recomiendo a los administradores que creen para ellos mismos un calendario con un cmdlet para cada día, de forma parecida a uno de esos calendarios que sugieren una palabra nueva para cada día. De este modo, cada mañana (sin contar los fines de semana), pueden dedicar unos minutos a familiarizarse con las capacidades completas de un cmdlet. Windows PowerShell se comercializa con unos 130 cmdlets, lo que significa que puede aprender prácticamente todo lo que Windows PowerShell es capaz de hacer en cuestión de seis meses si se ciñe a esta programación. Para entonces, estará preparado para enfrentarse a todos los cmdlets de Exchange Server 2007.

En la columna de este mes, quiero presentar algunos ejemplos de lo que podría descubrir y puede lograr sólo con dedicar unos minutos a explorar las capacidades más ocultas de varios cmdlets.

Informes HTML con mejor aspecto

Uno de los cmdlets que están bastante infrautilizados es ConvertTo-HTML. Este ingenioso cmdlet puede aceptar una colección de objetos de entrada (servicios, procesos, objetos de instrumental de administración de Windows® (WMI) o lo que sea) y los convierte en una tabla HTML. A continuación puede canalizar el HTML a Out-File y obtener una página HTML apta para exponer en un servidor web de intranet. Por ejemplo, puede programar esta línea sencilla para que se ejecute todas las mañanas:

Gwmi Win32_Service | Where { $_.StartMode
–eq "Auto" –and $_.State –ne "Running" } |
ConvertTo-HTML | Out-File C:\ServiceAlert.html

Con ello se creará un informe HTML, como el que se muestra en la figura 1, de servicios que deberían iniciarse automáticamente pero no se ejecutan.

Figura 1 Informe HTML de servicios que no se ejecutan

Figura 1** Informe HTML de servicios que no se ejecutan **(Hacer clic en la imagen para ampliarla)

Efectivamente, quizás desee producir un informe que sea un poco más atractivo. Afortunadamente, el cmdlet ConvertTo-HTML produce HTML limpio, lo que significa que no incrusta ningún formato en el código HTML que crea. Según las reglas de HTML, nunca debe ponerse formato en el HTML (bueno, debe ponerse lo menos posible). Donde sí que se debe poner formato es en una hoja de estilos en cascada (CSS) externa y vincularla al HTML. Y ese vínculo se puede crear con ConvertTo-HTML.

La CSS se vincula en la sección <HEAD> de un archivo HTML. Si observa la ayuda de ConvertTo-HTML, verá que su sintaxis incluye algunos parámetros que quizás haya pasado por alto:

ConvertTo-Html [[-property] <Object[]>] 
[-inputObject <psobject>] [-body <string[]>] 
[-head <string[]>] [-title <string>] [<CommonParameters>]

El parámetro –head le permite especificar código HTML adicional que insertar en la sección <HEAD> del script. Ahora puedo modificar fácilmente la línea para vincularla a un archivo CSS existente que contenga el formato que deseo aplicar a la tabla HTML:

Gwmi Win32_Service | Where { $_.StartMode
–eq "Auto" –and $_.State –ne "Running" } |
ConvertTo-HTML -title "Services" -head "<link
rel='stylesheet' href='styles.css' type='text/
css' />" | Out-File C:\ServiceAlert.html

En este caso usé el parámetro –head para insertar un vínculo en un archivo CSS ubicado en la misma carpeta que el archivo de salida HTML. También usé el parámetro –title para establecer el título de la página web. El resultado aparece en la figura 2. El texto del archivo Style.CSS que usé tiene este aspecto:

Figura 2 Informe HTML formateado con un archivo CSS

Figura 2** Informe HTML formateado con un archivo CSS **(Hacer clic en la imagen para ampliarla)

body { background-color:#EEEEEE; }
body,table,td,th { font-family:Tahoma; color:Black; Font-Size:10pt }
th { font-weight:bold; background-color:#CCCCCC; }
td { background-color:white; }

Filtrado más fácil

Cmdlet del mes

Este mes estoy estudiando un par de cmdlets: Start-Transcript y Stop-Transcript. Ambos sirven para controlar el registro de transcripciones de Windows PowerShell, es decir, para que todo lo que aparece en la ventana de la consola se escriba en un archivo de texto que haya especificado. Es bastante sencillo. Ejecute Start-Transcript y asígnele un nombre de archivo para empezar. A continuación, ejecute Stop-Transcript para terminar el registro y cerrar el archivo. Esta operación implica un modo estupendo de pasar del uso ad hoc de shells al scripting formal; una vez que haya líneas de comandos individuales funcionando en el shell, simplemente podrá copiarlos y pegarlos del archivo de transcripción que haya creado. Por supuesto, si lo desea, puede editar la transcripción para que pase a ser únicamente el script en sí. Jeffery Hicks, miembro de MVP, escribió incluso un script que analiza transcripciones y las convierte en archivos de Windows PowerShell PS1. Encontrará este script en blog.sapien.com/current/2006/11/28/powershell-transcripts.html.

Ahora observemos el cmdlet Get-WMIObject. Su sintaxis, como se indica en la ayuda integrada de Windows PowerShell, señala de forma sugerente hacia las capacidades sin explotar:

Get-WmiObject [-class] <string> [[-property]
<string[]>] [-namespace <string>] 
[-computerName <string[]>] [-filter <string>] 
[-credential <PSCredential>]
[<CommonParameters>]

Un error habitual que cometerán los nuevos usuarios de Windows PowerShell es el de ejecutar un comando WMI como éste:

Gwmi Win32_NTLogEvent –comp Server2

Este comando recuperará las entradas de registro de eventos de Server2 (todas las entradas de registro de eventos). Esta tarea ocupara unos minutos a Server2 hasta que procese y transmita, y Windows PowerShell tardará bastante en hacer algo útil con una colección tan grande.

Un mejor enfoque es hacer que Server2 busque y envíe los eventos que realmente le interesan. Esto podría hacerlo con toda seguridad usando una consulta de lenguaje de consulta de WMI (WQL). Para algunas personas esa sintaxis de consulta resulta difícil, pero Windows PowerShell le permite especificar simplemente la parte de filtrado de una consulta de WQL, mediante el parámetro –filter:

Gwmi Win32_NTLogEvent –comp Server2 –filter "EventIdentifier=1024"

Esto recuperará todos eventos (de cualquier registro) con el id. de evento 1024. Observe que los criterios de filtro usan = como operador de comparación en lugar del operador –eq de Windows PowerShell. Esto es así porque el filtro se está transfiriendo al servicio WMI del equipo remoto para su procesamiento, por lo que los criterios deben estar en la sintaxis de WMI, no en la sintaxis de Windows PowerShell.

Existe en realidad un parámetro –filter en otros cmdlets como, por ejemplo, Get-ChildItem, el cmdlet contenido en alias como Dir y Ls. En la mayoría de los casos, el parámetro –filter transfiere sus criterios de filtro directamente a la tecnología subyacente, y eso tiene como resultado lo que yo llamo filtrado de origen, que suele ser mucho más rápido que recopilar todos los objetos y, a continuación, ejecutarlos a través del cmdlet Where-Object para excluir los que no interesan.

Cmdlets que se pasan por alto

En efecto, este enfoque mediante el que se estudia un cmdlet al día le ayudará a comprender mejor los cmdlets ya creía conocer. Sin embargo, otro buen motivo para tener un calendario de cmdlets para cada día es evitar que se le pasen totalmente por alto cmdlets que, de otro modo, quizás no descubriría nunca. Uno de mis favoritos y que muchas personas no usan es Resolve-Path. Al determinar una ruta de acceso de caracteres comodín, éste devolverá una colección de nombres de archivo y de carpeta que coincidirá con la ruta de acceso. Es parecido al cmdlet Get-ChildItem (es decir, los conocidos alias Dir o Ls), pero en lugar de devolver objetos enteros de archivo y carpeta, devuelve cadenas sencillas que pueden canalizarse a otros cmdlets para un posterior filtrado o procesamiento. Su uso es sencillo:

Resolve-Path C:\P*

Esta línea sencilla devolverá rutas de acceso como C:\Archivos de Programa, C:\Processes.txt, etc. La figura 3 muestra dos ejemplos de este cmdlet en uso.

Figura 3 Uso del útil, aunque poco conocido, cmdlet Resolve-Path

Figura 3** Uso del útil, aunque poco conocido, cmdlet Resolve-Path **(Hacer clic en la imagen para ampliarla)

Comience por el principio

Cuando esté listo para empezar a trabajar con el cmdlet del día, ejecute Gcm, un alias para Get-Command. Obtendrá una lista de todos los cmdlets que Windows PowerShell conoce, incluidos los que se han agregado mediante complementos como, por ejemplo, el shell de administración de Exchange Server 2007, las extensiones de la comunidad de PowerShell, etc. Simplemente escoja el primero de la lista (el mío era Add-Content) y lea la ayuda correspondiente:

Help Add-Content –full

Le interesa la ayuda completa, y no la ayuda breve predeterminada, para poder obtener una descripción completa de lo que hace cada parámetro, consultar algunos ejemplos del uso de cmdlets y averiguar otra información detallada. Tómese su tiempo para experimentar con el cmdlet. (Quizás le interese usar una máquina virtual para no hacer pruebas con su entorno de producción.) Le recomiendo que se tome 10 minutos cada día, aproximadamente a la misma hora del día, para que se convierta en un hábito. En muy poco tiempo, conocerá a la perfección toda la funcionalidad y las capacidades que puede ofrecer Windows PowerShell.

Don Jones es el principal gurú de scripting de SAPIEN Technologies y coautor de Windows PowerShell: TFM (SAPIEN Press, 2007). Puede ponerse en contacto con él en www.ScriptingAnswers.com.

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