¡Hola, chicos del scripting!¿Dónde están los soportes para vasos?

Los chicos del scripting de Microsoft

Este artículo se basa en una versión preliminar de Windows PowerShell. Toda la información que aquí se menciona está sujeta a cambios.

Cuando se presenta una tecnología nueva, normalmente, la gente tarda un poco en apreciar realmente la diferencia entre la nueva tecnología y la anterior. Veamos, por ejemplo, el caso de los primeros automóviles. Hay un motivo por el que esos artilugios se conocían como carruajes sin caballos: eso es básicamente lo que eran. En realidad, la única diferencia entre los primeros automóviles y los carruajes tirados por caballos era que unos usaban caballos y los otros no. Aparte de eso, era difícil apreciar la diferencia.

Por supuesto, hoy nadie confundiría un automóvil con un carruaje tirado por caballos. El motivo es que, con el tiempo, los fabricantes de coches consiguieron avances que diferenciaban claramente los coches de los carruajes. Por ejemplo, los coches de hoy vienen de fábrica con reproductores de CD, aire acondicionado y sistemas de navegación por satélite; pocos carruajes de caballos pueden decir lo mismo. De la misma manera, suponga que conducía un carruaje tirado por caballos en la década de 1880 y necesitaba soltar el Frappuccino por un momento; lo sentimos, mala suerte. En contraste, algunos SUV vienen con nada menos que 17 soportes para vasos de serie y hay, como mínimo, un automóvil que incluye tres soportes para vasos sólo para el conductor. Algunos modelos más nuevos incluso disponen de soportes para vasos que pueden calentar o enfriar la bebida según lo desee.

Nota Sí, es difícil creer que, en algún momento, las personas tuvieron que sobrevivir sin poder beber tres bebidas diferentes mientras conducían. ¿Cómo va a conducir con sólo una o dos bebidas a su alcance?

Antes de que una tecnología nueva sea un éxito, la gente necesita saber por qué debe decantarse por la nueva y desconocida en lugar de por la antigua y de confianza. Cuando los DVDs aparecieron en el mercado, permitían ver películas, igual que los reproductores de vídeo. Sin embargo, los DVDs eran mucho más caros que los reproductores de vídeo y los reproductores de DVD no permitían grabar nada. No hace falta decir que los DVDs no arrasaron. De hecho, hasta que los fabricantes de DVD no empezaron a incluir escenas inéditas, comentarios de actores que ni siquiera se sabía que aparecían en la película y otras características que no tenían las cintas de vídeo, los DVDs no empezaron a sustituir a sus homólogos VHS. No bastaba con poder ver una película en casa, los fabricantes de DVD tenían que ofrecer algo más de lo que ya tenía la gente.

Nota Si alguien mira estos extras, es otro tema: la naturaleza humana es así, si hay algo disponible, lo quieres. Casualmente, los chicos del scripting están pensando en diseñar un DVD en el que se incluya, principalmente, texto eliminado de las columnas de la revista TechNet Magazine y finales alternativos para las secuencias de comandos de administración del sistema.

Uso de Windows PowerShell

Windows PowerShell™, la nueva tecnología de secuencias de comandos/shell de comandos de Microsoft, es otro ejemplo. La primera información que se suele recibir sobre Windows PowerShell es la siguiente:

  • "Windows PowerShell permite administrar procesos y servicios."
  • "Windows PowerShell permite recuperar eventos de los registros de eventos."
  • "Windows PowerShell permite usar WMI para administrar equipos."

Estas tareas no tienen nada de malo, de hecho son útiles e importantes. El único problema es que se puede realizar con VBScript y Windows Script Host. La compatibilidad con versiones anteriores es importante y Windows PowerShell no sería una aplicación innovadora si ni siquiera permitiese realizar las mismas tareas que VBScript. (Imagínese un reproductor de DVD que no pudiese reproducir películas. En realidad, no tiene que imaginárselo: uno de los chicos del scripting tiene uno en casa.)

No obstante, si Windows PowerShell sólo permite realizar las mismas tareas que VBScript, ¿por qué nos íbamos a molestar en descubrir esta nueva tecnología? Es cierto que VBScript no viene con soportes para vasos de serie, pero tampoco Windows PowerShell. Así, ¿en qué radica la diferencia de usar una tecnología de secuencias de comandos u otra?

Francamente, es posible que al fin y al cabo no haya ninguna diferencia. Por otro lado, dejando los soportes para vasos aparte, Windows PowerShell sí tiene algunas capacidades que VBScript no tiene. Si sólo tiene que administrar procesos y servicios, es posible que no tenga ningún motivo de peso para adquirir Windows PowerShell; como se suele decir, si no está roto, no lo arregle. (Para los chicos del scripting, esta máxima suele entenderse como "No intentéis arreglarlo, porque lo estropearéis.") El principal atractivo de Windows PowerShell es que permite realizar operaciones que VBScript no puede; por ejemplo, cambiar la hora de la última escritura de un archivo.

