Storing a Command/ScriptBlock as a Variable Which Contains a Variable Reference

by Jul 23, 2015

PoSH noob here – with what is likely a very simple problem.

 

I'm trying to store a command as a variable that I can then use later on in a scriptblock but I've run into problems.

Consider the following:

$arrSystems = @("sys1","sys2", … "sysN")

foreach($System in $arrSystems)
{
$Command = GCI -Path 'C:' -Include '*something*' -Recurse -ErrorAction SilentlyContinue | Select LastWriteTime,FullName | Ft -AutoSize | Out-File "\serversharelogs$System.log"

$Sess = New-PSSession -ComputerName $System -EA SilentlyContinue
Invoke-Command -Session $Sess -ScriptBlock { Start-Job -ScriptBlock { $Command } } -EA SilentlyContinue
$Sess | Remove-PSSession
}

 

 

However, instead of storing the command as the variable $Command, the command is actually executed and the results are stored in $Command.

My kneejerk reaction was to do change command to the following:

$Command = 'GCI -Path "C:" -Include "*something*" -Recurse -ErrorAction SilentlyContinue | Select LastWriteTime,FullName | Ft -AutoSize | Out-File "\serversharelogs' + $System + '.log"'

 

But even if I execute that on my machine via:

$System = $env:COMPUTERNAME
$Command = 'GCI -Path "C:" -Include "*something*" -Recurse -ErrorAction SilentlyContinue | Select LastWriteTime,FullName | Ft -AutoSize | Out-File "\serversharelogs' + $System + '.log"'
Start-Job -Name "Test" -ScriptBlock { $Command }

 

It doesn't seem to execute and I suspect its because of the way the command is formatted as this doesn't work:

PS C:Windowssystem32> &$Command
& : The term 'GCI -Path "C:" -Include "*something*" -Recurse -ErrorAction SilentlyContinue | Select LastWriteTime,FullName | Ft -AutoSize | Out-File "\serversharelogsSystem007.log"' is not recognized as the name of a cmdlet, function, script file, or operable program. Check the spelling of the name, or if a path was
included, verify that the path is correct and try again.
At line:1 char:2
+ &$Command
+ ~~~~~~~~~~~~~~~~~
+ CategoryInfo : ObjectNotFound: (GCI -Path "C:"…System007.log":String) [], CommandNotFoundException
+ FullyQualifiedErrorId : CommandNotFoundException

 

So my next thought was I needed to wrap the command in curly braces:

$Command = { GCI -Path 'C:' -Include '*something*' -Recurse -ErrorAction SilentlyContinue | Select LastWriteTime,FullName | Ft -AutoSize | Out-File "\serversharelogs$System.log" }

 

But that doesn't expand $System resulting in:

PS C:Windowssystem32> $Command
GCI -Path 'C:' -Include '*something*' -Recurse -ErrorAction SilentlyContinue | Select LastWriteTime,FullName | Ft -AutoSize | Out-File "\serversharelogs$System.log"

 

I realize it may be preferable to create scriptblocks that contain other references to variables like this:

$TagLine = "Just Do It"
$Brand = "The tag line (`$TagLine) for Nike is $TagLine"
[scriptblock]::Create($Brand)

But I can't get around the whole 'PowerShell is executing the command and storing the output in the variable versus storing the command in the variable' hump. 

Help!