Starting Programs: `Start-Process`

Start-Process opens a file or folder in the app a double-click would use, starts a program with arguments in its own window or none, hands back its process with -PassThru, waits for it with -Wait or Wait-Process so you can read its ExitCode, and asks Windows for administrator rights with -Verb RunAs.

Journeyman · PowerShell · Operating System · Updated

After this lesson you can

  • Open a file or folder in its app, or start a program with arguments, and keep its Id with Start-Process -PassThru
  • Wait for a program with -Wait or Wait-Process and read its ExitCode, and run one as administrator with -Verb RunAs only when a job needs it

Key takeaways

  • Start-Process -FilePath .\report.html opens a file in its own app, the way a double-click does. Start-Process -FilePath . opens File Explorer here.
  • -ArgumentList gives the program its arguments, -WindowStyle Hidden starts it with no window, and -PassThru hands back its process, Id and all.
  • -Wait, or Wait-Process -Id later, holds the prompt until the program ends. Its ExitCode then says whether it worked: 0 means it did.
  • -Verb RunAs starts a program as administrator, after Windows asks you. Use it for the one job that needs it, never by habit.

A script makes a weekly report and should open it for you when it's done. A tutorial says "open the folder you're in, in File Explorer". A backup has to finish before the script moves on and deletes anything. An IT ticket says "run this as administrator". Each time you need to start a program from PowerShell in a particular way, not only run a command, and Start-Process is how. IT staff use it in install scripts, and developers use it to open what their scripts build.

To run a script and wait for it in this window, you don't need Start-Process at all: .\backup.ps1 does that. Start-Process earns its place when you want the file's own app, another window or none, or administrator rights.

This lesson uses the processes practice folder from What's Running: Get-Process and Stop-Process.

Open a file the way a double-click does

Give Start-Process a file, and Windows opens it in the app a double-click would use. Make a small web page and open it:

Set-Location "$HOME\terminal-practice\processes"
Set-Content -Path report.html -Value '<h1>Weekly report</h1>', '<p>All 3 backups finished.</p>'
Start-Process -FilePath .\report.html

Nothing prints; your web browser opens the page. A folder works the same way: Start-Process -FilePath . opens File Explorer on the folder you're in (. is read "here"). To choose the app yourself, name the program and give it the file in -ArgumentList, the list of things to hand the program as it starts:

Start-Process -FilePath notepad -ArgumentList .\report.html

Notepad opens with the page's text in it. Invoke-Item (short name ii) also opens a file in its own app.

Starting a program, and keeping its Id

Make a pretend backup that takes six seconds:

Set-Content -Path backup.ps1 -Value '# backup.ps1: pretends to back up three folders, two seconds each.', "foreach (`$folder in 'Documents', 'Pictures', 'Music') {", '    Write-Output "Backing up $folder..."', '    Start-Sleep -Seconds 2', '}', "Write-Output 'Backup done.'"

(The backtick in front of $folder keeps that one $ as it is inside double quotes.) Start it as its own PowerShell, with no window, and ask for the process back:

Start-Process -FilePath pwsh -ArgumentList '-NoProfile', '-File', '.\backup.ps1' -WindowStyle Hidden -PassThru
 NPM(K)    PM(M)      WS(M)     CPU(s)      Id  SI ProcessName
 ------    -----      -----     ------      --  -- -----------
      9     1.64       7.70       0.02   67468   1 pwsh

Three parameters do the work:

  • -ArgumentList is everything after the program's name, as a list: pwsh -NoProfile -File .\backup.ps1.
  • -WindowStyle Hidden starts it with no window. Minimized and Maximized work too.
  • -PassThru hands back the process. Without it, Start-Process prints nothing, and a hidden program can get lost; you'd be hunting for it as in What's Running: Get-Process and Stop-Process.

Waiting for it to finish

The prompt came back at once, while the backup carried on. To wait for it now, give its Id to Wait-Process. It returns when the program ends, and then the process is gone:

Wait-Process -Id 67468
Get-Process -Id 67468
Get-Process: Cannot find a process with the process identifier 67468.

When you know from the start that the next step must wait, use -Wait. Add -NoNewWindow and the program prints into this window. Keep the process in a variable with -PassThru, and its ExitCode tells you how it went:

$backup = Start-Process -FilePath pwsh -ArgumentList '-NoProfile', '-File', '.\backup.ps1' -NoNewWindow -Wait -PassThru
$backup.ExitCode
Backing up Documents...
Backing up Pictures...
Backing up Music...
Backup done.
0

An exit code of 0 means it worked; any other number means something went wrong, as Did It Work? $?, $LASTEXITCODE, && and || showed. An install script checks it before going on.

As administrator: -Verb RunAs

An administrator may change anything on the computer: install apps for everyone, restart Windows' services, change other people's settings. Your PowerShell window doesn't use those rights unless you ask, and that's on purpose: one wrong command can't damage the whole PC. User Account Control (UAC) is the box that asks first. -Verb RunAs asks for a new PowerShell as administrator:

Start-Process -FilePath pwsh -Verb RunAs

Run that only when a job needs it. Windows dims the screen and asks Do you want to allow this app to make changes to your device? If you choose Yes, a new window opens whose title starts with Administrator:. Everything typed there can change the whole computer, so do the one job and close it. You can check which kind of window you're in; this line asks Windows about the account you're using in it:

$me = [Security.Principal.WindowsPrincipal][Security.Principal.WindowsIdentity]::GetCurrent()
$me.IsInRole([Security.Principal.WindowsBuiltInRole]::Administrator)
False

False: an ordinary window, the right one for nearly everything.

On a Mac or Linux, Start-Process opens files in their apps too, but -Verb, -WindowStyle and -NoNewWindow don't apply there; sudo is how a command gets administrator rights. Windows PowerShell 5.1 has the same Start-Process.

Check yourself

2 questions to try on the lesson page.

So what

Start-Process starts a program the way the job needs it: in its own app, out of sight, waited for, or as administrator, and -PassThru keeps hold of it so it never gets lost.

Key terms

Cheat sheets

Related