A while loop in PowerShell repeats a block of code as long as its condition is true. It checks the condition before each pass, so the block may never run at all:
$attempt = 1
while ($attempt -le 3) {
"Checking the backup server, attempt $attempt"
$attempt++
}
"Done after $($attempt - 1) attempts"
Output:
Checking the backup server, attempt 1
Checking the backup server, attempt 2
Checking the backup server, attempt 3
Done after 3 attempts

Don’t forget the line that changes the counter. Without $attempt++, the condition stays true and the loop never ends.
I ran every example in PowerShell 7.6 and Windows PowerShell 5.1, and the results were the same.
while vs do-while vs do-until
| Loop | Checks the condition | Keeps running while | Runs at least once |
|---|---|---|---|
while (...) { } | Before each pass | The condition is true | No |
do { } while (...) | After each pass | The condition is true | Yes |
do { } until (...) | After each pass | The condition is false | Yes |
Here all three start with a condition that’s already met. Only the two do loops run their block:
$count = 10
while ($count -lt 5) {
"while ran with count $count"
}
do {
"do-while ran with count $count"
} while ($count -lt 5)
do {
"do-until ran with count $count"
} until ($count -ge 5)
Output:
do-while ran with count 10
do-until ran with count 10

Use a do loop when the block has to run first, like asking for input before you can check it.
When you know exactly how many times to repeat, a for loop is often clearer.
PowerShell do-while loop
A do-while loop runs the block, then repeats it while the condition is true:
$page = 0
do {
$page++
"Downloading page $page of 3"
} while ($page -lt 3)
Output:
Downloading page 1 of 3
Downloading page 2 of 3
Downloading page 3 of 3
Microsoft covers both do forms in about_Do.
PowerShell do-until loop
A do-until loop is the reverse. It repeats until the condition becomes true, which often reads more naturally:
$balance = 1000
$month = 0
do {
$month++
$balance -= 250
"Month ${month}: `$$balance left"
} until ($balance -le 0)
Output:
Month 1: $750 left
Month 2: $500 left
Month 3: $250 left
Month 4: $0 left
${month} keeps the colon after the variable name from being read as part of it.
Use multiple conditions in a loop
Combine conditions with -and and -or. This loop stops when it connects or after five attempts, whichever comes first:
$attempt = 0
$connected = $false
while (-not $connected -and $attempt -lt 5) {
$attempt++
$connected = ($attempt -eq 3)
"Attempt ${attempt}: connected = $connected"
}
Output:
Attempt 1: connected = False
Attempt 2: connected = False
Attempt 3: connected = True
A retry limit like this keeps a loop from running forever when something never succeeds. about_While has the full syntax.
Why does my Read-Host loop accept the wrong numbers?
Read-Host always returns text. When text is on the left of -le or -gt, PowerShell compares it as text, not as a number:
$answer = '5'
"'5' -le 10 : $($answer -le 10)"
"[int]'5' -le 10 : $([int]$answer -le 10)"
Output:
'5' -le 10 : False
[int]'5' -le 10 : True
As text, ‘5’ comes after ’10’, so a range check lets 5 through. Convert the input first. -as [int] returns $null for anything that isn’t a number, instead of stopping with an error: