Objetos personalizados y tipos estándar

Introducción

PowerShell es un lenguaje de scripting orientado a objetos. Esto significa que los resultados de los comandos y las asignaciones de variables son objetos. Esto contrasta con lenguajes de scripting más convencionales, como cmd o bash en Linux, que manipulan cadenas de caracteres. PowerShell también permite manipular cadenas de caracteres, si es necesario.

En programación, la noción de objeto es una transposición de la vida cotidiana. Puede utilizarse el ejemplo de un coche para explicarlo. Un coche es un objeto. Tiene varios miembros, al igual que un archivo PowerShell:

  • Propiedades: una propiedad contiene información sobre el objeto. En el caso de un coche: su marca, modelo, tapicería o color. Una propiedad también puede contener otro tipo de objeto hijo con sus propios miembros. Ya sea similar a su padre, o completamente diferente. Un coche tiene puertas, que suelen ser del mismo color que el resto del coche, pero con una estructura muy diferente.

  • Métodos: un método se utiliza para realizar una acción sobre el objeto. En el caso de un coche, sirve para arrancarlo o hacerlo avanzar. Y en el caso de las puertas, para abrirlas.

Images/EI05_1.png

En este caso, solo se tratarán dos tipos de miembros (método y propiedad), ya que son los más utilizados. Hay otros, como los eventos, que tienen sus propios usos.

Objetos personalizados

Lo interesante es que puede crear sus propios objetos con los miembros que decida definir para ellos. De este modo, pueden incorporarse a funciones y utilizarse a través de un pipeline. Esto ofrece una gran flexibilidad y libertad a la hora de programar. También es una buena práctica a la hora de diseñar scripts.

1. Crear un objeto personalizado

Para crear un objeto personalizado, puede utilizar el tipo [psobject] con el comando New-Object:

PS > New-Object -TypeName psobject -Property @{  
    Name = 'Nicolas BAUDIN'  
    Email = 'nicolas.baudin@frpsug.com'  
    Age = 25  
    PostalCode = 44000  
}  
  
Email                        Name             Age PostalCode  
-----                        ----             --- ----------  
nicolas.baudin@frpsug.com    Nicolas BAUDIN    25      44000 

Se puede observar que no se respeta el orden de las propiedades. Para que esto sea así, es necesario utilizar un hashtable de tipo [ordered]:

PS > $Hash = [ordered]@{  
    Name = 'Nicolas BAUDIN'  
    Email = 'nicolas.baudin@frpsug.com'  
    Age = 25  
    PostalCode = 44000  
}  
PS > New-Object -TypeName psobject -Property $Hash  
  
Name             Email                       Age PostalCode  
----             -----                       --- ----------  ...

Tipos estándar

Hasta ahora, hemos hablado de añadir miembros a instancias de objetos específicos, utilizando el comando Add-Member. Ahora bien, ¿cómo se añade un miembro a un tipo de objeto? Supongamos que el miembro que desea añadir es esencial para llevar a cabo las tareas cotidianas, y que llamar a Add-Member cada vez que crea un objeto de un tipo concreto resulta poco práctico. ¿Cuáles son las opciones?

Hay muchas soluciones que se pueden aplicar en esta situación, pero solo dos serán descritas en el resto de este capítulo. La primera es utilizar un archivo .types.ps1xml, junto con el cmdlet Update-TypeData. El archivo .types.ps1xml se basa en un esquema XML diseñado específicamente para este fin. El archivo .types.ps1xml del directorio de instalación de PowerShell ($PSHOME) puede utilizarse como ejemplo. La segunda solución consiste en utilizar únicamente el cmdlet Update-TypeData.

Atención: no es aconsejable modificar directamente el archivo .types.ps1xml. Dado que Microsoft ha firmado digitalmente este archivo, cualquier modificación podría provocar fallos de funcionamiento al utilizar PowerShell.

1. Añadir un miembro mediante un archivo .types.ps1xml

Es útil utilizar un archivo de extensión de tipo en un módulo. Para ello, basta con colocar el archivo en un directorio del módulo e indicarlo en el manifiesto en el campo TypeToProcess. El archivo se cargará cuando se importe el módulo. 

Antes de seguir adelante, es necesario determinar con precisión qué hay que hacer y sobre qué tipo de objeto.

Recuperar los derechos NTFS asignados a un archivo o carpeta puede resultar complicado al principio. Generalmente, esto implica buscar en los distintos miembros de los objetos archivo y carpeta. Estos objetos tienen un método llamado GetAccessControl(). Este método recupera los distintos derechos de acceso de un archivo o carpeta.

PS > $File = Get-Item ./MyFile.docx  
PS > $File.GetAccessControl()   
  
Path Owner                 Access  
---- -----                 ------  
     AUTORIDAD...

Formato

Después de ver cómo se trabaja con objetos en PowerShell, queda un último aspecto por conocer: cómo se presentan en la consola. Como se ha descrito en capítulos anteriores, los applets de comandos de PowerShell devuelven objetos. Estos se presentan de diferentes maneras en la consola. Es importante tener en cuenta que no es el comando el que define el formato del objeto que devuelve. De hecho, lo que determina el formato de sus propiedades, ya sea en forma de tabla o lista, es su tipo. Esta es la razón por la que dos comandos diferentes que devuelven el mismo objeto tienen la misma presentación en pantalla. La elección de las propiedades mostradas ha sido realizada por Microsoft.

Este proceso garantiza un cierto grado de legibilidad en la consola, sin abrumarla. Aunque se aplique un formato a un objeto, todas las propiedades siguen estando disponibles. Se trata ante todo de una cuestión estética.

Dicho esto, PowerShell ofrece la posibilidad de modificar las propiedades que muestra un objeto, sea del tipo que sea: personalizado o estándar. Pero antes de entrar en materia, hay que saber algunas cosas. El formato se define en los archivos .format.ps1xml. Al igual que los archivos .types.ps1xml, éstos tienen su propio esquema XML. En el caso de que un tipo no tenga un archivo de formato, como los objetos personalizados, el formato se produce de la siguiente manera:

  • Mostrar como tabla si el objeto tiene cuatro propiedades o menos

  • Mostrar como lista si el objeto tiene más de cuatro propiedades

Hay otro dato importante que conviene conocer. En el caso de una colección de objetos, si el primer objeto contiene un número limitado de propiedades (por ejemplo, tres), pero los objetos que le siguen tienen más, solo se mostrarán las propiedades idénticas al primer objeto cuando se utilice Format-Table.

Cuando se utiliza un comando y devuelve un resultado, este se envía primero por la canalización (pipeline) y lo procesa el comando Out-Default. Si el resultado es una cadena de caracteres, entonces se envía por la canalización para mostrarse mediante Out-Host. En caso contrario, Out-Default utiliza el tipo de objeto que pasa por la tubería para organizar su visualización. Utiliza las vistas definidas en los archivos .format.ps1xml. Por último, si no encuentra una vista para el tipo de objeto...