When using Start-Process with -Verb RunAs, a -WorkingDirectory argument is honored if the target executable is a .NET executable; examples:
pwsh.exe (the PowerShell (Core) CLI) does honor it.
cmd.exe and, curiously, powershell.exe (the Windows PowerShell CLI) do not, and invariably use C:\Windows\System32.
- The problem exists at the level of the .NET API that PowerShell uses behind the scenes (see
System.Diagnostics.ProcessStartInfo), as of this writing (.NET 6.0.0-preview.4.21253.7).
Unless you know that you're invoking a .NET executable, a workaround that changes to the desired working folder in the new process is therefore required; to offer a more robust alternative to ふゆな's helpful answer:
$dir = $PWD.ProviderPath # use the current dir.
Start-Process -Verb RunAs powershell.exe @"
-noexit -c Set-Location -LiteralPath "$dir"
"@
The embedded "..." quoting around $dir ensures that paths with spaces are also handled correctly. (To use the current directory without an intermediate variable, replace "dir" with "$($PWD.ProviderPath)".
- Using a here-string (
@"<newline>...<newline>"@) isn't strictly necessary, but simplifies the embedded quoting; with a regular expandable string ("..."), the embedded " must be escaped as `" (or "").
Using $PWD's .ProviderPath property ensures that a file-system-native path is used (based on drive letters also seen in cmd.exe, for instance), given that the calling session's current location may be based on a PowerShell-only drive (see New-PSDrive) that the elevated process may not have defined (at all or not based on the same root location).
- Caveat: If the native path is on a mapped network drive, this won't work, because elevated processes do not see the same drive mappings; in that event, pass the underlying UNC path.
Workaround for launching a GUI application elevated from a given working directory:
Since changing to the working directory must happen in the new, elevated process, a helper shell process is needed to perform this operation, which is best done via cmd.exe (for better performance):
$exeToLaunch = 'Notepad.exe' # may include arguments
$dir = $PWD.ProviderPath # use the current dir.
Start-Process -Verb RunAs -WindowStyle Hidden cmd.exe @"
/c cd "$dir" & $exeToLaunch
"@