powershell - 如何使用 Start-Process 在 session 中使用本地 PowerShell 变量?

标签 powershell

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

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  ...

我发现问题出在变量范围上。我的变量是本地变量,(远程) session 看不到它。我发现this blog post这完美地解释了这个问题,但我不明白该解决方案在我的情况下如何工作。老实说,我在研究这个具体问题时遇到了困难,所以希望这里有人可以提供帮助?

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

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)

当我尝试上述任一操作时,我收到完全相同的错误消息。

最佳答案

使用 Start-Process 时,无法直接将脚本 block 传递给 powershell.exe[1] ,但您可以传递 1 的字符串表示,然后需要在其前面加上调用运算符 & 前缀。

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

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

请注意 - 不幸的是 - 需要将参数的值括在双重转义嵌入的 "..." 中,这是带有嵌入空格的值所必需的正确通过 - 请参阅 this GitHub issue .

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


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

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

  • 需要注意的是,区分调用者上下文中将执行的内容与被调用者最终执行的内容可能会很棘手(您需要 `-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]。如果将脚本 block ({...}) 转换为字符串,文字内容 - 不包含封闭的 { } 已通过;简而言之:传递 {...} 与传递 '...' 相同,无论 ... 代表什么,以及目标powershell.exe 实例不会将其视为脚本 block 。

关于powershell - 如何使用 Start-Process 在 session 中使用本地 PowerShell 变量?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51315395/

相关文章:

windows - PowerShell - Invoke-Sqlcmd 结果到 Export-Csv 设置批处理行限制

powershell - 从另一个 csv 中删除 1 个 csv 中的行

powershell - -PipelineVariable 不适用于 Get-NetIPAddress

c# - 自定义 Powershell 提供程序实现

json - Powershell 无法从名为 count 的键中获取值

windows - 如何获得 LAN 上事件的 IP 地址、MAC 地址和 NetBIOS 名称的列表?

powershell - 在PowerShell中获取PATH环境变量

sql-server - 使用不同的凭据调用 SQLCmd

azure - 获取 Azure VM 创建日期

windows - 使用批处理文件/脚本编辑注册表