Introducción a Powershell

En algún punto trabajando con Exchange nos vamos a encontrar con que no queda alternativa que recurrir a la línea de comando, específicamente al Shell de Exchange.

El shell de Exchange funciona sobre Windows Powershell por lo que antes de entrar en este tema es recomendable estar familiarizado con los principales conceptos o al menos los que a mi entender pueden resultar de mayor utilidad.

Powershell es una interfaz de línea de comando integrada en el sistema operativo desde Windows 7 o en el caso de servidores Windows Server 2008 R2.

Este es un entorno basado en objetos, es decir que no trabajamos con texto sino que lo hacemos con objetos del .Net Framework.

En todos los casos la sintaxis utiliza un verbo o acción por un lado seguido por un guion y luego un sustantivo o sujeto. Cada cmdlet (comando en Powershell) realiza una tarea administrativa y es posible combinar múltiples comandos para llevar a cabo tareas complejas.

Por ejemplo para ver la lista de servicios de Windows podemos usar el cmdlet Get-Service.

Para definir el comportamiento de un cmdlet utilizamos parámetros, cada parámetro comienza con un guion y en caso de utilizar múltiples parámetros es necesario dejar un espacio entre medio. Para declarar variables usamos el signo de pesos ($) cosa que si armamos un script vamos a usar en múltiples ocasiones. Adicionalmente tenemos a disposición características programáticas y la posibilidad de utilizar loops y estructuras como foreach, If y where entre otras.

A lo largo de este artículo vamos a ver algunas de las interrogantes más comunes al trabajar con Powershell y cómo poner en práctica los conceptos. Para hacer el tema interesante te recomiendo ir abriendo Windows Powershell (powershell.exe) y probar los ejemplos planteados.

Introducción a Powershell


Para qué usar el PIPE (|) en Powershell?

Este es uno de los conceptos más importantes.

Al igual que en muchos otros tipos de shell, el pipe nos permite enviar la salida de un comando a otro. En el caso particular de Powershell en lugar de enviar la salida en texto plano se trabaja con objetos.

Por qué nos podría interesar que trabaje con objetos en lugar de texto plano?

Porque cuando pasamos un objeto lo estamos haciendo junto a todas sus propiedades en lugar de tener que trabajar con una salida de texto en “crudo”.

Dependiendo del idioma del teclado cómo realizar el pipe, lo más sencillo es recordar como hacerlo en ASCII: ALT + 124.

Dentro de una misma línea podemos utilizar varias veces el pipe y si bien lo podemos usar para modificar múltiples objetos en una sola línea, también lo podríamos utilizar para dar formato o filtrar la salida.


Formato de la salida en Powershell

Al ejecutar un cmdlet nos devuelve la salida en un formato predeterminado, esta salida la podemos adaptar a nuestros requerimientos.

Por ejemplo, para obtener un listado de los servicios:

Get-Service

Aprendiendo Powershell | Trabajando con servicios

Este cmdlet de forma predeterminada nos devuelve 3 columnas:

  • Status
  • Name
  • DisplayName

Si solo quisiéramos obtener el estado y el nombre a mostrar podríamos hacer lo siguiente:

Get-Service | Format-Table DisplayName, Status

Aprendiendo Windows Powershell | Formato en Tabla

De este modo solo traería 2 columnas. Esto sería en formato tabla (Format-Table o FT).

De forma predeterminada el formato tabla nos devuelve pocas propiedades, claro que podríamos especificar que propiedades queremos, pero cómo saber que propiedades tiene un objeto?

Siempre podemos recurrir a technet o al sistema de ayuda entre otras opciones, pero lo más rápido en general es utilizar el formato en lista, por ejemplo:

Get-Service | Format-List

Conceptos de Powershell | Formato en lista

Esto devolvería la salida en formato lista (alias: FL) mostrando más propiedades que en el caso de formato tabla, entonces podríamos ver el nombre de cada propiedad y posteriormente especificarla a continuación del tipo de formato, por ejemplo para ver el nombre a mostrar, estado y servicios de los que depende podríamos hacer:

Get-Service | Format-Table DisplayName, Status, DependentServices

Conceptos de Powershell | Formato en Tabla

En este caso podríamos utilizar Format-Table o Format-List dependiendo de la salida deseada.

Si bien esto nos permite dar formato cuando trabajamos de forma interactiva, en algún caso podríamos querer exportar la salida a un CSV o HTML por ejemplo, en estos casos no podemos utilizar ni Format-Table ni Format-List, acá sería necesario utilizar Select-Object (alias: Select):

Get-Service | Select DisplayName, Status

Esto devolvería una salida similar a la de formato tabla, la diferencia es que nos habilitaría a complementar con un cmdlet de exportación, por ejemplo:

Get-Service | Select DisplayName, Status | Export-CSV -Path c:\temp\servicios.csv

Conceptos de Powershell | Exportando a CSV

