HOWTO · PowerShell

Cómo saltar a ciertos puntos en un script de PowerShell

PowerShell no tiene el comando GOTO. Aprende a saltar a puntos con nombre con function, ramificar con if y switch, repetir con while y for, y salir de bucles anidados con break y continue etiquetados.

En esta página

PowerShell no tiene el comando goto. En un archivo Batch de cmd.exe, GOTO :label envía la ejecución a una línea etiquetada para avanzar o volver atrás. PowerShell omite esa palabra clave a propósito. En su lugar, saltas a un punto con nombre al llamar a una function, eliges un camino con if / elseif / else o switch, repites el trabajo con while o for, y sales de bucles anidados con break o continue etiquetados.

Estas funciones de control de flujo funcionan igual en Windows PowerShell 5.1 y en PowerShell 7. Los ejemplos siguientes se verificaron con PowerShell 7.6.6. Úsalos al convertir scripts Batch, al crear menús o al organizar un .ps1 largo sin saltos tipo espagueti.

Saltar a puntos con nombre con functions

Una function es un bloque con nombre que puedes invocar desde otra parte del script. Es el equivalente más seguro en PowerShell de «saltar a esta sección» y sustituye tanto los patrones Batch de CALL/etiqueta como muchos usos de GOTO. En un archivo de script, define la function antes de llamarla.

function Choice {
    $continue = Read-Host "Do you want to continue?"
    if ($continue -eq 'y') {
        Write-Host "Welcome to PowerShell tutorials."
    }
    else {
        Write-Host "Exited."
    }
}
Choice

Salida cuando la respuesta es y:

Do you want to continue?: y
Welcome to PowerShell tutorials.

Salida cuando la respuesta no es y:

Do you want to continue?: n
Exited.

Usa return dentro de una function cuando necesites una salida anticipada solo de esa function. El siguiente caso límite devuelve "invalid" para un código negativo y "ok:<n>" en caso contrario:

function Get-Status {
    param([int]$Code)
    if ($Code -lt 0) {
        return "invalid"
    }
    return "ok:$Code"
}
Get-Status -Code -1
Get-Status -Code 2
invalid
ok:2

return abandona la function, el script o el bloque de script actual. Prefiérelo a exit salvo que quieras terminar a propósito el proceso de PowerShell y fijar un código de salida para un llamador o programador de tareas. Poner el trabajo reutilizable en functions también facilita las pruebas posteriores, porque puedes invocar un solo punto sin ejecutar todo el script.

Ramificar con if y switch

Las sentencias condicionales eligen qué punto se ejecuta a continuación. Una cadena if / elseif / else sirve para pocas opciones. Una sentencia switch queda más clara para la navegación tipo menú y sustituye patrones Batch como IF ... GOTO sectionA seguidos de otro GOTO que salta las secciones no usadas.

$action = Read-Host "Enter 1 for date marker or 2 for greeting"
switch ($action) {
    '1' { Write-Output "DATE_MARKER" }
    '2' { Write-Output "Hello, welcome to the PowerShell tutorial!" }
    default { Write-Output "Invalid option selected." }
}

Al elegir 2:

Enter 1 for date marker or 2 for greeting: 2
Hello, welcome to the PowerShell tutorial!

Al elegir una opción no válida:

Enter 1 for date marker or 2 for greeting: x
Invalid option selected.

Cada rama es un bloque completo, así que no hace falta un segundo salto para «omitir» las demás secciones.

Repetir con while y for

Los bucles son el reemplazo estructurado de volver a saltar a una etiqueta de inicio como :start. Una sentencia while ejecuta su bloque mientras la condición sea $true. Si la condición ya es $false, PowerShell omite el bloque y continúa después del bucle: un salto controlado, no un salto arbitrario a una etiqueta.

$a = 1
while ($a -lt 10) {
    $a
    $a++
}
1
2
3
4
5
6
7
8
9

Caso límite: el cuerpo del bucle no se ejecuta nunca:

$a = 10
Write-Output "before"
while ($a -lt 10) {
    $a
    $a++
}
Write-Output "after"
before
after

Un bucle for resulta útil cuando necesitas juntos un inicializador, una condición y un iterador:

for ($b = 1; $b -lt 6; $b++) {
    Write-Host $b
}
1
2
3
4
5

PowerShell también ofrece do/while, do/until y foreach cuando necesitas ejecutar al menos una vez o recorrer una colección. Siguen la misma idea de bucle estructurado en lugar de un GOTO :start de Batch. Para un menú que deba reaparecer hasta que el usuario salga, envuelve el mensaje y el switch en un bucle while ($true) y usa break cuando se elija la opción de salida.

Salir de bucles anidados con break y continue etiquetados

Las etiquetas de PowerShell no son destinos de salto de Batch. Una etiqueta como :outer puede aparecer justo antes de una palabra clave de bucle o de switch. Después usas break outer o continue outer —sin dos puntos en la línea de break/continue— para apuntar a esa construcción. Microsoft documenta esta forma en about_Break y about_Continue; las páginas que muestran goto :Label o break :Label como sintaxis de PowerShell son incorrectas.

:outer for ($i = 1; $i -le 3; $i++) {
    for ($j = 1; $j -le 3; $j++) {
        Write-Output "i=$i j=$j"
        if ($j -eq 2) {
            break outer
        }
    }
}
Write-Output "done"
i=1 j=1
i=1 j=2
done

Cuando $j vale 2, break outer abandona por completo el bucle exterior etiquetado y continúa en Write-Output "done". Un break sin etiqueta solo saldría del for interior. Usa continue outer cuando quieras saltar el resto de la iteración exterior actual y empezar la siguiente, en lugar de salir del bucle exterior.

No inventes una sentencia goto :label en PowerShell ni coloques un :label suelto esperando un aterrizaje al estilo Batch. Evita también break o continue fuera de un bucle, switch o trap: PowerShell puede recorrer la pila de llamadas y terminar en silencio el runspace actual, lo que puede detener un llamador que no pretendías detener.

Elegir el método de salto adecuado

Objetivo Preferir
Ejecutar una sección reutilizable con nombre function + llamada, opcionalmente return
Elegir entre opciones if / elseif / else o switch
Repetir o volver atrás while, for, do o foreach
Salir antes de un bucle anidado break / continue etiquetados
Terminar todo el proceso exit (con cuidado)

Mantén los scripts legibles: prioriza functions y condicionales para la mayoría de las necesidades de «salto», usa bucles para la repetición y reserva las etiquetas para el control de bucles anidados. El rendimiento rara vez decide; la claridad y una sola ruta de salida obvia importan más cuando mantengas el script más adelante.

FAQ

¿Tiene PowerShell goto?

No. A diferencia de Batch en cmd.exe, PowerShell no tiene la palabra clave goto. Las palabras clave oficiales del lenguaje y la especificación de PowerShell listan break, continue, throw, return y exit para el control de flujo, no goto.

¿Qué hacen las etiquetas en PowerShell?

Las etiquetas marcan un bucle o un switch para que break / continue puedan apuntarlo. No crean destinos de salto arbitrarios como las líneas :label de Batch.

¿Cuál es la mejor alternativa cotidiana al GOTO de Batch?

Llama a una function para un punto con nombre, o usa if / switch y bucles para ramificar y repetir. Reserva el break etiquetado solo cuando los bucles anidados necesiten una salida exterior controlada.

¿Se pueden combinar estas técnicas?

Sí. Una function de menú suele usar switch dentro de un bucle while, y el procesamiento anidado puede añadir un break etiquetado cuando un bucle exterior deba detenerse.

¿Funcionarán estos ejemplos en Windows PowerShell 5.1?

Sí para las funciones del lenguaje mostradas aquí. Las salidas verificadas se capturaron con PowerShell 7.6.6; el formato del mensaje de Read-Host puede variar ligeramente según el host.