Cambio de la hora de la última escritura

Ha oído bien: cambiar la fecha de la última modificación de un archivo. Existen varios motivos (por ejemplo, una forma rápida y sencilla de control de versión) por los que los escritores de secuencias de comandos siempre han deseado poder cambiar la hora de la última escritura (o hora de creación) de un archivo o conjunto de archivos. Por desgracia, ni el Instrumental de administración de Windows (WMI) ni FileSystemObject tienen esta capacidad, la fecha y la hora del archivo son de sólo lectura en ambas tecnologías.

En cambio, Windows PowerShell permite cambiar la hora de la última escritura de un archivo a la fecha y la hora actuales de una manera tan sencilla como ejecutar el comando siguiente:

$a = Get-Item c:\scripts\test.txt; $a.LastWriteTime = Date

Antes de describir el funcionamiento de este comando, respondamos a una pregunta que seguramente todos tienen en mente: ¿cómo puede Windows PowerShell modificar la hora de la última escritura de un archivo si WMI no puede? Creemos que debemos responder a esta pregunta antes de nada, ya que se trata de una idea equivocada habitual sobre Windows PowerShell. Los usuarios tienden a pensar que Windows PowerShell no es más que una nueva manera de usar WMI. De acuerdo, sin duda se puede usar Windows PowerShell para tener acceso a datos WMI; también es verdad que, mientras esperamos la creación de cmdlets adicionales (comandos nativos de Windows PowerShell), la mayoría de las secuencias de comandos de administración del sistema se basarán principalmente en WMI. Sin embargo, Windows PowerShell se basa esencialmente en .NET Framework y los cmdlets de Windows PowerShell suelen tratar con objetos .NET, no objetos WMI. Esto es importante porque las propiedades disponibles en .NET Framework no son necesariamente las mismas que las propiedades disponibles en WMI.

Por ejemplo, cuando usamos el cmdlet Get-Item para enlazarlo con un archivo, no obtenemos una instancia de la clase WMI CIM_Datafile, sino que obtenemos un objeto .NET. ¿Y eso es tan importante? Le aseguro que lo es. El objeto .NET muestra un conjunto de propiedades y métodos ligeramente diferentes a los que proporciona WMI para la administración de archivos. Como hemos visto, estas pequeñas diferencias pueden ser de suma importancia, como la diferencia entre una propiedad de sólo lectura y otra de lectura y escritura.

Una pregunta de fondo: ¿cómo sabemos que el cmdlet Get-Item devuelve un objeto .NET? En este caso, y en la mayoría de los casos, el modo más sencillo de averiguar con qué clase de objeto estamos trabajando (así como el modo más sencillo de identificar las propiedades y los métodos disponibles) es enlazar el archivo y, a continuación, pasar ese objeto al cmdlet Get-Member:

Get-Item c:\scripts\test.txt | Get-Member

Los resultados de este comando se muestran en la figura 1. Como puede ver, se trata de un objeto .NET (¡como si los chicos del scripting se pudiesen equivocar en algo así!)

Figure 1 Miembros de Objeto devuelto por Get-Item

   
TypeName: System.IO.FileInfo