En este caso el CSV generado incluiría un encabezado seguramente no deseado (#TYPE …):

Conceptos de Powershell | Export a CSV

Para que este encabezado no aparezca podemos usar Export-CSV incluyendo el parámetro NoTypeInformation:

Get-Service | Select DisplayName, Status | Export-CSV -Path c:\temp\servicios.csv -NoTypeInformation

En este caso quedaría del siguiente modo:

Conceptos de Powershell | Exportando a CSV - Encabezado


Filtrado de salida

El cmdlet Where-Object nos sirve para filtrar los datos devueltos por otros cmdlets. Lo podemos encontrar tanto como Where-Object o incluso como “where” o “?”.

El código incluido dentro del “where” se ubica entre paréntesis de tipo llave: “{}” y este código es evaluado para cada objeto que pasa a través del pipeline. El resultado de la expresión puede ser verdadero (true) o falso (false). Si se evalúa “true” el objeto es devuelto, en caso contrario es ignorado.

Por ejemplo, si ejecutamos en Powershell “Get-Service”, este devuelve todos los servicios del equipo. Si solo nos interesan los servicios que tengan la palabra “time” en el nombre podemos filtrar del siguiente modo:

Get-Service | Where {$_.displayname -like “*time*”}

Introducción a Powershell | Filtrando la salida

Si traducimos al español la sentencia diríamos:

“Traer servicios donde el nombre a mostrar tenga la palabra time en cualquier parte”.

En este caso también estamos utilizando el operador “like”.

El operador “like” nos sirve para utilizar comodines como el “*”. Si por ejemplo quisiera todo lo que empiece por time utilizaría “time*”, si quisiera todo lo que finalice con time “*time” y en el caso del ejemplo anterior “*time*”.

Del mismo modo podríamos utilizar a la inversa con “notlike”, en este caso por ejemplo la línea anterior:

Get-Service | Where {$_.displayname -notlike “*time*”}

Se traduciría en:

“Traer servicios donde el nombre a mostrar no tenga la palabra time en ninguna parte”.


Qué es “$_” ?

En el caso del ejemplo anterior el “$_” representa el servicio que en ese momento está pasando por el pipe.

Si queremos acceder a alguna propiedad del objeto que está pasando por el pipe podemos utilizar “.”, entonces si un objeto que pasa por el pipe tiene una propiedad “name” podríamos utilizar “$_.name”.

En un escenario simple podríamos hacer lo siguiente:

“1”,”2″,”3″ | foreach {$_}

Introducción a Powershell | $_

Esto nos devuelve en una línea el “1” en otra el “2” y en otra el “3”.

En definitiva “$_” lo vamos a utilizar para acceder al objeto que está siendo pasado por el pipe.


Estructura Foreach

El foreach nos permite procesar objetos dentro de una colección, por ejemplo:

foreach ($usuario in $usuarios)

En este caso en particular la colección estaría almacenada en $usuarios. Esta colección de usuarios puede ser generada de varias formas por ejemplo importando un listado en CSV.

La variable $usuario en este caso hace referencia a cada línea de un CSV y se pudo haber llamado de otro modo, por ejemplo:

foreach ($linea in $usuarios)

La idea es que para cada línea dentro de la colección de objetos almacenada en $usuarios se ejecute el bloque incluido entre llaves “{}”. En la siguiente demo se ve cómo usar el foreach dentro de un script de alta masiva de objetos en Exchange.


Uso de variables en Powershell

Las variables en Powershell comienzan por “$”. Por ejemplo: $variable

Volviendo al ejemplo de servicios, podríamos almacenar en $servicios todos los servicios y en otra línea filtrar la salida de $servicios utilizando Where:

$servicios = Get-Service

$servicios | Where {$_.displayname -like “*time*”}

Introducción a Powershell | Variables

O directamente podríamos almacenar en $servicios la salida ya filtrada:

$servicios = Get-Service | Where {$_.displayname -like “*time*”}

Conceptos de Powershell | Variables

El nombre de la variable es opcional mientras no coincida con algo reservado para el sistema.


Operadores comunes en Powershell

En Powershell tenemos operadores aritméticos, lógicos, de comparación y asignación.

Veamos algunos de los que vamos a utilizar con más frecuencia:

=” Este sería un operador de asignación y lo que estamos diciendo es que le asigne un determinado valor a una variable, en este caso almacenamos el nombre de un servidor en $servidor y posteriormente ejecutamos la variable para ver qué devuelve:

$servidor = “servidor1”

Operadores en Windows Powershell | Asignación

eq” (equal) Esto se leería “igual” pero no es de asignación sino que de comparación, por ejemplo:

“prueba” -eq “prueba”

Operadores en Windows Powershell | Eq

Esto devuelve “true” porque la palabra “prueba” es igual a “prueba”.

“prueba -eq “prueba1”

Operadores en Powershell | Eq

Esto devuelve “false” porque “prueba” no es igual a “prueba1”.

ne” (not equal) Por el contrario podríamos utilizar “no igual”:

“prueba” -ne “prueba”

Operadores en Powershell | Not Equal

Esto devuelve “false” porque “prueba” es igual a “prueba”, en cambio:

“prueba” -ne “prueba1”

Operadores en Windows Powershell | Not Equal

Devuelve “true” porque “prueba” no es igual a “prueba1”.

Otro operador de comparación muy utilizado es “like” y este nos sirve para utilizar comodines en busca de una coincidencia:

“prueba” -like “*ueba”

Operadores en Windows Powershell | Like

Esto devuelve “true”, por el contrario con “notlike”:

“prueba” -notlike “*ueba”

Operadores en Powershell | Not Like

Devuelve “false”.

En adición tenemos operadores lógicos como “And” y “Not”, por ejemplo para traer todos los servicios que se encuentren iniciados y en el nombre para mostrar incluyan la palabra “time” podríamos ejecutar:

Get-Service | Where {$_.displayname –like “*time*” –and $_.status –eq “Running”}

Powershell | Where


Sobre las comillas en Powershell

El tema de las comillas en muchos casos se puede prestar a la confusión. En este sentido podemos utilizar comillas dobles (“ ”) o simples (‘ ‘).

Cuando utilizamos valores con espacio, por ejemplo Nombre Apellido, estos deben encontrarse entre comillas en todos los casos, estas pueden ser dobles o simples.

Veamos algunos ejemplos con y sin comillas:

$nombre = “Juan”

$apellido = “Perez”

$nombrecompleto = $nombre $apellido

Powershell | Comillas dobles o simples?

En este caso $nombrecompleto da error, probemos nuevamente pero utilizando comillas simples:

$nombrecompleto = ‘$nombre $apellido’

Powershell | Comillas simples

En este caso si ejecutamos $nombrecompleto vemos que devuelve literalmente: $nombre $apellido

El objetivo sería que se muestre el valor de la variable y no la variable de forma literal, por lo que en lugar de comillas simples tendríamos que usar dobles:

$nombrecompleto = “$nombre $apellido”

Powershell | Comillas dobles

Ahora al ejecutar $nombrecompleto se devuelve correctamente: Juan Perez


Ayuda en Powershell

Por último, saber manejarse con el sistema de ayuda de Powershell es muy importante, en lugar de ir a un buscador a ver cómo usar un determinado comando podemos acceder a esta misma información sin salir del shell.

Para esto usamos el cmdlet Get-Help o su alias “Help” seguido por el cmdlet en cuestión.

Tenemos varios parámetros para especificar el nivel de ayuda que deseamos, uno que utilizo con frecuencia es el de “Examples”, este parámetro en lugar de devolver toda la ayuda del cmdlet devuelve ejemplos de casos de uso, muchas veces con esto es suficiente.

Get-Help  Get-Service -Examples

Windows Powershell | Sistema de ayuda

Ayuda en Powershell

En adición podemos obtener ayuda detallada o completa utilizando “Detailed” o “Full” y en caso de que no exista localmente la información, con el parámetro “Online” nos lleva directamente a la página oficial con el detalle del comando.


Con esto llegamos al final del artículo, por más información teórica y práctica sobre el shell de Exchange ver el siguiente recurso para miembros VIP del sitio (videos de entrenamiento):


About Daniel Núñez Banega

Consultor IT especializado en Microsoft Exchange, Active Directory y Microsoft 365.
Principales Certificaciones: Microsoft Certified Trainer | Microsoft Certified Solutions Expert | Microsoft Certified Systems Engineer | Microsoft Certified Systems Administrator | Microsoft Certified IT Professional | Microsoft Certified Technology Specialist | Microsoft 365 Certified: Enterprise Administrator Expert | Microsoft 365 Certified: Security Administrator Associate | Microsoft Certified: Cybersecurity Architect Expert | Comptia Pentest+ | EC-Council Certified Ethical Hacker Master

Reader Interactions

Comments

  1. Soledad Molina says

    Muchas gracias, utilizo esta herramienta de manera empírica. A partir de ahora ya es otra cosa.

  2. Jorge Valenzuela Correa says

    Buen resumen Daniel.
    Solo aportar la mejor innovación, desde mi humilde punto de vista, que incluyen las últimas versiones de Powershell, y es la posibilidad de redirigir las salidas de los comandos, a un contenedor gráfico, que facilitará enormemente el analisis de los resultados, y con solo agregarles al final lo siguiente:

    | out-gridview

    Ejemplo: get-process | out-gridview

    Para hacer tracking de los correos es genial.

    • Daniel Núñez Banega says

      Sin dudas muy práctico el out-gridview para trabajar de forma interactiva. Gracias por el aporte Jorge

Deja una respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *