Use Start-Sleep -Seconds 10 for a known fixed delay, but do not use sleeps as a substitute for checking whether a process or service is ready. Prefer Wait-Process for a process that must exit, a loop with a timeout for a service condition, Read-Host for user input, and Write-Progress when the delay exists only to show UI feedback.
How to Pause in PowerShell: Adding Delays and User Prompts
Learn every way to pause a PowerShell script: Start-Sleep, Wait-Process with timeout, Read-Host, countdown timers, and when not to use sleep loops.
// The short answer
In this guide · 7 sections
- 01Start-Sleep: The Classic Way to Hit the Brakes
- 02Wait-Process and Wait-Event: Watching the Actual System State
- 03Read-Host: Waiting on a Human Being
- 04Write-Progress: Giving Users a Visual Cue While Waiting
- 05The Sleep-Check Anti-Pattern to Steer Clear Of
- 06What About the Old-School CMD Pause?
- 07Quick Cheat Sheet
Throwing a Start-Sleep into a tight loop to see if a service is finally awake is an easy trap to fall into, but it will eat your CPU alive and quietly sabotage your deployment pipeline. Counting on arbitrary time delays for stuff that is inherently event-driven is one of those classic automation gotchas. If you want scripts that actually survive in the real world, you need to lean on object-based waiting and always set sensible timeouts.
- Fixed delay when you know the timing:
Start-Sleep -Seconds 10 - Hold until an app wraps up:
Wait-Process -Name process_name - Wait for someone to hit a key:
Read-Host - Keep people from thinking it froze:
Write-Progress - Clean timespans with -Duration: PowerShell 7 or newer
Start-Sleep: The Classic Way to Hit the Brakes
The most straightforward way to pause whatever your script is doing is Start-Sleep. Save this purely for situations where you know the exact window of time you need to wait out. Just keep in mind that the session halts dead in its tracks - meaning no other work in that same scope will get processed while the clock is ticking down.
Pausing for a Specific Number of Seconds
PowerShell
Start-Sleep -Seconds 5If you are typing interactively at the console, you can just type sleep 5 to save a few keystrokes. Just don't rely on this if your delay hinges on things outside your control, like an unpredictable network hop or a sluggish download.
Dialing in Milliseconds for Sub-Second Pauses
A lot of automation tasks need tiny pauses well under a full second, which comes up constantly when you are juggling fast REST endpoints:
PowerShell
Start-Sleep -Milliseconds 500Tossing a quick half-second breather between your outgoing web requests is usually all it takes to keep external APIs from throttling or blocking your IP.
Cleaner Timespans with -Duration (PowerShell 7+)
PowerShell 7 brought a welcome quality-of-life update here. Instead of forcing you to do mental gymnastics converting hours into seconds, the -Duration parameter lets you drop in a clean timespan string directly:
PowerShell
Start-Sleep -Duration "01:30:00"This neatly pauses execution for an hour and a half without cluttering your code with giant, messy second counts that nobody wants to calculate.
Wait-Process and Wait-Event: Watching the Actual System State
Guessing wait times with fixed sleeps falls apart fast when an installer hits a slow disk or an app hangs during shutdown. Object-aware cmdlets fix this by watching the actual state of the operating system. Your script stays put until the exact event you care about takes place.
Waiting for an App or Installer to Wrap Up
Say your script kicks off an uninstaller - you want to know for sure the executable has cleared out before you start deleting residual directories:
PowerShell
Wait-Process -Name "setup"PowerShell keeps an eye on the process ID and kicks execution over to your next line the split-second that executable actually exits memory.
Always Add -Timeout to Avoid Frozen Pipelines
Letting a script wait on another process without an escape hatch is asking for trouble in production. If the target executable crashes silently in the background or hangs on a prompt, your pipeline will sit there indefinitely. Give it a hard ceiling every time:
PowerShell
Wait-Process -Name "setup" -Timeout 120If that setup executable is still lingering after two minutes, PowerShell will spit out an error. Wrap that in a try/catch block so you can gracefully roll back changes or fire off a message to your team instead of leaving a ghost runner.
Read-Host: Waiting on a Human Being
Every so often, you are building an operational tool where a person needs to eyeball the screen and give explicit approval before something destructive kicks off. That is where you force the script to wait on an actual keystroke.
Dropping in a Simple "Press Enter" Gate
PowerShell
Read-Host "Press Enter to start the server reboot"This is super handy when you are writing diagnostic or recovery routines. It leaves the log output up on screen so you can inspect everything before pulling the trigger on the next step. Just remember that Read-Host is built strictly for interactive terminals. If you toss it into a GitHub Actions runner or a headless scheduled task, it will choke or blow straight past the prompt; running PowerShell scripts without an active console means sticking to unattended methods like Start-Sleep or Wait-Process.
Masking Sensitive Input with -AsSecureString
If you ever need an operator to pass in a token or an admin credential mid-run, you definitely do not want those characters sitting in plain text across the terminal buffer:
PowerShell
$apiKey = Read-Host "Enter your API Key" -AsSecureStringThe console turns each keypress into an asterisk on screen, and PowerShell packs the result straight into an encrypted secure string object in memory.
Write-Progress: Giving Users a Visual Cue While Waiting
Nothing makes someone kill a terminal faster with Ctrl+C than a frozen prompt and a blank screen. If your script has to pause for more than a few seconds, pair your delay with a clean status bar:
PowerShell
for ($i = 10; $i -gt 0; $i--) {
Write-Progress -Activity "Waiting for service" -Status "$i seconds left" -PercentComplete ($i * 10)
Start-Sleep -Seconds 1
}This paints an active visual tracker right across the top of your terminal window. Anyone watching knows right away that the job is healthy, what it is stuck on, and roughly when it will finish.
The Sleep-Check Anti-Pattern to Steer Clear Of
You will see this pattern in legacy scripts all the time: sleep five seconds, run a test to see if a file dropped, sleep another five seconds, repeat. It is a messy polling anti-pattern that burns background CPU cycles and makes automation brittle.
Whenever you can, hook into something like Register-ObjectEvent for file system activity instead of rolling your own sleep loop. It lets Windows tell you when the file is ready, keeping your code snappy, lean, and much kinder to server resources.
What About the Old-School CMD Pause?
If you are porting over older batch scripts, you can technically still trigger the legacy CMD pause behavior, but it is not doing what most folks think:
PowerShell
cmd.exe /c pauseAll this does is spin up an entire secondary cmd.exe process just to print the old "Press any key to continue . . ." banner. It is clunky, slow, and easy to replace with native cmdlets in any modern script. If you find yourself bridging between PowerShell and native executables regularly, this run EXE from CMD guide breaks down the argument passing and elevation quirks that usually trip people up.
Quick Cheat Sheet
Start-Sleep: Ideal for API throttling, short pauses, or intentional pacingWait-Process: The right call for installers, patches, and external binariesRead-Host: Built for interactive checkpoints, yes/no confirmation gates, and capturing secretsWrite-Progress: Anytime a script holds for over five seconds and someone is watching the screen
Quick answers
Frequently asked questions
How do I pause a PowerShell script until a key is pressed?
Use Read-Host to pause until the user presses Enter: Read-Host 'Press Enter to continue'. For any key (not just Enter), use [console]::ReadKey($true). Note that Read-Host is only reliable in interactive sessions and will silently skip in scheduled tasks or CI pipelines.
What is the difference between Start-Sleep and Read-Host in PowerShell?
Start-Sleep pauses for a fixed duration with no user interaction. Read-Host pauses indefinitely until the user provides input. Use Start-Sleep for timed delays, API rate limiting, or unattended scripts. Use Read-Host only in interactive scripts where a human is present.
How do I add a delay in milliseconds in PowerShell?
Use Start-Sleep -Milliseconds 500 for a 500ms delay. This is useful for API rate limiting when a full second pause would slow down your script unnecessarily.
How to wait for a process to finish in PowerShell?
Use Wait-Process -Name 'processname' to block until the process exits. Always add a timeout with -Timeout 120 to prevent infinite hangs if the process crashes: Wait-Process -Name 'setup' -Timeout 120. Without -Timeout, a ghost process will cause the script to wait forever.
Does PowerShell have a pause command like CMD?
Yes, but it works differently. Running cmd.exe /c pause in PowerShell launches a separate CMD instance just to display the 'Press any key to continue' message. This is inefficient. The native PowerShell equivalent is Read-Host 'Press Enter to continue'.
Something wrong or out of date?
Tools change fast. Tell the editor what no longer works.