1

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 I used the ss64 set-executionpolicy command guide for powershell to get powershell working. But I am trying to use the solution from another stackoverflow 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 this command at https://ss64.com/ps/powershell.html at the bottom where there are details on how to run a powershell command as administrator. The problem with that code is that my powershell script 1. has arguments, and 2. has a long name. 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.

Henry Wl
  • 35
  • 1
  • 7
  • [This link](https://support.microsoft.com/en-us/help/830473/command-prompt-cmd--exe-command-line-string-limitation) may be relevant – Bryce McDonald Nov 27 '17 at 16:50
  • I'm not hitting the max-length of my command. The problem is the -file option for powershell. It is not recognizing my filename and therefore does not run it at all. – Henry Wl Nov 27 '17 at 17:07
  • I know Task Scheduler has a 256 char limit but I tested that by passing a 291 char argument to a PowerShell script in the same manner as the OP is trying to run his file, and it worked fine. If there is a limit it's going to be unreasonable to hit. – Deadly-Bagel Nov 27 '17 at 17:34

3 Answers3

0

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

Mark
  • 691
  • 7
  • 20
  • Why are you using a call operator with script block? – Maximilian Burszley Nov 27 '17 at 17:04
  • Running your example command with the escaped filename still causes command prompt to end theparsing of '-command' line after the -file \`". I've tried that method too, and command prompt only sees `powershell.exe -noprofile -command "&{ start-process powershell -ArgumentList '-noprofile -file \`"` – Henry Wl Nov 27 '17 at 17:09
  • Probably due to Command Prompt trimming out the double quotes due to it interpreting them as string start and end points. See my answer. – Deadly-Bagel Nov 27 '17 at 17:29
0

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"
Bill_Stewart
  • 22,916
  • 4
  • 51
  • 62
  • I don't understand the downvotes, but I wasn't looking to do this using a 3rd-party tool, as I want this batch file to be portable. – Henry Wl Nov 27 '17 at 17:12
  • 1
    You can ignore any downvotes as many people are using the freeware tools quite successfully. But in any case I updated my answer with a WSH script solution and a PowerShell self-elevation solution. – Bill_Stewart Nov 27 '17 at 18:17
-1

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
Deadly-Bagel
  • 1,612
  • 1
  • 9
  • 21
  • Worked for me. I managed to pass in 2 arguments using the method described here. – Henry Wl Nov 27 '17 at 18:41
  • Bill, if you don't escape them CMD consumes them. That is true anywhere in the argument you're passing to PowerShell, – Deadly-Bagel Nov 28 '17 at 10:37
  • This technique doesn't work from PowerShell. From my cursory investigation, it seems that this is because powershell.exe currently uses [CommandLineToArgvW](https://msdn.microsoft.com/en-us/library/bb776391.aspx). Due to this complexity I don't recommend this solution unless you are sure that the parser won't misinterpret your intent. – Bill_Stewart Nov 28 '17 at 15:31
  • Whether it works from PowerShell or not is irrelevant, OP explicitly states they are running this from Command Prompt therefore that's what we need to format it for, and if you want the quotes to be interpreted as part of the argument sent to PowerShell they need to be escaped. – Deadly-Bagel Nov 29 '17 at 11:41
  • Yes, and my point is that this only "works" because PowerShell uses that Win32 API. (If they decide to change to a different API or parse differently, this solution might break.) – Bill_Stewart Nov 29 '17 at 14:57