开发者

String expansion does not work in PowerShell when using Invoke-Command on remote computer

开发者 https://www.devze.com 2023-02-07 11:01 出处:网络
Why isn\'t the first example equivalent to the second ? 1: $volumeNum 开发者_运维问答= 2 Invoke-Command -ComputerName $IP -Credential $GuestVM -ScriptBlock {\"select volume $volumeNum\" | diskpart}

Why isn't the first example equivalent to the second ?

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}

Why does't powershell evaluate

"select volume $volumeNum"

to

select volume 2


The script block that is executed via Invoke-Command does not have access to the current environment state, it is run in a separate process. If you were running the command on your local computer it would work.

The issue is that the string "select volume $volumeNum" is not being evaluated until it is executed on the remote machine. So it is looking for the value in the environment of the current process on the remote machine and $volumeNum is not defined there.

PowerShell provides a mechanism for passing arguments via Invoke-Command. This works from my local machine to a remote:

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

I believe a similar approach would work for you:

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


Script blocks are compiled. That means the variable references in them are fixed at compile time. You can work around this by deferring creation of the script block until run time:

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


Further note for others comming along: GetNewClosure doesn't work as well.

$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*" }
0

精彩评论

暂无评论...
验证码 换一张
取 消