Windows PowerShell: Piense en comandos, no en scripts

No se intimidated por el término “ secuencias de comandos ”, puesto que puede hacer mucho con Windows PowerShell con comandos sencillos.

Don Jones

Percepción ha sido una de las dificultades más importantes, que Windows PowerShell ha tenido en lo que respecta a la aceptación del administrador. Hay una percepción persistente que el shell es “ lenguaje de secuencias de comandos ”, como VBScript. Mientras que muchos administradores encanta lo que pueden hacer con un lenguaje de secuencias de comandos, mucho más se desactivan la percepción de la complejidad y una curva de aprendizaje pronunciada.

Es una lástima. El shell es compatible con un enfoque basado en la secuencia de comandos eficaz, pero igualmente un enfoque más simple y orientada por el comando. La belleza real del shell es que puede utilizar cualquiera de los enfoques para realizar muchas de las mismas tareas.

Una secuencia de comandos

La siguiente función aceptará los nombres de equipo desde la línea de comandos, como cadenas o en la propiedad “ NombreDeEquipo ” de un objeto de entrada.También recuperará la información del BIOS y del sistema operativo de cada equipo con Windows Management Instrumentation (WMI):

function Get-Inventory
{
   [CmdletBinding()]
   Param(
       [Parameter(Mandatory=$true,
                 ValueFromPipeline=$true,
                 ValueFromPipelineByPropertyName=$true)]
       [string] $computername
   )
   Process {
      $os = gwmi win32_operatingsystem -computername $computername
      $bios = gwmi win32_bios -computername $computername
      $obj = new-object psobject
      $obj | add-member noteproperty ComputerName $computername
      $obj | add-member noteproperty OSBuild ($os.buildnumber)
      $obj | add-member noteproperty SPVersion ($os.servicepackmajorversion)
      $obj | add-member noteproperty BIOSSerial ($bios.serialnumber)
      Write-output $obj
   }
}

Nota que los paréntesis hacen que el shell para ejecutar expresiones, como, por ejemplo, obtenga la propiedad BuildNumber del objeto en la variable de sistema operativo $ y devolver el resultado de esa expresión como el tercer valor de parámetro de Add-Member.

También puedo ejecutar esta función, tuberías en los nombres de equipo estático:

'localhost','server2' | Get-Inventory

O bien enviando el contenido de un texto de archivo que contiene un nombre de equipo por línea:

Get-Content names.txt | Get-Inventory

O incluso recuperar objetos de equipo de Active Directory, cambiando la propiedad Name para NombreDeEquipo y canalizarlos:

Import-Module ActiveDirectory
Get-ADComputer –filter * | Select-Object @{Label='ComputerName';Expression={$_.Name}} | Get-Inventory

Por cierto, utilizo las llaves para encapsular el código ejecutable. El marcador de posición de $ _ representa el objeto por departamento en el cmdlet Select-Object. Los resultados de cualquiera de los siguientes son una tabla con claridad y con formato de cuatro columnas. Puede fácilmente redirigir ese resultado a un archivo, la impresora o la cuadrícula, o incluso filtrar y ordenar los resultados antes de mostrarlos. Por ejemplo:

Get-Content names.txt | Get-Inventory | Where { $_.BuildNumber –eq 7600 } | Sort ComputerName

Una vez más, las llaves encapsulan un bloque ejecutable de código, la expresión que desea filtrar, y el marcador de posición de $ _ representa el objeto por departamento.

Rendimiento de comandos

No hay ningún problema con una secuencia de comandos como ésta, pero funciona bastante esfuerzo. Es un generador o programador de estilo que una gran cantidad de administradores encontrar intimidatorio. Se puede hacer lo mismo en un comando único, un poco complejo. Llave usted mismo:

Get-WmiObject Win32_OperatingSystem -computername (get-content names.txt) | 
Select-object @{Label="ComputerName";Expression={$_.__SERVER}},
             @{Label="OSBuild";Expression={$_.BuildNumber}},
             @{Label="SPVersion";Expression={$_.ServicePackMajorVersion}},
             @{Label="BIOSSerial";Expression={(gwmi win32_bios -comp $_.__server).serialnumber}}

Hay una gran cantidad de allí. Ésta es una lista:

  1. En primer lugar, ejecute Get-WmiObject, para recuperar el objeto de Win32_OperatingSystem de los nombres de equipo especificado. Si es usted un lector normal de esta columna, ya sabrá que los objetos devueltos por Get-WmiObject incluirá siempre una propiedad __SERVER, que contiene el nombre del equipo procedentes de los objetos WMI.
  2. Los objetos WMI se canalizan a Select-Object. Uso cuatro tablas de hash para definir cuatro propiedades: NombreDeEquipo, OSBuild, SPVersion y BIOSSerial. Cada tabla de hash especifica una etiqueta, que posteriormente se utilizará como el encabezado de columna para la salida y una expresión. La tabla hash se construye mediante el uso de la @ operador de matriz, seguido de la definición de etiqueta/expresión dentro de llaves. Las llaves incluya el código ejecutable que define la parte de la expresión de la tabla hash.
  3. Para las tres primeras columnas, la expresión sólo es hacer referencia a una propiedad existente del objeto;Básicamente estoy cambie sólo el nombre de propiedad.
  4. Para la cuarta columna, la expresión se realmente está ejecutando una segunda consulta WMI en el mismo servidor. Extrae el nombre del equipo de la propiedad __SERVER. ¿Vea cómo la llamada WMI toda está encerrada entre paréntesis? Los que la expresión se ejecuta en primer lugar. Cualquier objeto que da como resultado de dicha expresión va a insertarse en lugar de la parte entre paréntesis. El punto después del paréntesis de cierre que se me permite tener acceso a las propiedades del objeto resultante, por lo que estoy acceso a la propiedad de número de serie para la cuarta columna.

En cierto modo, esta sintaxis es más difícil de leer que la secuencia de comandos con el que inició. Es compacto y utiliza una gran cantidad de signos de puntuación. Éste es el tipo de cosas que puede utilizar como plantilla y modificarlo según sus necesidades de otros. Si no sabe por qué no funciona, publique una pregunta en mi blog en ConcentratedTech.com y le ayudaré a averiguarlo.

No llamar IT una secuencia de comandos

El punto es que Windows PowerShell no es necesario que se utiliza como un lenguaje de secuencias de comandos. El comando demostré puede ser complejo, pero no más compleja que algunos de los comandos extravagante que he visto los administradores escribir para el antiguo shell cmd.exe. Una vez que se haya acostumbrado a la sintaxis, que hay que reconocer que tiene cierta práctica, el comando es mucho menos complicado que escribir todo-en la secuencia de comandos o la función.

Por lo tanto, no deje que el término “ lenguaje de secuencias de comandos ” activar fuera desde el shell. Sólo es tan “ scripty ” como usted elija.

Don Jones

Don Jones es un fundador de la tecnología concentrado y preguntas de respuestas sobre Windows PowerShell y otras tecnologías en ConcentratedTech.com. También es un autor de Nexus.Realtimepublishers.com, lo que muchos de sus libros disponibles, como las ediciones electrónicas gratuitas a través de su sitio web.

Contenido relacionado