I want to use start-job to run a .ps1 script requiring a parameter. Here's the script file:
#Test-Job.ps1
Param (
[Parameter(Mandatory=$True)][String]$input
)
$output = "$input to output"
return $output
and here is how I am running it:
$input = "input"
Start-Job -FilePath 'C:\PowerShell\test_job.ps1' -ArgumentList $input -Name "TestJob"
Get-Job -name "TestJob" | Wait-Job | Receive-Job
Get-Job -name "TestJob" | Remove-Job
Run like this, it returns " to output", so $input is null in the script run by the job.
I've seen other questions similar to this, but they mostly use -Scriptblock in place of -FilePath. Is there a different method for passing parameters to files through Start-Job?
tl;dr
$input
is an automatic variable (value supplied by PowerShell) and shouldn't be used as a custom variable.Simply renaming
$input
to, say,$InputObject
solves your problem.As Lee_Dailey notes,
$input
is an automatic variable and shouldn't be assigned to (it is automatically managed by PowerShell to provide an enumerator of pipeline input in non-advanced scripts and functions).Regrettably and unexpectedly, several automatic variables, including
$input
, can be assigned to: see this answer.$input
is a particularly insidious example, because if you use it as a parameter variable, any value you pass to it is quietly discarded, because in the context of a function or script$input
invariably is an enumerator for any pipeline input.Here's a simple example to demonstrate the problem:
That the built-in definition of
$input
takes precedence can be demonstrated as follows:While you can technically get away with using
$input
as a regular variable (rather than a parameter variable) as long as you don't cross scope boundaries, custom use of$input
should still be avoided: