HOWTO · PowerShell

How to Jump Around to Certain Spots in PowerShell Script

PowerShell has no GOTO command. Learn how to jump to named spots with functions, branch with if and switch, repeat with while and for, and exit nested loops with labeled break and continue.

On this page

PowerShell has no goto command. In a cmd.exe Batch file, GOTO :label sends execution to a labeled line so you can skip ahead or loop back. PowerShell deliberately omits that keyword. Instead, you jump to a named spot by calling a function, choose a path with if / elseif / else or switch, repeat work with while or for, and leave nested loops with labeled break or continue.

These control-flow features work the same way in Windows PowerShell 5.1 and in PowerShell 7. The examples below were verified with PowerShell 7.6.6. Use them when you are converting Batch scripts, building menus, or organizing a long .ps1 file without spaghetti jumps.

Jump to Named Spots With Functions

A function is a named block you can call from elsewhere in the script. That is the safest PowerShell equivalent of “jump to this section,” and it replaces Batch CALL/label subroutine patterns as well as many GOTO uses. In a script file, define the function before you call it.

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

Output when the answer is y:

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

Output when the answer is not y:

Do you want to continue?: n
Exited.

Use return inside a function when you need an early exit from that function only. The following boundary case returns "invalid" for a negative code and "ok:<n>" otherwise:

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 leaves the current function, script, or script block. Prefer it over exit unless you intentionally want to end the PowerShell process and set a process exit code for a caller or scheduler. Putting reusable work in functions also makes later testing easier because you can invoke one spot without running the whole script.

Branch With if and switch

Conditional statements choose which spot runs next. An if / elseif / else chain works for a few options. A switch statement is clearer for menu-style navigation and replaces Batch patterns such as IF ... GOTO sectionA followed by another GOTO past the unused sections.

$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." }
}

Selecting 2:

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

Selecting an invalid option:

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

Each branch is a complete block, so you do not need a second jump to “skip” the other sections.

Repeat With while and for

Loops are the structured replacement for jumping back to a start label such as :start. A while statement runs its block as long as the condition is $true. If the condition is already $false, PowerShell skips the block and continues after the loop — a controlled skip, not an arbitrary label jump.

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

Boundary case — the loop body never runs:

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

A for loop is useful when you need an initializer, condition, and iterator together:

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

PowerShell also provides do/while, do/until, and foreach when you need run-at-least-once behavior or collection iteration. Those follow the same structured-loop idea instead of a Batch GOTO :start. For a menu that should reappear until the user exits, wrap the prompt and switch in a while ($true) loop and break when the exit option is chosen.

Exit Nested Loops With Labeled break and continue

PowerShell labels are not Batch jump targets. A label such as :outer may appear immediately before a loop or switch keyword. You then use break outer or continue outer — without a colon on the break/continue line — to target that construct. Microsoft documents this form in about_Break and about_Continue; pages that show goto :Label or break :Label as PowerShell syntax are incorrect.

: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

When $j equals 2, break outer leaves the labeled outer loop entirely and continues at Write-Output "done". An unlabeled break would leave only the inner for. Use continue outer when you want to skip the rest of the current outer iteration and start the next one instead of exiting the outer loop.

Do not invent a PowerShell goto :label statement, and do not place a bare :label expecting Batch-style landing. Also avoid break or continue outside a loop, switch, or trap: PowerShell may walk the call stack and quietly terminate the current runspace, which can stop a caller you did not intend to stop.

Choose the Right Jump Method

Goal Prefer
Run a named reusable section function + call, optionally return
Choose among options if / elseif / else or switch
Repeat or loop back while, for, do, or foreach
Leave a nested loop early labeled break / continue
End the whole process exit (use carefully)

Keep scripts readable: prefer functions and conditionals for most “jump” needs, use loops for repetition, and reserve labels for nested-loop control. Performance is rarely the deciding factor; clarity and a single obvious exit path matter more when you maintain the script later.

FAQ

Does PowerShell have goto?

No. Unlike cmd.exe Batch, PowerShell has no goto keyword. Official language keywords and the PowerShell language specification list break, continue, throw, return, and exit for flow control — not goto.

What do PowerShell labels do?

Labels mark a loop or switch so break / continue can target it. They do not create arbitrary jump destinations the way Batch :label lines do.

What is the best everyday alternative to Batch GOTO?

Call a function for a named spot, or use if / switch and loops for branching and repetition. Reach for labeled break only when nested loops need a controlled outer exit.

Can I combine these techniques?

Yes. A menu function often uses switch inside a while loop, and nested processing may add a labeled break when an outer loop must stop.

Will these examples work on Windows PowerShell 5.1?

Yes for the language features shown here. The verified outputs were captured with PowerShell 7.6.6; host prompt formatting for Read-Host can vary slightly by host.