如何在调用另一个PowerShell实例时扩展变量?

时间:2017-08-28 11:43:45

标签: powershell

我想运行以下命令在新的PowerShell实例中执行某些命令。

start powershell {java -jar x.jar -url $URL/computer/$name/ -secret $secret; Read-Host}

我已将$URL$name以及$secret作为输入参数传入,我可以毫无问题地回显其值。

问题是当新的PowerShell实例启动时,它只能看到

java -jar x.jar -url /computer// -secret

(即变量值尚未通过。) 我该如何解决这个问题?

完整的示例脚本是:

param(
[parameter(Mandatory=$TRUE,Position=0)]
  [string] $URL,
[parameter(Mandatory=$TRUE,Position=1)]
  [string] $name,
[parameter(Mandatory=$TRUE,Position=2)]
  [string] $secret
)

echo $URL
echo $name
echo $secret

start powershell {java -jar x.jar -url $URL/computer/$name/ -secret $secret; Read-Host}

1 个答案:

答案 0 :(得分:1)

通过将代码包含在方括号{}中,可以创建代码块。 Powershell解释器不会扩展代码块内的任何内容。尝试在powershell命令行中键入{ java $dummy }并单击return。 (未执行的)代码块的返回值是其未展开的内容。

通常,代码块会继承外部变量的值,因此如果要在调用上下文中执行代码块,变量值将是可见的并且可以使用。

但是,在新的PowerShell流程中启动它,变量未设置并返回空($null)值。

因此,您需要在前往start命令的路上扩展变量,并在执行java.exe的过程中保留扩展变量中的任何空格。以下转义应该适合你:

start powershell "java -jar x.jar -url '$URL/computer/$name/' -secret '$secret'; Read-Host"

为了安全起见这些问题,您可以将EncodedCommand参数与powershell一起使用,如下所示:

$command = "java -jar x.jar -url '$URL/computer/$name/' -secret '$secret'; Read-Host"  # Variables get expanded here
$bytes = [System.Text.Encoding]::Unicode.GetBytes($command)
$encodedCommand = [Convert]::ToBase64String($bytes)
start powershell "-EncodedCommand $encodedCommand"
# Or, with full parameters:
# Start-Process -FilePath powershell -ArgumentList "-EncodedCommand $encodedCommand"