Capítulo 1: ¿Qué es PowerShell?

Publicado por P. Ruiz en

Redirecciones y tuberías

Básicamente, tanto las redirecciones como las tuberías tienen como objetivo obtener la salida de una acción y dirigirla a un lugar diferente del predeterminado (que normalmente es la pantalla)

Redirecciones

Las redirecciones están orientadas a la obtención de un archivo de texto con la salida que ofrece un cmdlet.

De esta forma, en lugar de consultar el resultado en ese momento, podremos guardarlo para revisarlo en el futuro.

Existen dos formas de realizar redirecciones:

  • Usando el carácter >: Crea un nuevo archivo y deposita en él la salida del cmdlet. En caso de que el archivo exista previamente, sustituye su valor anterior por el nuevo.

    Veamos un ejemplo:

    Get-ChildItem > prueba.txt

    Escribimos la orden y pulsamos la tecla Intro.

    PowerShell-025

    A continuación, comprobamos el contenido del archivo

    … Por ejemplo, utilizando el bloc de notas.

    PowerShell-026

  • Usando los caracteres >>:  Añade al contenido del archivo la salida del cmdlet. En caso de que el archivo no exista previamente, se crea.

    En este caso, el ejemplo quedaría así:

    Get-ChildItem >> prueba.txt

    Volvemos a escribir la orden y pulsar la tecla Intro.

    PowerShell-027

    Y comprobamos de nuevo el contenido del archivo.

    Donde comprobamos que, efectivamente, la nueva salida se ha añadido a la anterior.

    PowerShell-028

Actividades resueltas: Trata de resolver las siguientes cuestiones, antes de consultar la respuesta:

    1. El cmdlet Get-WmiObject Win32_ComputerSystem nos permite obtener información sobre el sistema. ¿Cómo podrías guardar esa información en un archivo de texto llamado informacion.csv del directorio actual?

    2. El cmdlet Get-Process nos ofrece una lista de los procesos que se encuentran en ejecución en el sistema. ¿Cómo podrías guardar la lista en un archivo de texto llamado procesos.txt del directorio actual?

Lógicamente, para guardar el archivo en una ubicación diferente, solo habría que cambiar la ruta (en este caso .\ para la ubicación actual), por la ubicación adecuada.

Tuberías

El objetivo de las tuberías consiste en conectar la salida de un cmdlet con la entrada de otro, que la tratará como su información de inicio. Este mecanismo no se limita a dos cmdlets, si no que puede haber un tercero, un cuarto, etc.

Para establecer una tubería, basta con escribir el primer cmdlet y, a continuación, el carácter pleca (|), que suele llamarse operador de canalización. Por último, escribiremos el segundo cmdlet.

En la mayoría de los teclados, para obtener el carácter pleca (|), usaremos la combinación de teclas Alt Gr + 1.

De hecho, el primer ejemplo que pusimos en esta documentación, ya usaba una tubería:

Get-Command -CommandType cmdlet | Measure-Object

En este ejemplo, comenzamos con el cmdlet Get-Command, que permite obtener una lista con todos los comandos instalados en el sistema, incluidos cmdlets, alias, funciones, flujos de trabajo, filtros, scripts y aplicaciones.

Para reducir el abanico, empleamos el parámetro -CommandType, donde le indicamos que sólo estamos interesados en los cmdlets.

Hasta aquí, estaríamos ejecutando un cmdlet individual, como habíamos hecho hasta ahora con Get-Help o Get-ChildItem:

Get-Command -CommandType cmdlet

Al ejecutarlo, tendríamos una relación completa de los cmdlets que tenemos disponibles en nuestro equipo.

La lista es mucho más larga de lo que se ve en la imagen..

PowerShell-031

Sin embargo, a pesar de que Get-Command puede ser muy útil, no era lo que necesitábamos en el momento de incluir por primera vez el ejemplo. Si recuerdas, el objetivo era saber cuántos cmdlets teníamos, no cómo se llamaban todos ellos.

Por ese motivo, redireccionamos la salida de Get-Command para que se utilizara como entrada en Measure-Object, cuya función es, básicamente, contar los distintos valores recibidos.

Así averiguamos que el número total de cmdlets que teníamos instalados en nuestro sistema era de 666.

PowerShell-032

Puedes encontrar información detallada sobre el cmdlet Measure-Object, en la dirección https://msdn.microsoft.com/en-us/powershell/reference/5.1/microsoft.powershell.utility/measure-object.

A diferencia de otros intérpretes de comandos, PowerShell no comunica un cmdlet con el siguiente enviando la salida en texto plano. En su lugar, se envían objetos (en el ejemplo anterior, uno por cada línea de salida con información). De este modo, el cmdlet que recibe la salida puede utilizarla directamente, sin tener que analizar la sintaxis del texto generado por el primer cmdlet.

Esto es posible porque PowerShell se basa en .NET framework, del que hereda sus características orientadas a objetos.

Incluso puedes combinar las tuberías con las redirecciones, obteniendo el resultado en un archivo. Por ejemplo, imagina que necesitas saber, en las carpetas de los usuarios del sistema, qué archivos exceden un determinado tamaño.

Primero debemos pensar en cómo obtener todos los archivos que hay en la carpeta Users. Pero esto ya lo sabemos hacer, basta con utilizar el cmdlet Get-ChildItem indicando la ruta donde buscamos y, en este caso, el parámetro -Recurse para que también busque en las subcarpetas:

Get-ChildItem C:\Users -Recurse

Lógicamente, para tener acceso a los archivos de todos los usuarios, deberemos estar ejecutando PowerShell con privilegios administrativos.

El resultado será una lista de todos los archivos que hay en la ruta indicada. Para filtrar los que nosotros necesitamos, basta con enviar la salida al cmdlet Where-Object, que nos permite filtrar la salida anterior en función del tamaño del objeto (en nuestro ejemplo, los archivos mayores que 1 MB, pero tú puedes usar la cantidad que prefieras):

Get-ChildItem C:\Users -Recurse | Where-Object Length -gt 1mb

Finalmente, enviaremos la salida a un archivo para poder consultarla más tarde:

Get-ChildItem C:\Users -Recurse | Where-Object Length -gt 1mb > archivos.txt
PowerShell-033

Actividades resueltas: Trata de resolver las siguientes cuestiones, antes de consultar la respuesta:

    1. El cmdlet Out-File nos permite enviar la información que reciba a un archivo. Puede ser similar al operador de redirección que hemos visto arriba (‘>’), pero con la ventaja de que dispone de diversos argumentos (que no usaremos en este ejemplo), No obstante, ¿Cómo crees que sería la sintaxis que nos permitiría enviar la salida del cmdlet Get-Process al archivo de texto procesos.txt del directorio actual?

    2. Algo parecido al ejemplo anterior, podríamos hacer para listar el contenido de un directorio y guardar el resultado en un archivo de texto.

    3. Siguiendo la idea del último ejemplo, también podríamos filtrar eventos, del registro de eventos, y redirigir la salida a un archivo de texto. Por ejemplo, Get-WinEvent -LogName Application -MaxEvents 100 obtiene los últimos 100 eventos del registro Application de eventos del sistema. A continuación, Where-Object {$_.Level -eq 2} puede filtrarlos para quedarse con aquellos que tengan un nivel de error 2. ¿Serías capaz de combinar ambas órdenes y obtener la salida en un archivo de texto llamado errores.log del directorio actual?

      PowerShell-036

      Recuerda escribir toda la orden anterior en una sola línea.