I have the code below that I have been working on and I have an issue, I can not get it to send the variable message to the computer, if I take out the variable it works but that is not what I was trying to accomplish with it.
Function Send-PopupMessage {
#Requires -Version 2.0
[CmdletBinding()]
Param(
[Parameter(Mandatory = $true)]
[String]$ComputerName,
[Parameter(Mandatory = $true)]
[String]$Message
)
Invoke-Command -ComputerName $ComputerName -Scriptblock {
$CmdMessage = "msg.exe * $Message"
Write-Host $CmdMessage
$CmdMessage | Invoke-Expression
}
}
This is not the same as the question linked because I am in a session to another computer using PSWA so I am not able to start another session from this. Also even when I changed my code to be more like the one in the "Duplicate" question I am still getting the same results that the cmd being sent to the other computer is
msg.exe * '' instead of msg.exe * 'Test Message'
PowerShell script blocks are not lexical closures by default. The scriptblock passed to Invoke-Command does not save the current value of the $Message
parameter when being run on the other computer.
When the block is run in the remote session, it is using the current value of $Message
in that session. Because that variable is most likely $null
, the message is omitted from your command.
Use the $using:variable
syntax described in this question to capture the value of $Message
.
Invoke-Command -ComputerName $ComputerName -Scriptblock {
$CmdMessage = "msg.exe * $using:Message"
Write-Host $CmdMessage
$CmdMessage | Invoke-Expression
}
The $using:variable
syntax only works when invoking a block on a remote computer. If you need to capture variables in a scriptblock for local execution, instead call GetNewClosure()
on the ScriptBlock.
$Message = "Hey there."
$closure = {
$CmdMessage = "msg.exe * $Message"
Write-Host $CmdMessage
$CmdMessage | Invoke-Expression
}.GetNewClosure()
$Message = $null
Invoke-Command -Scriptblock $closure