Powershell

Bucles en PowerShell: ForEach, While y Do-Until con ejemplos

Los bucles son donde PowerShell pasa de «ejecutar comandos» a «automatizar de verdad». También son donde más dudas surgen, porque hay dos foreach distintos y varios bucles clásicos. Aclarémoslo de una vez con ejemplos que puedes probar según lees.

foreach (la instrucción): rápido y legible

$servicios = Get-Service | Where-Object Status -eq 'Stopped'
foreach ($s in $servicios) {
    Write-Output "Detenido: $($s.DisplayName)"
}

Carga toda la colección en memoria y la recorre. Es la opción más rápida y clara cuando los datos caben en memoria (miles de elementos, sin problema).

ForEach-Object (el cmdlet): para tuberías

Get-ChildItem C:\Logs -Filter *.log |
    ForEach-Object { Compress-Archive $_.FullName "$($_.FullName).zip" }

Procesa los elementos según llegan por la tubería, sin cargarlo todo en memoria. Es la elección correcta con colecciones enormes o cuando encadenas cmdlets. Dentro del bloque, $_ es el elemento actual.

While: repite mientras se cumpla la condición

# Esperar a que un servidor responda
while (-not (Test-Connection servidor01 -Count 1 -Quiet)) {
    Write-Output 'Esperando al servidor...'
    Start-Sleep -Seconds 10
}
Write-Output '¡Servidor en línea!'

Do-While y Do-Until: ejecutar al menos una vez

do {
    $respuesta = Read-Host '¿Continuar? (s/n)'
} until ($respuesta -in 's','n')

do garantiza que el cuerpo se ejecuta al menos una vez — perfecto para pedir datos al usuario. until repite hasta que la condición sea verdadera; while, mientras lo sea. Elige el que haga la condición más legible.

Controlar el flujo: break y continue

foreach ($equipo in $lista) {
    if ($equipo -eq 'excluido01') { continue }  # saltar este
    if (-not (Test-Connection $equipo -Count 1 -Quiet)) { break }  # abortar el bucle
    # ... trabajo ...
}

El error de rendimiento clásico

Añadir elementos a un array dentro de un bucle con $resultado += $x recrea el array completo en cada vuelta: con miles de iteraciones se vuelve lentísimo. La solución idiomática es dejar que PowerShell recoja la salida:

# Lento con colecciones grandes
$resultado = @(); foreach ($i in 1..50000) { $resultado += $i * 2 }
# Rápido y limpio
$resultado = foreach ($i in 1..50000) { $i * 2 }

Conclusión

Regla rápida: foreach para colecciones en memoria, ForEach-Object en tuberías, while para esperar condiciones y do cuando algo debe ejecutarse al menos una vez. Con eso y el truco del array, tus scripts serán más rápidos y más legibles desde hoy.

Deja una respuesta

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