Run with elevated rights a PowerShell script, with spaces in path, from Windows Command Prompt (CMD)

4.2k views Asked by At

I tried to launch a long PowerShell script with the name "long name here.ps1" from command prompt. But I am also trying to ensure that it runs as an administrator command in PowerShell. I have all execution policies in PowerShell set accordingly and I used the SS64 Set-ExecutionPolicy command guide for PowerShell to get PowerShell working. But I am trying to use the solution from another Stack Overflow question that talks about running commands as administrator. I am running a batch script that needs to execute a PowerShell script (.ps1) as admin, and I don't mind if the user is prompted by UAC or for the password.

I am currently using the following command:

powershell.exe -command "&{ Start-Process powershell -ArgumentList '-noprofile -file "C:\long name here.ps1"' -verb RunAs}"

I found a similar command in the "Run a Script As Admin" at https://ss64.com/ps/powershell.html. The problem with that code is that my PowerShell script has arguments and a long name with spaces. I have tried many different iterations of this command with no success, and the ones that DON'T work are listed below:

powershell.exe -command "&{ Start-Process powershell -ArgumentList '-noprofile -file C:\long\` name` here.ps1' -verb RunAs}"
powershell.exe -command "&{ Start-Process powershell -ArgumentList '-noprofile -file:"C:\long name here.ps1' -verb RunAs}"

Also, I am completely lost as to how to send arguments to the actual script.

3

There are 3 answers

5
Deadly-Bagel On BEST ANSWER

When you use PowerShell.exe -Command you don't need to use quotes. For example, you can run the following:

PowerShell.exe -Command Get-Service 'wuauserv'

Everything after -Command is interpreted as the command. Note also that double quotes in CMD need escaping with a backslash. Therefore:

powershell.exe -Command Start-Process PowerShell -ArgumentList '-NoProfile -File \"C:\long name here.ps1\"' -Verb RunAs

If your file has arguments:

powershell.exe -Command Start-Process PowerShell -ArgumentList '-NoProfile -File \"C:\long name here.ps1\" \"Arg1\" \"Arg2\"' -Verb RunAs
3
Mark On

If I'm reading your question correctly - powershell wont find the file as it stops reading the path name when it encounters a blank space?

The example given here specifies that; powershell commands to be run from command prompt as an administrator should have the following syntax:

powershell.exe -noprofile -command "&{ start-process powershell -ArgumentList '-noprofile -file MyScript.ps1' -verb RunAs}"

Couple of ways to achieve what you're looking for. But the easiest method would be to escape the quotes using a ` character. So something similar to;

powershell.exe -noprofile -command "&{ start-process powershell -ArgumentList '-noprofile -file `"C:\long file name.ps1`"' -verb RunAs}"

Also might be worth checking out other answers here

2
Bill_Stewart On

Use an Open Source Utility

If an open source utility is permissible, you can use a short tool I wrote called elevate.exe to launch powershell.exe as administrator with the -File parameter and the script arguments you want to use:

elevate -- powershell.exe -File "<path>\<long script name>.ps1" -Arg "<long script argument>"

You can get the open source tool here:

https://github.com/Bill-Stewart/elevate

Use a WSH Script

If you can't use an external executable, you can also do this (although it does not handle quoting in as robust a manner as the elevate tool's -- parameter) using a Windows Script Host (WSH) script, elevate.js:

// elevate.js
var args = WScript.Arguments;

if ( (args.Length == 0) || (args.Named.Exists("?")) ) {
  WScript.Echo("Usage: elevate.js command [arg [...]]");
  WScript.Quit();
}

var exec = args.Item(0);
var cmdLine = "";
for ( var i = 1; i < args.Length; i++ ) {
  cmdLine += cmdLine == "" ? '"' + args.Item(i) + '"' : ' "' + args.Item(i) + '"';
}
var shellApp = new ActiveXObject("Shell.Application");
shellApp.ShellExecute(exec,cmdLine,"","runas");

You can call as follows:

wscript.exe "d:\path\elevate.js" powershell.exe -File "C:\long path\script name.ps1" "long script argument"

Self-Elevate your PowerShell Script

Another option is to write a self-elevating PowerShell script. You can check for elevation in the script; if not elevated, it can launch itself elevated and run any command you need. Example:

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

if ( -not $isElevated ) {
  Start-Process powershell.exe "-File",('"{0}"' -f $MyInvocation.MyCommand.Path) -Verb RunAs
  exit
}

& "d:\long path name\script name.ps1" "Long Argument 1" "Long Argument 2"