PowerShell Start-Process: Launch Apps and Scripts

Deployment scripts don’t just run PowerShell commands — they launch installers, open external tools, run batch files, and wait for each step to complete before moving to the next. PowerShell Start-Process handles all of this: launching any executable, passing arguments, running elevated, waiting for completion, and capturing exit codes. This guide covers every practical pattern used in real automation scripts.
Quick Answer / TL;DR
# Launch an application and wait for it to finish
Start-Process -FilePath 'notepad.exe' -Wait
# Run a script elevated
Start-Process powershell -Verb RunAs -ArgumentList '-File C:\Scripts\setup.ps1'
Basic Start-Process Syntax
Launch any executable with Start-Process:
# Open a file (uses associated application)
Start-Process -FilePath 'C:\Reports\report.xlsx'
# Launch an application
Start-Process -FilePath 'notepad.exe'
# Launch with a full path
Start-Process -FilePath 'C:\Program Files\Tool\tool.exe'
# Open a URL in the default browser
Start-Process 'https://docs.microsoft.com/powershell'
# Open a folder in File Explorer
Start-Process -FilePath 'explorer.exe' -ArgumentList 'C:\Logs'
Without extra parameters, the process launches independently — Start-Process returns immediately and doesn’t wait. The new process runs in the background while your script continues.
Passing Arguments to the Process
Use -ArgumentList to pass command-line arguments:
# Pass arguments as a string
Start-Process -FilePath 'robocopy.exe' -ArgumentList 'C:\Source C:\Dest /E /LOG:C:\Logs\copy.log'
# Pass arguments as an array (safer for paths with spaces)
Start-Process -FilePath 'msiexec.exe' -ArgumentList @(
'/i',
'C:\Installers\MyApp.msi',
'/quiet',
'/log',
'C:\Logs\install.log'
)
# Run a PowerShell script with arguments
Start-Process powershell -ArgumentList '-NoProfile', '-ExecutionPolicy', 'Bypass',
'-File', 'C:\Scripts\deploy.ps1', '-Environment', 'Production'
# Process launches asynchronously
# Check Logs for results after -Wait
Passing arguments as an array is safer when paths contain spaces — each array element is passed as a separate argument token, which avoids quoting issues that occur with a single string.
Wait for Process to Finish with -Wait
Add -Wait to block the script until the launched process exits:
# Run installer and wait for completion before continuing
Write-Output 'Starting installation...'
Start-Process -FilePath 'msiexec.exe' -ArgumentList '/i "C:\Installers\App.msi" /quiet' -Wait
Write-Output 'Installation complete.'
# Run a batch file and wait
Start-Process -FilePath 'cmd.exe' -ArgumentList '/c C:\Scripts\build.bat' -Wait
Write-Output 'Build finished.'
# Run another PowerShell script and wait
Start-Process -FilePath 'powershell.exe' -ArgumentList '-File "C:\Scripts\step2.ps1"' -Wait
Starting installation...
Installation complete.
Build finished.
Run as Administrator with -Verb RunAs
The -Verb RunAs flag elevates the process through UAC:
# Relaunch as Administrator
Start-Process powershell -Verb RunAs
# Run a script elevated
Start-Process powershell -Verb RunAs -ArgumentList '-NoProfile -File "C:\Scripts\install.ps1"'
# Run a specific tool elevated
Start-Process -FilePath 'regedit.exe' -Verb RunAs
The -Verb RunAs triggers the UAC prompt. This only works in an interactive desktop session with a GUI. In non-interactive contexts (scheduled tasks, CI/CD agents), configure the process to run as an account with the required permissions rather than using UAC elevation.
Capture Exit Code
To capture an exit code, use -Wait and -PassThru:
# Capture exit code from a process
$proc = Start-Process -FilePath 'robocopy.exe' `
-ArgumentList 'C:\Source C:\Dest /E' `
-Wait -PassThru -NoNewWindow
$exitCode = $proc.ExitCode
Write-Output "Robocopy exit code: $exitCode"
# Robocopy exit codes: 0=no change, 1=copied ok, 2=extra files, 8+=errors
if ($exitCode -ge 8) {
Write-Error "Robocopy failed with exit code $exitCode"
}
# Generic success/failure check
$proc = Start-Process 'myapp.exe' -Wait -PassThru
if ($proc.ExitCode -ne 0) {
throw "Process failed with exit code: $($proc.ExitCode)"
}
Robocopy exit code: 1
Exit code is only available after using -Wait. Without -Wait, the ExitCode property is $null because the process hasn’t finished yet.
Run Minimized or Hidden
Control the window style for background processes:
# Run hidden (no window)
Start-Process -FilePath 'cmd.exe' -ArgumentList '/c dir C:\ > C:\Temp\dirlist.txt' -WindowStyle Hidden
# Run minimized
Start-Process -FilePath 'notepad.exe' -WindowStyle Minimized
# Run without creating a new window (for console apps)
Start-Process -FilePath 'ping.exe' -ArgumentList 'google.com -n 4' -NoNewWindow -Wait
Common Errors and Fixes
-
Arguments with spaces need quoting inside -ArgumentList: When passing a path with spaces as a single string argument, wrap it in escaped quotes:
-ArgumentList '/i \"C:\Program Files\App\setup.msi\"'. Using an array argument list is cleaner:@('/i', 'C:\Program Files\App\setup.msi'). -
Exit code only available after -Wait: Checking
$proc.ExitCodewithout-Waitreturns$nullbecause the process is still running. Always pair-PassThruwith-Waitwhen you need exit codes.
Related Cmdlets / See Also
Wrapping Up
Start-Process is the controlled way to launch external tools from PowerShell. Use -Wait to sequence steps, -PassThru to capture exit codes, -Verb RunAs for elevation, and -WindowStyle Hidden for background processes. Pass complex arguments as arrays to handle spaces correctly. Your next step: wrap your most common installer or external tool invocation in a Start-Process call with exit code checking.


