Pide tu presupuesto ya!

Una guía práctica de lógica condicional

PowerShell 101: flujo de control y lógica condicional

Al automatizar tareas en varios servidores, escribir código eficiente para manejar acciones repetitivas puede ahorrar mucho tiempo y reducir la posibilidad de errores. En PowerShell, el código de andamiaje para manejar tareas, incluidas las comprobaciones de servidores y la administración de archivos, garantiza que pueda administrar varios servidores sin problemas.

Este tutorial explora estrategias clave para crear y organizar scripts de PowerShell que le permiten realizar tareas de manera eficiente en múltiples servidores utilizando matrices, lógica condicional y un manejo sólido de errores.

Código de andamiaje para múltiples tareas

La implementación del código es importante cuando se realizan múltiples tareas, como verificar servidores y leer el mismo archivo en ellos. Este proceso significa escribir primero el código que actúa sobre un solo elemento.

En este comando, se utiliza `Get-Content`, junto con la ruta UNC para un único servidor y el nombre del archivo. Este comando no funcionará tal como está, pero constituye el núcleo de lo que necesitamos.

## Step 1: Scaffold the command you need to run against each server
Get-Content -Path "\\servername\c$\App_configuration.txt"

Observe que todo lo que ve son comentarios en este script de demostración con regiones. Las regiones le permiten contraer y expandir secciones de código para que el código sea más fácil de leer y organizar. Puede expandir y contraer regiones ya que VS Code reconoce regiones de la extensión de PowerShell.

Almacenamiento y referencia de servidores en una matriz

Dado que procesaremos muchos servidores, una matriz puede almacenarlos todos. Cuando se trata de elementos similares, utilizar una matriz es una buena práctica.

## Since there are multiple servers involved, defining them in an array is always the best way
$servers = @('localhost','SRV2','SRV3','SRV4','SRV5')

Ahora puede hacer referencia a cada servidor de la matriz.

## Now you can reference each element in the array instead of referencing different server name variables.
## This will come in handy when we loop later
Get-Content -Path "\\$($servers[0])\c$\App_configuration.txt"
Get-Content -Path "\\$($servers[1])\c$\App_configuration.txt"
Get-Content -Path "\\$($servers[2])\c$\App_configuration.txt"
Get-Content -Path "\\$($servers[3])\c$\App_configuration.txt"
Get-Content -Path "\\$($servers[4])\c$\App_configuration.txt"

Comprobación de la conectividad del servidor y uso de lógica condicional

Con un código aproximado para leer el archivo, el siguiente requisito es verificar si el servidor está en línea. El cmdlet `Test-Connection` realiza esta tarea haciendo ping al servidor.

El uso del parámetro `Quiet` hace que `Test-Connection` devuelva un valor booleano Verdadero o Falso si PowerShell puede hacer ping al servidor. El parámetro `Count` limita los intentos a uno.

Pruebe el código para cada “estado”; en este caso, se puede hacer ping o no.

## Come up with the code to handle the next requirement
Test-Connection -ComputerName 127.0.0.1 -Quiet -Count 1
Test-Connection -ComputerName 111.111.111.111 -Quiet -Count 1

Ahora que se cumplen ambos requisitos, es hora de comprender la lógica condicional.

Comience con comparaciones de igualdad utilizando el operador `-eq`, que compara un valor de referencia a la izquierda con un valor de comparación a la derecha.

## Testing equality comparisons
1 –eq 1

1 es igual a 1, ¿verdad? PowerShell confirma esto devolviendo “$true”.

Para verificar si un valor NO es igual a algo, use el operador `-ne`.

## Testing the inequality comparisons
1 -ne 2

A continuación, agregue la declaración “if”, una construcción común en las secuencias de comandos.

Este ejemplo devuelve una cadena si la condición definida es `$true`. PowerShell ejecuta el código SÓLO si la condición es verdadera.

## Check if 1 equals 1 and output a message if true
if (1 -eq 1) {
    'Duh. 1 equals 1'
}

Opcionalmente, respalde la otra condición y tome medidas si ocurre.

## Check if 1 equals 2 and output the appropriate message
if (1 -eq 2) {
    'True'
} else {
    'Yep, not true'
}

Aplicar lógica condicional a las comprobaciones del servidor

Aplique esto a nuestra situación actual. Dado que `Test-Connection` ya devuelve un valor `$true` o `$false` usando el parámetro `Quiet`, utilícelo como condición en la declaración if.

Este código intenta hacer ping al primer elemento de la matriz `$servers`.

Si devuelve `$true`, ejecuta el código para obtener el contenido del archivo de configuración. En caso contrario, devuelve un mensaje indicando lo contrario.

## Check if the server is online and read its configuration file,
## otherwise, report it's offline
if (Test-Connection -ComputerName $servers[0] -Quiet -Count 1) {
    Get-Content -Path "\\$($servers[0])\c$\App_configuration.txt"
} else {
    Write-Host "The server $($servers[0]) is offline!"
}

