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
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With