# Until Something Is True: \`while\`, \`do\` and \`for\`

while repeats steps as long as a condition is true, do runs them at least once and checks at the end, which suits trying again up to three times, and for counts from a start to a finish one step at a time.

Apprentice · PowerShell · Updated November 10, 2026

## After this lesson you can

- Repeat steps while a condition is true with while, or at least once with do and until
- Count with a for loop from its start, its test and its step
- Choose foreach, while, do or for for a job

## Key takeaways

- while (condition) { … } checks first and repeats while the condition is true. If it's false at the start, the steps never run.
- do { … } until (condition) runs at least once and stops when the condition becomes true, which suits retrying. do { … } while (condition) goes on while it's true.
- for ($n = 5; $n -ge 1; $n--) { … } counts: a start, a test before each pass, and a step after it.
- Something inside a while or do loop must change its condition, or the loop never ends. Ctrl+C stops it.
- Choose foreach for a list, while to wait, do to try at least once, and for to count.

Some jobs have no list to work through, only a moment to stop. A download has to finish before you unzip it. A website is down for a minute, so you try again, but not forever. *For Each Thing: `foreach`* needs a list to go round; these jobs need a loop that keeps going until something is true. An IT technician's script waits for a computer to restart before it copies the updates, and a backup script tries the network drive three times before it gives up and says so.

The examples are on the launch pad at Mission Control. Make the practice folder and go into it:

```powershell
New-Item -ItemType Directory -Force -Path "$HOME\terminal-practice\launch-pad" | Out-Null
Set-Location "$HOME\terminal-practice\launch-pad"
```

## while: as long as it's true

Filling a tank, you keep the pump running while the tank isn't full. A `while` loop checks its **condition**, a test that answers True or False like an `if`'s, before every pass, and runs the steps in its braces for as long as the answer is True:

```powershell
$fuel = 40
while ($fuel -lt 100) {
    "Fuel at $fuel%"
    $fuel += 20
}
'Tank full'
```

```text
Fuel at 40%
Fuel at 60%
Fuel at 80%
Tank full
```

Read it aloud: "while the fuel is less than 100, do what's in the braces." `+=`, read "add to", adds 20 to `$fuel` on each pass. At 100 the test answers False, and PowerShell carries on after the loop. If the test answers False the first time, a `while` loop never runs at all.

Something inside the loop has to change the answer. Leave out `$fuel += 20` and the loop never ends, an **infinite loop** that fills the screen with `Fuel at 40%`. Press **Ctrl+C** to stop it; nothing is harmed.

## Waiting: while and Start-Sleep

The launch can't go until the flight director says so by leaving a file called `go.txt`. `Test-Path` (*Is It There? `Test-Path`*) answers True when the file is there, and `-not` turns the answer around, so the loop goes round while it isn't. `Start-Sleep -Seconds 2` pauses for two seconds on each pass, so the loop doesn't check thousands of times a second:

```powershell
while (-not (Test-Path go.txt)) {
    'Waiting for go...'
    Start-Sleep -Seconds 2
}
'Go for launch'
```

```text
Waiting for go...
Waiting for go...
Waiting for go...
Go for launch
```

While it waits, make the file from a second PowerShell window, `New-Item "$HOME\terminal-practice\launch-pad\go.txt"`, or in File Explorer. You'll see a `Waiting for go...` every two seconds until the file appears. Run the loop again and it says `Go for launch` at once, because the file is still there; `Remove-Item go.txt` makes it wait again.

## do: try first, check after

When you call a friend who doesn't pick up, you try again, and after three tries you leave a message. That's a `do` loop: it runs its steps first and checks at the end, so it always runs at least once. Here a script asks the ground station's computer whether it's there with `Test-Connection`, which works like the `ping` program: `-Count 1` asks once, and `-Quiet` answers only True or False. A name ending in `.invalid` never exists, so this one never answers:

```powershell
$tries = 0
do {
    $tries++
    $answered = Test-Connection ground-station.invalid -Count 1 -Quiet
    "Try $tries of 3: answered $answered"
} until ($answered -or $tries -eq 3)
```

```text
Try 1 of 3: answered False
Try 2 of 3: answered False
Try 3 of 3: answered False
```

Read the last line aloud: "until it answered, or we've tried three times." `$tries++`, read "tries plus plus", adds one. `until` stops the loop as soon as its condition is True. `do { … } while (…)` works the other way around and goes on while its condition is True. Change the name to `localhost`, your own computer, and the loop stops after `Try 1 of 3: answered True`.

![Two loops side by side: while checks its condition first, so its steps may never run, and do … until runs its steps first and checks at the end, so they always run at least once](https://fsdtrainingmedia.blob.core.windows.net/public/images/2026/11/0c7dca40508b473697740f07147d22d6.webp)

## for: counting

A countdown has a start, a finish and a step: 5, 4, 3, 2, 1. A `for` loop keeps all three in its parentheses, separated by semicolons:

```powershell
for ($n = 5; $n -ge 1; $n--) {
    "T-minus $n"
}
'Liftoff!'
```

```text
T-minus 5
T-minus 4
T-minus 3
T-minus 2
T-minus 1
Liftoff!
```

Read the parentheses aloud: "start `$n` at 5; go round while `$n` is at least 1; after each pass, take one off." `$n--`, read "n minus minus", takes one away; counting up is `for ($i = 1; $i -le 10; $i++)`. For a plain range, `foreach ($n in 5..1)` does the same job. `for` earns its place when the step isn't one, such as `$day += 7` for each week of a month.

## Which loop?

| Your job | Loop | Why |
|---|---|---|
| Something for every file, song or line | `foreach` | there's a list to go round |
| Wait until a file appears | `while` | it checks first, and may not need to run at all |
| Try up to three times | `do … until` | it tries at least once, then checks |
| Count down from 10, or every seventh day | `for` | a start, a test and a step in one place |

These loops, `Test-Connection` and `Start-Sleep` work the same in Windows PowerShell 5.1 and on a Mac or Linux.

## Check yourself

2 questions to try on the lesson page.

## So what

When there's no list, only a moment to stop, `while` waits, `do` tries again and `for` counts: the loops that let a script keep at a job with nobody watching it.

## Key terms

- [while Loop](https://www.ask-codey.com/glossary/while-loop-powershell)
- [do-until Loop](https://www.ask-codey.com/glossary/do-until-loop)
- [for Loop](https://www.ask-codey.com/glossary/for-loop-powershell)
- [Start-Sleep](https://www.ask-codey.com/glossary/start-sleep)
- [Infinite Loop](https://www.ask-codey.com/glossary/infinite-loop-powershell)

## Cheat sheets

- [Until Something Is True: \`while\`, \`do\` and \`for\`](https://www.ask-codey.com/cheat-sheets/powershell-while-and-for-cheat-sheet)

## Related

- [For Each Thing: \`foreach\`](https://www.ask-codey.com/lessons/powershell-foreach-loop)
- [Stopping Early: \`break\` and \`continue\`](https://www.ask-codey.com/lessons/powershell-loop-control)
- [Is It There? Test-Path](https://www.ask-codey.com/lessons/powershell-test-path)
- [If This, Then That: \`if\`, \`elseif\` and \`else\`](https://www.ask-codey.com/lessons/powershell-if-statements)

Source: https://www.ask-codey.com/lessons/powershell-while-and-for
