Expand a variable in a scriptblock

Hello All

I am writing a powerscript to display a message on every computerscreen. However I wanted it to be flexible and to take the input from a command line (or a text file).

The moment the variable is used inside the scriptblock, it’s not working anymore

[pre]

function SendAll($msg) {
$pclist=Get-Content $list
$number_of_pcs=$pclist.count
write-host “Sending message to” $number_of_pcs “systems”
foreach ($pc in $pclist) {
write-host "Sending to " $pc
invoke-command -computername $pc -scriptblock {
$cmdMessage = {c:\windows\system32\msg.exe * ‘Please logoff - system restart in 5 minutes’}
$cmdMessage | invoke-expression
}
}
}
[/pre]

now, above works fine, but this means altering the text each and every time
What I was hoping to achieve was to use $msg (which contains the full command, i.e. {c:\windows\system32\msg.exe * 'text which was input at an earlier stage to send the message, something along following lines

 

Invoke-Command -Computername $pc -Scriptblock {
$msg | invoke-expression

But the variable $msg is not expanding in the scriptblock, therefore I only receive an error message when running the script

Can anyone point me into the right direction on how to solve this ?

Thank you

 

The thing to bear in mind is that you’re running that scriptblock in a new session on another PC - it can’t access the variables you have in your current scope.

You can pass arguments to the scriptblock by adding a param block, and using `-ArgumentList` on Invoke-Command.

For instance:
[pre]
param(
$MSG
)
Invoke-Command -ComputerName $Computer -ArgumentList $MSG -ScriptBlock {
param($Msg)
msg * $Msg
}
[/pre]

In PS v3 and higher, you can also do it a little more directly using the $using: prefix:

param(
$Msg
)
Invoke-Command -ComputerName $Computer -ScriptBlock {
msg * $using:Msg
}

thank you. I will alter the code and give it a try

I modify it like this:

function Send-Message
{
Param ($list,$msg)
$pclist=Get-Content $list
write-host ("Sending message to ["+$pclist.count+"] systems")
$Sessions = $pclist |%{New-PSSession -ComputerName $_}
invoke-command -Session $Sessions -scriptblock {
	Write-host "Sending to: " $env:computername
	msg.exe * $Using:msg
	}
}

Send-Message -list "d:\list.txt" -msg 'Please logoff – system restart in 5 minutes'

Use session faster than foreach.

 

thank you all for your kind explanations and examples … It now works perfectly…