在远程计算机上使用Invoke-Command时,字符串扩展在PowerShell中不起作用

时间:2011-01-27 00:23:02

标签: string variables powershell

为什么第一个例子不等同于第二个?

1:

$volumeNum = 2
Invoke-Command -ComputerName $IP -Credential $GuestVM -ScriptBlock {"select volume $volumeNum" | diskpart}

2:

Invoke-Command -ComputerName $IP -Credential $GuestVM -ScriptBlock {"select volume 2" | diskpart}

为什么不对PowerShell进行评估

  

“select volume $ volumeNum”

  

选择第2卷

3 个答案:

答案 0 :(得分:7)

通过Invoke-Command执行的脚本块无法访问当前环境状态,它在单独的进程中运行。如果您在本地计算机上运行该命令,它将起作用。

问题是字符串"select volume $volumeNum"在远程计算机上执行之前不会被评估。因此,它正在远程计算机上查找当前进程环境中的值,并且未在此处定义$volumeNum

PowerShell提供了一种通过Invoke-Command传递参数的机制。这可以从我的本地机器到遥控器:

Invoke-Command -ComputerName $ip -ScriptBlock { param($x) "hello $x" } -ArgumentList "world"

我相信类似的方法对你有用:

Invoke-Command -ComputerName $IP -Credential $GuestVM -ScriptBlock {param($volumeNum) "select volume $volumeNum" | diskpart} -ArgumentList $volumeNum

答案 1 :(得分:3)

编译脚本块。这意味着它们中的变量引用在编译时是固定的。您可以通过将脚本块的创建推迟到运行时来解决此问题:

$sb = [scriptblock]::create("select volume $volumeNum | diskpart")
Invoke-Command -ComputerName $IP -Credential $GuestVM -ScriptBlock $sb

答案 2 :(得分:2)

进一步注意到其他人:GetNewClosure不起作用。

$filt = "*c*"
$cl = { gci D:\testdir $filt }.GetNewClosure()
& $cl

# returns 9 items
Invoke-command -computer mylocalhost -script $cl
# returns 9 items
Invoke-command -computer mylocalhost -script { gci D:\prgs\tools\Console2 $filt }
# returns 4 items
Invoke-command -computer mylocalhost -script { gci D:\prgs\tools\Console2 "*c*" }