cmd.exe --> powershell.exe "-File" and "-Command" in the same line

Viewed 516

test.ps1 contains:

echo ok

I have a line in the command prompt (cmd.exe) that needs to call powershell.exe passing both the "-File" option and the "-Command" option.
With this wrong syntax:

powershell.exe -File "test.ps1" -Command "echo test"

"-Command" and "echo test" are passed as arguments to the "test.ps1" script file. In fact the output is:

ok

I expect as output:

ok
test

If, on the other hand, I invert the "-Command" and "-File" options:

powershell.exe -Command "echo test" -File "test.ps1"

"-File" and "test.ps1" are the simple continuation of the argument of the "-Command" option. In fact the output is:

test
-File
test.ps1

I expect as output:

test
ok

Help for the "-Command" option:
"If the value of Command is a string, it must be the last parameter in the command, any characters typed after command are interpreted as the command arguments.".
This is a substantially false claim, so a bug should be reported to Microsoft.

Question:

That said, what is the right way to write the command?

Answer Requirements:

As a solution, I want a method that doesn't call the file using the "-Command" option argument; so, even if it works, I don't want something like this:

powershell.exe -Command "echo test; & \".\test.ps1\""

This command will ultimately need to be used as a value in a registry key (the classic subkey "Shell\Open\Command").

For example for directory [HKEY_CLASSES_ROOT\Microsoft.PowerShellScript.1\Shell\Open\Command]:

This works:

"C:\Windows\System32\WindowsPowerShell\v1.0\powershell.exe" -Command "if((Get-ExecutionPolicy ) -ne 'AllSigned') { Set-ExecutionPolicy -ExecutionPolicy Bypass -Scope Process -Force }; & \"%1\""

This not:

"C:\Windows\System32\WindowsPowerShell\v1.0\powershell.exe" -Command "if((Get-ExecutionPolicy ) -ne 'AllSigned') { Set-ExecutionPolicy -ExecutionPolicy Bypass -Scope Process -Force }" -File "%1"

because any characters typed after command are interpreted as the command arguments.

Windows 10 Pro 64-bit
Powershell Version: 5.1.19041.1237 (Integrated in Windows 10).

1 Answers

I'm not sure what the practical reason for this is. with -command, there's a lot you can do. For example if the script takes an argument:

# test.ps1
param ($a)
echo ($a)
powershell .\test.ps1 $(write-host test;echo ok)

test
ok
# test.ps1
param ($a)
get-itemproperty ($a)
powershell -file test.ps1 HKLM:\SOFTWARE\Classes\Microsoft.PowerShellScript.1\Shell\Open\Command

(default)    : "C:\Windows\System32\notepad.exe" "%1"
PSPath       : Microsoft.PowerShell.Core\Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Classes\Microsoft.PowerShellScript.1\Shell\Open\Command
PSParentPath : Microsoft.PowerShell.Core\Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Classes\Microsoft.PowerShellScript.1\Shell\Open
PSChildName  : Command
PSDrive      : HKLM
PSProvider   : Microsoft.PowerShell.Core\Registry
Related