Name                      MemberType     Definition
----                      ----------     ----------
AppendText                Method         System.IO.StreamWriter AppendText()
CopyTo                    Method         System.IO.FileInfo CopyTo(String destFileName),
                                         System.IO.FileInfo CopyTo(S...
Create                    Method         System.IO.FileStream Create()
CreateObjRef              Method         System.Runtime.Remoting.ObjRef CreateObjRef(
                                         Type requestedType)
CreateText                Method         System.IO.StreamWriter CreateText()

Por cierto, este pequeño comando ilustra dos de las capacidades más interesantes (y útiles) de Windows PowerShell: canalización y metainformación. No entraremos en detalles técnicos, pero la idea básica que se esconde tras la canalización es que puede usar un cmdlet para obtener un objeto y, a continuación, pasar este objeto a otro cmdlet. En este comando hemos usado el cmdlet Get-Item para obtener un objeto que represente el archivo C:\Scripts\Test.txt y, a continuación, hemos pasado este archivo (como un objeto) a través de la canalización al cmdlet Get-Member. (El símbolo | representa la canalización en un comando de Windows PowerShell.)

Entonces, Get-Member realiza su tarea, que consiste en recuperar las propiedades y los métodos para el objeto recuperado. Esta es otra de las ingeniosas características de Windows PowerShell: es muy fácil tener acceso a la metainformación, información sobre la información. Los cmdlets como Get-Member y Get-Command permiten interrogar a Windows PowerShell tanto como desee, más o menos de la misma manera en que escribe una secuencia de comandos de WMI para recuperar información sobre las clases, propiedades y métodos de WMI disponibles.

Recuerde que Get-Member va un paso más adelante de lo que le permite hacer WMI. Puede usar WMI para obtener información sobre objetos WMI, pero no puede usarlo para obtener información sobre otros objetos COM (como por ejemplo, FileSystemObject). No es el caso de Windows PowerShell. Get-Member funciona con todos los objetos que enlace o cree. ¿No recuerda los métodos que hay disponibles cuando usa FileSystemObject? Entonces, ejecute el comando siguiente:

New-Object -comobject "Scripting.     FileSystemObject" | Get-Member

Esta capacidad es increíblemente útil y, hasta la fecha, poco empleada.

Funciona, ¿verdad? Si nos desplazamos por la lista de propiedades y métodos disponibles cuando trabajamos con el archivo C:\Scripts\Test.txt, finalmente veremos esta línea:

LastWriteTime             Property       System.DateTime LastWriteTime {get;set;}

Interesante. Aparentemente, LastWriteTime es una propiedad que admite tanto el comando get (lectura) como el comando set (escritura). ¿Significa esto que podemos usar Windows PowerShell para modificar el valor de la hora de la última escritura del archivo? Hmmm...

Glosario de Windows PowerShell

Alias Nombre personalizable que representa un cmdlet existente. Windows PowerShell proporciona una serie de alias predeterminados que asignan comandos de shell comunes a sus cmdlet equivalentes.

Cmdlet Unidad de funcionalidad más pequeña de Windows PowerShell, análoga a los comandos integrados de otros shells.

Comando Unidad de ejecución en Windows PowerShell. Los comandos pueden incluir varias operaciones canalizadas y pueden abarcar líneas empleando el carácter ;.

Frappuccino Bebida de café con hielo que se sirve en Starbucks.

Shell de comandos Monad/MSH/Microsoft Nombres de código anteriores para Windows PowerShell.

Objeto Datos con estructura recuperados del sistema o un comando. Windows PowerShell manipula los datos como objetos .NET, lo que permite manipular las propiedades de los objetos por nombre, en lugar de tener que analizar la salida del comando basados en texto.

Parámetro Opciones establecidas en un cmdlet de la línea de comandos. Windows PowerShell usa un carácter de guión inicial (-) para designar un parámetro.

Canalización Permite el envío de la salida de un comando a la entrada de otro comando. También se llama canal y, en los comandos, se representa mediante el carácter |.

Perfil Valores que permiten configurar el funcionamiento del shell. Estos valores se cargan cuando se inicia Windows PowerShell.

Secuencia de comandos Uno o más comandos guardados como un archivo y que se ejecutan desde un archivo. Windows PowerShell usa una extensión .ps1 para los archivos de secuencia de comandos.

Shell Entorno de línea de comandos en el que puede ejecutar tanto comandos como cmdlets.

Variable Objeto o parámetro cuyo valor se puede establecer, modificar o recuperar durante la ejecución de un comando.

Retomemos el tema anterior y hablemos sobre el comando que establece la hora de la última escritura de Test.txt en la fecha y la hora actuales. Tiene el siguiente aspecto:

$a = Get-Item c:\scripts\test.txt; $a.LastWriteTime = Date

Como puede ver, el comando no es demasiado complicado. Para empezar, se declara una variable llamada $a. A continuación, se usa el cmdlet Get-Item para conectarse al archivo C:\Scripts\Test.txt. De esta manera, se almacena el objeto en la variable $a. Después de escribir un punto y coma (que permite efectuar varios comandos en una sola línea), se establece el valor de la propiedad LastWriteTime en la fecha y la hora actuales. Esto casi compensa que no tenga soporte para vasos, ¿verdad?

Seamos un poco más elegantes

Por supuesto, no está limitado a establecer la hora de la última escritura en la fecha y la hora actuales. Considere, por ejemplo, este comando:

$b = Get-Date "5/22/2006 8:15 PM";
$a = Get-Item c:\scripts\test.txt; $a.LastWriteTime = $b

Esta vez hemos unido tres comandos. Primero, empleamos el cmdlet Get-Date para crear un objeto de fecha-hora igual a 22/05/2006, 08:15 p.m. ¿Por qué no hemos tenido que usar Get-Date para crear un objeto de fecha-hora en la primera secuencia de comandos, la que establece la hora de la última escritura en la fecha y la hora actuales? Es fácil: el comando Date devuelve automáticamente un objeto de fecha-hora. (Si desea verificarlo, escriba el comando siguiente en la consola de Windows PowerShell: Date | Get-Member.)

Tras crear un objeto de fecha-hora igual a la fecha y la hora deseados, se debe usar el comando Get-Item para obtener un objeto que represente al archivo Test.txt (un objeto que se almacena en la variable $a). Por último, se establece la propiedad LastWriteTime en el valor representado por la variable $b:

$a.LastWriteTime = $b

Lo crea o no, todavía no ha visto ni la mitad. Eche un vistazo a este comando de aspecto inofensivo:

$b = Get-Date "5/22/2006 8:15 PM";
Get-ChildItem c:\scripts | ForEach-Object {$_.LastWriteTime = $b}

¿Qué tiene de interesante este comando? Veamos lo que hace. La primera parte es sencilla: una vez más, se debe crear un objeto de fecha-hora equivalente a 22/05/2006, 08:15. Sin embargo, en la segunda parte no se usa el cmdlet Get-Item, sino que se usa este comando:

Get-ChildItem c:\scripts

¿Por qué? Bueno, cada vez que se aplica el cmdlet Get-ChildItem a una carpeta, se obtiene una colección de todos los archivos que se encuentran en dicha carpeta. Tomemos esa colección y pasemos todos sus elementos a través de la canalización (otra vez, el símbolo |) hasta el cmdlet ForEach-Object.

¿Qué va hacer ForEach-Object con todos estos archivos? Pues va a cambiar el valor de la propiedad LastWriteTime en todos ellos, por supuesto:

ForEach-Object {$_.LastWriteTime = $b}

Nota Aunque la columna de este mes no pretende ser una guía para principiantes de Windows PowerShell, deseamos destacar que $_ es una variable especial que representa el elemento actual de un bucle For Each. Es equivalente a objItem en el bucle de VBScript siguiente:

For Each objItem in colItems
    Wscript.Echo objItem.Name
Next

Cuando el comando de Windows PowerShell termine de ejecutarse, todos los archivos de la carpeta C:\Scripts tendrán la misma hora de la última escritura. ¡Ya nos gustaría ver a uno de esos nuevos carruajes sin caballos hacer eso!

Podríamos estar ejecutando variantes de este comando toda la noche. Por ejemplo, es posible que sólo desee cambiar la hora de la última escritura de los archivos .txt de la carpeta C:\Scripts. De acuerdo, sólo tenía que preguntar:

$b = Get-Date "5/22/2006 8:15 PM"; Get-ChildItem c:\scripts\*.txt | ForEach-Object {$_.LastWriteTime = $b}

Abramos su apetito

Es estupendo. No obstante, queremos mencionar que el objetivo de esta columna no es "venderle" Windows PowerShell, ni animarle a tirar todas sus secuencias de comandos de VBScript y convertirlas a Windows PowerShell. Si esas secuencias de comandos hacen lo que desea y necesita que hagan, déjelas tal como están; y lo mismo para los archivos por lotes, herramientas de líneas de comandos, correctores ortográficos o cualquier otra herramienta que use para administrar sus equipos. Recuerde, si no está roto...

Lo importante no es que Windows PowerShell le permita hacer lo que ya puede hacer, sino que (en parte porque proporciona acceso a .NET Framework) Windows PowerShell le permite hacer cosas que no podía hacer antes. La posibilidad de modificar la fecha del último acceso a un archivo (o un grupo de archivos) es un ejemplo de esto. Si hay otros ejemplos o no, depende de lo que necesite hacer. Esas capacidades son las que hacen que merezca la pena echar un vistazo a Windows PowerShell.

Seguramente, para muchos, ha sido una presentación poco usual a Windows PowerShell: después de todo, en lugar de empezar con un simple "Hola a todos", hemos arrancado directamente con un comando de Windows PowerShell de varias partes, presentando constantemente términos como canalización y cmdlet, como si todo el mundo supiese lo que significan. Ha sido a propósito. Al fin y al cabo, sabemos que muchos de ustedes todavía tienen que probar Windows PowerShell y nos daba miedo enseñarles cómo recuperar una lista de servicios de un equipo y que se limitasen a encogerse de hombros y seguir con lo que estaban haciendo.

Nota Esperamos que no estuviesen conduciendo. Para muchos de ustedes ya es bastante difícil beber tres bebidas diferentes, ver un DVD y hablar por el móvil mientras conducen sin añadir la "lectura de TechNet Magazine" a la mezcla.

Eh, vamos: dijimos para muchos de nosotros. No para todos nosotros.

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.

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