如何在 PowerShell 中将参数作为 -file 的一部分传递

How to pass parameters as part of -file in PowerShell

如果我 运行 PowerShell 中的这一行 window,它会完美执行

.\buildTestAndPublish.ps1 -buildPath 'C:\Program Files (x86)\Microsoft Visual Studio17\Enterprise\MSBuild.0' -testPath 'C:\Program Files (x86)\Microsoft Visual Studio17\Enterprise\Common7\IDE\CommonExtensions\Microsoft\TestWindow'

现在我需要自动执行此操作,但我没有这样做

$pth = 'C:\Program Files (x86)\Microsoft Visual Studio17\Community\MSBuild.0'
$testPth = 'C:\Program Files (x86)\Microsoft Visual Studio17\Community\Common7\IDE\CommonExtensions\Microsoft\TestWindow' 
start-process powershell -Verb runAs -ArgumentList "-file $PSScriptRoot\AutomationScripts\buildTestAndPublish.ps1 -buildPath $pth -testPath $testPth"

A positional parameter could not be found that accepts argument Files

这看起来像是在抱怨白色space,但经过搜索,我将它们用单引号括起来并作为变量传递(我在网上找到的建议)

我需要做什么?

在可能包含空格的参数周围使用嵌入式双引号;在 "..." 中, 将嵌入的 " 转义为 `",因为 ` 反引号 字符[1] , 是 PowerShell 的转义符:

"-file $PSScriptRoot\buildTestAndPublish.ps1 -buildPath `"$pth`" -testPath `"$testPth`""

注意:*.ps1 为便于阅读缩短了路径。

注意:嵌入式引号('...' 在这种情况下有效,因为将 PowerShell CLI 与 -File 一起使用不会将单引号识别为字符串分隔符;相比之下,它们被识别为 -Command.[2]


请注意,您可以或者将参数单独作为数组传递给-ArgumentList.
然而,由于a known bug 你必须仍然应用嵌入式双引号:

Start-Process powershell -Verb runAs -ArgumentList '-file',
  $PSScriptRoot\AutomationScripts\buildTestAndPublish.ps1,
  '-buildPath',
  "`"$pth`"",
  '-testPath',
  "`"$testPth`""

[1] 正式名称为 GRAVE ACCENT, Unicode code point U+0060.

[2] 因此,您可以使用 -Command 而不是 -File,这将启用以下解决方案:
"-Command $PSScriptRoot\buildTestAndPublish.ps1 -buildPath '$pth' -testPath '$testPth'",但是 (a) ' 是文件名中的合法字符(而 " 不是)并且文件名中存在 ' 会破坏命令; (b) -Command 将参数视为 PowerShell 代码,这可能会导致额外的不需要的解释(相比之下,-File 将其参数视为 文字 )。