Author Posts

August 18, 2015 at 3:58 am

I was playing with some little code and found a moment I cannot understand

$w = '1..10'
Invoke-Expression $w #this runs OK

then I try to run it as a job

start-job {Invoke-Expression $w} # or start-job {Invoke-Expression $global:w}

this returns an error: Cannot evaluate parameter 'Command' because its argument is specified as a script block and there is no input. A script block cannot be evaluated without input.

what is wrong?

August 18, 2015 at 5:00 am

Hi Simeon,

You will need to use the $using: scope modifier to let the PowerShell engine know to inject the value of the variable $w into the scriptblock {}.


$w = '1..10'
Start-Job { Invoke-Expression $using:w }

Jobs are running in another process and do not have access to variables in your current session.

Please consider more then twice if Invoke-Expression is the right command to be included in your scripts. It is a dangerous / harmful command because it allows injection of bad command lines similar to SQL injection and its usage can be avoided in 99.9% of all use cases.

http://blogs.msdn.com/b/powershell/archive/2011/06/03/invoke-expression-considered-harmful.aspx
http://powershell.com/cs/blogs/tips/archive/2014/11/06/invoke-expression-is-evil.aspx

Best,
Daniel

August 18, 2015 at 5:06 am

The problem is that that a job runs in a separate Powershell process so in your case $w doesn't exist when Invoke-expression tries to run

You could do this

Start-Job -ScriptBlock { $w = '1..10'; Invoke-Expression $w}

or
$w = '1..10'
Start-Job -ScriptBlock { param($w) Invoke-Expression $w} -ArgumentList $w

August 18, 2015 at 5:20 am

thanks, now I got it