Powershell删除引号参数

时间:2018-07-30 14:08:08

标签: powershell powershell-v5.0 start-process

我正在使用Start-Process以管理员身份启动Powershell的另一个实例,但是当我尝试传递参数列表时,无论是作为变量还是纯字符串,Powershell都会删除引号。下面是我正在使用的命令:

$argu = '-noexit "C:\Program Files (x86)\Microsoft Visual Studio\2017\BuildTools\VC\Auxiliary\Build\vcvars64.bat"';
powershell Start-Process -Verb RunAs -FilePath powershell -ArgumentList $argu

这是我得到的错误:

x86 : The term 'x86' is not recognized as the name of a cmdlet, function, script file, or operable program. Check the spelling of the name, or if a path was included,
verify that the path is correct and try again.
At line:1 char:88
+ ... Program Files (x86)\Microsoft Visual Studio\2017\BuildTools\VC\Auxiliary\Build\v ...
+                    ~~~
    + CategoryInfo          : ObjectNotFound: (x86:String) [], CommandNotFoundException
    + FullyQualifiedErrorId : CommandNotFoundException

在此先感谢您的帮助。

更新:

$argu = '''-noexit ""C:\Program Files (x86)\Microsoft Visual Studio\2017\BuildTools\VC\Auxiliary\Build\vcvars64.bat""''';
powershell Start-Process -Verb RunAs -FilePath powershell -ArgumentList $argu

这几乎可以解决它,但是现在我在第二窗口而不是第一个窗口中得到了上面的错误。

1 个答案:

答案 0 :(得分:2)

(A)从内部 PowerShell:

$argu = '-noexit -command & \"C:\Program Files (x86)\Microsoft Visual Studio\2017\BuildTools\VC\Auxiliary\Build\vcvars64.bat\"'
Start-Process -Verb RunAs -FilePath powershell -ArgumentList $argu

注意:我一般不会通过Start-Process呼叫powershell.exe,因为通常不需要这样做。

  • 嵌入式"被转义为\,这是PowerShell在调用其 CLI 时所需要的(也许令人惊讶,因为PowerShell在内部是`作为转义字符。

    • 也就是说,假设"嵌入在'...'内,它们不需要额外转义-见下文。
  • 要执行的文件路径以调用运算符&为前缀,因为您需要它来执行以引号形式指定的文件。

  • 请注意,我已经添加了-Command,这在Windows PowerShell中不是严格必需的,但是如果您从PowerShell Core (现在默认为-File


或者,您也可以单独指定参数,作为 array 的一部分,这可以说是更干净的解决方案:

$argu = '-noexit', '-command', '&', 'de', 
  '\"C:\Program Files (x86)\Microsoft Visual Studio\2017\BuildTools\VC\Auxiliary\Build\vcvars64.bat\"'
Start-Process -Verb RunAs -FilePath powershell -ArgumentList $argu

遗憾的是,即使在这种情况下,您也需要为包含空格的参数a known Start-Process problem being tracked on GitHub使用多余的嵌入式引号

PowerShell在调用外部程序时对报价的处理通常是有问题的。 this GitHub issue中总结了当前问题。


(B)从外部 PowerShell(cmd.exe,自定义File Explorer上下文菜单):

powershell -command Start-Process -Verb RunAs -FilePath powershell -ArgumentList '-noexit -command . ''C:\Program Files (x86)\Microsoft Visual Studio\2017\BuildTools\VC\Auxiliary\Build\vcvars64.bat'''
    现在使用
  • 引号(嵌套的单引号转义为''),因为双引号实际上会使转义变得复杂。

  • 使用
  • .而不是&来执行.bat文件,这避免了如何解析&的问题。尽管.的用途与&的用途不同,但是两个运算符在调用 external 程序时的行为相同。

  • 如果您还想为最终打开提升权限的PowerShell会话设置工作目录,则需要合并一个明确的Set-Locationcd)调用放入命令字符串中,因为Start-Process -Verb RunAs始终默认为SYSTEM32文件夹(在这种情况下,即使-WorkingDirectory参数也无济于事)。

    • 为使该文件安全运行,您必须使用 double -引号 quote 目录路径,因为文件名可能包含单引号。使用%V作为目录路径(文件浏览器将其提供给通过自定义上下文菜单调用的命令),正确转义的Set-Location调用看起来像这样(我希望我在开玩笑):

      • Set-Location \"\"\"%V%\"\"\"

已集成到完整命令中(为简便起见,使用Set-Location的内置别名cd

powershell -command Start-Process -Verb RunAs -FilePath powershell -ArgumentList '-noexit -command cd \"\"\"%V%\"\"\"; . ''C:\Program Files (x86)\Microsoft Visual Studio\2017\BuildTools\VC\Auxiliary\Build\vcvars64.bat'''

顺便说一句:PowerShell Core 现在具有一个-WorkingDirectory-wd)CLI参数,该参数可让您更可靠地控制启动目录(pwsh -wd "c:\path\to\dir" ...) ;实际上,prompted the introduction of this parameter正是File Explorer自定义上下文菜单用例。