devcrea

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

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.

Full walkthrough, edge cases and why it works
In this guide · 7 sections
  1. 01Start-Sleep: The Classic Way to Hit the Brakes
  2. 02Wait-Process and Wait-Event: Watching the Actual System State
  3. 03Read-Host: Waiting on a Human Being
  4. 04Write-Progress: Giving Users a Visual Cue While Waiting
  5. 05The Sleep-Check Anti-Pattern to Steer Clear Of
  6. 06What About the Old-School CMD Pause?
  7. 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

code1 line
Start-Sleep -Seconds 5

If 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

code1 line
Start-Sleep -Milliseconds 500

Tossing 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

code1 line
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

code1 line
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

code1 line
Wait-Process -Name "setup" -Timeout 120

If 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

code1 line
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

code1 line
$apiKey = Read-Host "Enter your API Key" -AsSecureString

The 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

code4 lines
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

code1 line
cmd.exe /c pause

All 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 pacing
  • Wait-Process: The right call for installers, patches, and external binaries
  • Read-Host: Built for interactive checkpoints, yes/no confirmation gates, and capturing secrets
  • Write-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.