31

When I enter the command

Start-Process powershell -WorkingDirectory "D:\folder"

it opens new PowerShell window with D:\folder location set.

But when I enter the command

Start-Process powershell -WorkingDirectory "D:\folder" -Verb RunAs

it opens new PowerShell window with admin rights but with C:\Windows\system32 location set.

How can I open new PowerShell window with admin rights and my own location determined?

Ansgar Wiechers
  • 193,178
  • 25
  • 254
  • 328
Paweł
  • 4,238
  • 4
  • 21
  • 40
  • just do a `cd d:\folder` as the first command? – 4c74356b41 Apr 19 '17 at 12:14
  • 9
    Windows resets the working directory upon elevation for security reasons, otherwise something planted in the current directory might inadvertently be run with elevated privileges. As 4c74356b41 said, you need to change the working directory in your code. [Related](http://stackoverflow.com/q/34261567/1630171). – Ansgar Wiechers Apr 19 '17 at 12:31
  • 4
    thank you, I wanted to run script via powershell with admin rights that moves files from `\currentdir` but it moved files from `\system32`, but I've just discovered that I can get current location with `$PSScriptRoot` in scripts and it works great now – Paweł Apr 19 '17 at 13:47
  • 1
    Beware that `$PSScriptRoot` gives you the location of the script, which isn't necessarily identical with the working directory. – Ansgar Wiechers Apr 19 '17 at 21:00

5 Answers5

10

I also had the same problem and solved it with this command:

Start-Process powershell.exe -verb runAs -ArgumentList '-NoExit', '-Command', 'cd D:\folder'

Once you run the above command, Windows will launch with admin authority and the specified directory.

karel
  • 5,489
  • 46
  • 45
  • 50
ふゆな
  • 109
  • 1
  • 3
  • 7
    Note: Since -file and -command can't be used simultaneously, if you need to start a powershell script in the new admin powershell, just append `; & 'PathToPS1File';` to the `cd ...` string, as seen here: https://stackoverflow.com/a/57033941/2441655 – Venryx Jul 15 '19 at 06:24
4

Here's another example which can be used for opening CMD from PowerShell as an administrator into the current folder:

Start-Process cmd -ArgumentList ("/k cd {0}" -f (Get-Location).path) -Verb RunAs
if used within a script you can use
Start-Process cmd -ArgumentList ("/k cd {0}" -f $PSScriptRoot) -Verb RunAs

If you want to open a new elevated PowerShell session from the current one which is not elevated you can use:
Start-Process powershell.exe -ArgumentList ("-NoExit",("cd {0}" -f (Get-Location).path)) -Verb RunAs
or
Start-Process powershell.exe -ArgumentList ("-NoExit",("cd {0}" -f $PSScriptRoot)) -Verb RunAs
when used inside scripts

Shane
  • 489
  • 4
  • 9
1

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
"@
mklement0
  • 382,024
  • 64
  • 607
  • 775
-2

Once you run Powershell as administrator;

user the push-location command like so:

Push-Location -Path C:\

or put it into your script and run the script from the elevated Powershell prompt.

  • 6
    The point is to launch an elevated prompt, and have that elevated prompt start at the location of the prompt that launched it, without having to type that location in. – StingyJack Apr 01 '18 at 22:03
-2

I just ran your code example and it opened correctly for me at the WorkingDirectory location. Ensure the directory exists before you run the command. I tested against a drive on C and secondary drive as well and both worked.

sheldonhull
  • 1,807
  • 2
  • 26
  • 44
  • With `-Verb RunAs`, `-WorkingDirectory` is only honored by _.NET_ executables, so it doesn't work for `cmd.exe` and `powershell.exe` (which seems to have a native wrapper); however, it does work for `pwsh.exe`, the PowerShell (Core) CLI. – mklement0 Jul 15 '21 at 19:21