Passing quoted arguments to PowerShell scripts

蹲街弑〆低调 提交于 2019-12-24 01:07:37

问题


Scripting is made for CLI and, in the Microsoft world, script arguments referring to files may often have spaces requiring them to be quoted.

This turns out to be problematic for me. Consider this script:

#testarg.ps1 
for($i=0; $i -lt $args.length; $i++)
{
    write-host "Arg$i = $($args[$i])"
} 

If I run it inside the PowerShell interactive environment, like this:

PS C:\script> .\testarg.ps1 "first arg"  "second arg"

I get, as expected,

Arg0 = first arg
Arg1 = second arg

But the ordinary use of a script would be, outside the interactive mode, in a batch one. As far as I understand, the Microsoft suggested way to run scripts from cmd.exe seems to be powershell.exe path\to\script.ps1 (without space in path). But:

powershell.exe .\testarg.ps1 "first arg"  "second arg"

gives the inconsistent result:

Arg0 = first
Arg1 = arg
Arg2 = second
Arg3 = arg 

I noted that to obtain the intended result I can use single quotes:

powershell.exe .\testarg.ps1 'first arg' 'second arg'

But this is often not viable when the script is to be run by GUI tools that automatically generate and pass the arguments, and/or in presence of more CLI tools for reason of consistency in the use of the quotes.

For some reason when using the -file option:

powershell.exe –file .\testarg.ps1 "first arg"  "second arg"
::(reference to relative path '.\' is optional)

I get again the intended result:

Arg0 = first arg
Arg1 = second arg

So with the -file option the double quotes work properly. This suggests that one can remap the Windows file type association for ps1 files (with FTYPE.exe) to something like:

FTYPE Microsoft.PowerShellScript.1=C:\Windows\System32\WindowsPowerShell\v1.0\powershell.exe -file "%1" %*

Given the FTYPE association, I can obtain the intended result by simply writing:

testarg.ps1 "first arg"  "second arg"

The latter is quite satisfying for me, but since I am newbie with PowerShell, I wonder:

  1. For a general script, are the batch form powershell.exe –file path\to\script.ps1 and the interactive form (from within PowerShell) PS > path\to\script.ps1 equivalent? Are there some instances when the two forms may produce different output/effects?
  2. Is there a possible solution inside the script to read the command line as is (without stripping double quotes)? Something like *% for cmd.exe.

回答1:


There is one thing I don't understand when you wrote:

testarg.ps1 "first arg"  "second arg"

Inside which batch are you calling that?

From PowerShell.exe, it should be written:

cd "c:\Temp"
& .\testarg.ps1 "first arg"  "second arg"

From cmd.exe it should be written:

powershell –file .\testarg.ps1 "first arg" "second arg"


来源:https://stackoverflow.com/questions/14011901/passing-quoted-arguments-to-powershell-scripts

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!