Agregando lógica a los scripts

La lógica permite que los scripts puedan hacer cosas con las variables que están utilizando y tomar decisiones acerca de qué hacer. Necesitamos saber dos conceptos básicos de lógica para escribir scripts de PowerShell; bucles (loops) y condiciones.

Los bucles o loops le permiten pasar a través de una colección de artículos y hacer algo para cada elemento, por ejemplo, si ejecuta el CmdLet Get-Process en un equipo, PowerShell mostrará una lista de procesos que se estén ejecutando y también, puede asignar la salida de Get-Process a una variable, con el siguiente comando:

$RunningProcesses = Get-Process

En la variable $RunningProcesses, cada proceso está representado por un objeto diferente, se podría recorrer los objetos en esta variable y hacer algo para cada objeto, como mostrar el ID de cada proceso, la forma de lograr esto es con el CmdLet ForEach-Object, como se muestra a continuación:

$RunningProcesses = Get-Process | ForEach-Object {
				  Write-Host "$($_.Name) : $($_.Id)"}

Por medio del Pipeline (|) en la instrucción, la variable $RunningProcesses es recorrida a través de todos los objetos, ejecutando el o los comando dentro de las llaves ({…}) para cada uno de los objetos procesados por el Loop.

Otro tipo de ciclo que podemos utilizar es Do, el ciclo Do le permite recorrer todos los objetos hasta que se cumpla una condición específica. Hay dos tipos de ciclos Do: Do-While y Do-Until.

En un ciclo Do-While, el código se ejecuta una y otra vez, siempre y cuando algo está pasando, por ejemplo, considere el siguiente fragmento de código script:

$Counter = 0

Do {
        Write-Host "Numero Actual: $Counter"
        $Counter++;
        }

While ($Counter -lt 10)

La instrucción Do recorre el código dentro de las llaves por el tiempo que la condición especificada en la instrucción While sea válida, en este ejemplo, el ciclo Do va a seguir adelante, siempre y cuando la variable $Counter sea inferior a 10 (-lt 10), después que el contador ($Counter) llegue a 10 el ciclo se detiene, y por lo tanto sólo los números 0, 1, 2, 4, 5, 6, 7, 8, 9 se muestran.

Con un Do-While, el código dentro de las llaves se ejecuta en primer lugar, y luego se evalúa la condición para determinante si debe continuar o detenerse.

Por otro lado, un ciclo Do-Until  procesa primero la condición. Para entender esto, vamos a convertir el código anterior en un ciclo Do-Until:

$Counter = 0

Do {

    Write-Host "Current Number: $counter"
    $Counter++;
    }

Until ($Counter -gt 10)

Esta vez, el ciclo Do continuará procesando hasta que el contador ($Counter) sea mayor que 10, antes que el código en el ciclo Do se procese se evalúa la condición asegurarse de $Counter sigue siendo 10 o menos.

Después de que la secuencia de comandos muestra que el número actual es 10, $Counter se incrementa a 11, esto hace que la condición ($Counter -gt 10) se cumpla ya que 11 es mayor que 10 y el ciclo Do ya no se procesa.

En nuestros scripts se pueden utilizar las condiciones o ciclos condicionales para tomar decisiones dentro de un script,  una condición que utilizaremos a es If-Else, este ciclo prueba sí determinada condición es verdadera, sí es así, se ejecuta algún código, si no, el ciclo If puede realizar otras comparaciones para evaluar sí alguna otra condición se cumple, por ejemplo:

$RunningProcesses = Get-Process

$RunningProcesses | ForEach-Object {

    $MemUsageMB = $_.PrivateMemorySize / 1024 / 1024

    If ($MemUsageMB -lt 50) {

        Write-Host $_.Name ": Using less than 50MB of memory"
    }
    Else {

        Write-Host $_.Name ": Using " $MemUsageMB "MB of memory"
   	   }
    }

Si ejecutamos este script, obtendremos todos los procesos en ejecución y si está utilizando más de 50 MB de memoria. El comando ForEach-Object recorre todos los procesos, para cada proceso, se evalúa la instrucción If.

El ciclo If recorre los objetos en búsqueda del valor PrivateMemorySize  para verificar si la cantidad de memoria es inferior a 50, sí es así, escribe a la pantalla que el proceso está utilizando menos de 50 MB de memoria, de lo contrario sí el proceso está utilizando más de 50 MB, se ejecuta la instrucción Else.

El parámetro -lt indica que la instrucción If comprueba (en su condición) si $MemUsageMB es menor a 50, además de la instrucción If, se puede utilizar el CmdLet Where-Object, que evalúa los objetos y filtra todo lo que no cumple con la expresión que se ha establecido, por ejemplo, puede utilizar el CmdLet Where-Object siguiendo en una secuencia de comandos para filtrar todos los procesos que utilizan menos de 50 MB de memoria:

Get-Process | Where-Object 
{ $_.PrivateMemorySize / 1024 / 1024 -gt 50 } | 
ForEach-Object { Write-Host $_.Name }

En este comando, el CmdLet Where-Object está pasando por todos los procesos que utiliza más de 50 MB de memoria, los procesos que se superan el filtro se canalizan al CmdLet ForEach-Object para que puedan ser procesados.

También útil para el trabajo con ciclos tenemos los operadores de comparación, aca una buena referencia:

https://technet.microsoft.com/en-us/library/hh847759.aspx

Hasta la próxima !!!

Deja un comentario