首页 > 解决方案 > 如何使用 Start-Process 在会话中使用本地 PowerShell 变量?

问题描述

我有一个本地字符串变量,其中包含我想在 PS 脚本中尽早定义和设置的文件路径,然后在Start-Process调用的命令块中重用。我试过这个:

Start-Process Powershell { Set-Location $FlatScriptFolder ; .\BH-Corporate-Flats-Make-Assets.ps1 ; Read-Host}

脚本运行时,该特定行会导致错误:

Set-Location : Cannot process argument because the value of argument "path" is null. Change the value of argument
"path" to a non-null value.
At line:1 char:1
+ Set-Location $FlatScriptFolder ; .\BH-Corporate-Flats-Make-Serve.ps1  ...

我已经收集到问题是变量范围。我的变量是本地的,(远程)会话看不到它。我发现这篇博客文章完美地解释了这个问题,但我不明白解决方案在我的情况下如何工作。老实说,我在研究这个特定问题时遇到了麻烦,所以希望这里有人可以提供帮助?

这是我尝试过的另外两件事:

Start-Process Powershell { param ($FlatScriptFolder) Set-Location $FlatScriptFolder ; .\BH-Corporate-Flats-Make-Assets.ps1 ; Read-Host}

$Script1Command = { Set-Location $FlatScriptFolder ; .\BH-Corporate-Flats-Make-Serve.ps1 ; Read-Host}
Start-Process Powershell -ArgumentList ($Script1Command)

当我尝试上述任何一种方法时,我都会收到完全相同的错误消息。

标签: powershell

解决方案


当您使用powershell.exeStart-Process[1]时,您不能直接脚本块传递给 ,但您可以传递一个的字符串表示形式,然后需要您在其前面加上&呼叫运算符 。

此外,为了从调用者的上下文中合并变量值,您需要将它们作为参数传递(其中第一个可以作为 访问$Args[0]):

Start-Process powershell.exe '-Command', '&',
 '{ Set-Location $Args[0]; .\BH-Corporate-Flats-Make-Assets.ps1; Read-Host }',
   "\`"$FlatScriptFolder\`""

请注意 - 不幸 - 需要将参数的值包含在双重转义的嵌入"..."中,这是正确传递具有嵌入空格的值所必需的 - 请参阅此 GitHub 问题

注意:"'$FlatScriptFolder'",即对嵌入的引号使用引号原则上是可行的,但前提是指定的值'本身不包含任何实例。所需的双重转义"源于 (a) 满足 PowerShell在双引号字符串 ( )中嵌入双引号的直接语法要求,另外还需要 -转义它们以便 Powershell 的CLI识别它们。`"\


或者,您可以在调用者的上下文中使用字符串扩展(插值)扩展将局部变量“烘焙”到命令字符串中以传递给新的 PowerShell 实例

  • 由于您没有传递任何参数,因此无需传递&运算符前面的(字符串化)脚本块 - 您可以按原样传递语句列表。

  • 需要注意的是,将在调用者上下文中执行的内容与被调用者最终执行的内容区分开来可能会很棘手(您需要`-escape$引用被调用者上下文中的变量/表达式的实例)。

Start-Process powershell.exe '-Command', 
 "Set-Location \`"$FlatScriptFolder\`"; .\BH-Corporate-Flats-Make-Assets.ps1 ; Read-Host"

最后,如果您只想为新进程设置工作目录,您可以简单地使用-WorkingDirectory参数

Start-Process -WorkingDirectory $FlatScriptFolder powershell.exe '-Command', 
  '.\BH-Corporate-Flats-Make-Assets.ps1; Read-Host'

[1] 后面的参数powershell.exe被隐式传递给Start-Process' 第二个位置参数
-ArgumentList,其类型为[string[]]. 因此,任何非字符串类型都会[string]在调用时转换为。如果将脚本块 ( {...}) 转换为字符串,则文字内容- 没有封闭的{and}被传递;简而言之:传递{...}与传递相同'...',无论...代表什么,目标powershell.exe实例都不会将其视为脚本块。


推荐阅读