Aún mejor, use el cmdlet `Write-Error` para devolver un objeto de error, resaltado en rojo, haciendo obvio lo que sucedió.

## Check if the second server is online and read its configuration file, 
## otherwise, log an error
if (Test-Connection -ComputerName $servers[1] -Quiet -Count 1) {
    Get-Content -Path "\\$($servers[1])\c$\App_configuration.txt"
} else {
    Write-Error "The server $($servers[1]) is offline!"
}

El operador `-not` puede crear la lógica opuesta negando el resultado.

## # Check if the second server is offline using -not and log an error, 
## otherwise, read its configuration file
if (-not (Test-Connection -ComputerName $servers[1] -Quiet -Count 1)) {
    Write-Error "The server $($servers[1]) is offline!"
} else {
    Get-Content -Path "\\$($servers[1])\c$\App_configuration.txt"
}

Manejo de múltiples estados

Considere otro estado: el servidor podría estar en línea, pero el archivo podría no existir. Este enfoque es un desarrollo iterativo: crear código según sea necesario en lugar de intentar anticipar todos los escenarios por adelantado.

Para tener en cuenta este tercer estado, utilice el operador “-y”. Este operador le dice a PowerShell que ejecute “Test-Connection”.

Si el servidor está en línea, verifica la existencia del archivo con el cmdlet `Test-Path`, que devuelve `$true` o `$false`.

## Check if the server is online -and if the configuration file exists, 
## otherwise, log an error
if ((Test-Connection -ComputerName $servers[0] -Quiet -Count 1) -and (Test-Path "\\$($servers[0])\c$\App_configuration.txt")) {
    Get-Content -Path "\\$($servers[0])\c$\App_configuration.txt"
} else {
    Write-Error "The server $($servers[0]) is offline or the app configuration file doesn't exist!"
}

Quizás desee excluir temporalmente uno de los servidores del conjunto. Si es así, cree código para excluirlo en lugar de eliminarlo, que se puede eliminar fácilmente más adelante utilizando una construcción “elseif”.

## Exclude the specified server, otherwise, check if the server is online 
## and the configuration file exists
$excludeThisServer="localhost"
if ($servers[0] -eq $excludeThisServer) {
  Write-Host "Excluding the $($servers[0]) server temporarily."
} elseif ((Test-Connection -ComputerName $servers[0] -Quiet -Count 1) -and (Test-Path "\\$($servers[0])\c$\App_configuration.txt")) {
    Get-Content -Path "\\$($servers[0])\c$\App_configuration.txt"
} else {
    Write-Error "The server $($servers[0]) is offline or the app configuration file doesn't exist!"
}

Optimización de la lógica condicional con declaraciones de “cambio”

Puede encadenar varias construcciones `elseif`, pero una declaración de cambio suele ser mejor si hay más de 1 o 2.

La declaración `switch` define una única condición y verifica claramente varios valores de salida para esa condición. Cada condición tiene un conjunto de llaves y una construcción “predeterminada” coincide si no se cumple ninguna de las otras condiciones.

## The switch Statement

## Structure
switch (expression) {
    outputvalue {
        # Do something with code here.
    }
    outputvalue {
        # Do something with code here.
    }
    default {
        # Stuff to do if no matches were found
    }
}

La palabra clave `break` detiene el cambio cuando se encuentra una coincidencia; de lo contrario, procesa todos los elementos incluso después de realizar una coincidencia.

Observe cómo ambos devolvieron información. La palabra clave “break” detiene eso.

$currentServer = $servers[0]
switch ($currentServer) {
    'localhost' {
        Write-Host "The current server value is $_"
        break
    }
    'SRV1' {
        Write-Host "The current server value is $_"
        break
    }
    'SRV2' {
        Write-Host "The current server value is $_"
        break
    }
    default {
        Write-Host "No matches found for the current server $_"
    }
}

Además, observe la variable `$_`, que representa el valor de salida de la expresión dentro de la declaración de cambio. Una vez que la declaración de cambio termina de ejecutarse, `$_` desaparece.

Comprender los “estados”, las condiciones y controlar el flujo de código es fundamental en PowerShell y una tarea que encontrará con frecuencia.

switch (1) {
    1 {
        Write-Host "The number is $_"
    }
    2 {
        Write-Host "The number is $_"
    }
    1 {
        Write-Host "The number is $_"
    }
    default {
        Write-Host "No number matches for $_"
    }
}

Conclusión

Siguiendo este enfoque, puede optimizar tareas complejas como verificar la conectividad del servidor, leer archivos de configuración y manejar excepciones. Todo esto se hace de una manera que sea escalable y eficiente.

Ya sea que se trate de un puñado de servidores o de una infraestructura más extensa, el uso de matrices, lógica condicional y cmdlets integrados de PowerShell ayuda a crear scripts resistentes y fáciles de mantener.

Con estas técnicas, ahora puede manejar varios estados del servidor de manera efectiva y responder a los errores rápidamente, garantizando operaciones fluidas en su entorno de TI.

Written by

Leave a comment