如何将参数传递给通过启动作业调用的PS脚本



我想使用启动作业来运行需要参数的.ps1脚本。这是脚本文件:

#Test-Job.ps1 
Param (
[Parameter(Mandatory=$True)][String]$input
)
$output = "$input to output"
return $output

下面是我运行它的方式:

$input = "input"
Start-Job -FilePath 'C:PowerShelltest_job.ps1' -ArgumentList $input -Name "TestJob"
Get-Job -name "TestJob" | Wait-Job | Receive-Job
Get-Job -name "TestJob" | Remove-Job

像这样运行,它返回"以输出";,因此$input在作业运行的脚本中为null。

我看到过其他类似的问题,但它们大多使用-Scriptblock代替-FilePath。是否有不同的方法通过启动作业将参数传递到文件?

tl;dr

  • $input自动变量(PowerShell提供的值(,不应用作自定义变量。

  • 简单地将$input重命名为$InputObject就可以解决您的问题。


正如Lee_Dayey所指出的,$input是一个自动变量,不应将分配给(它由PowerShell自动管理,以在非高级脚本和函数中提供管道输入的枚举器(。

令人遗憾和出乎意料的是,几个自动变量,包括$input可以分配给:请参阅此答案。

$input是一个特别阴险的例子,因为如果将其用作参数变量,则传递给它的任何值都会被悄悄丢弃,因为在函数或脚本的上下文中,$input始终是任何管道输入的枚举器。

这里有一个简单的例子来演示这个问题:

PS> & { param($input) "[$input]" } 'hi'
# !! No output - the argument was quietly discarded.

$input的内置定义优先,可以证明如下:

PS> 'ho' | & { param($input) "[$input]" } 'hi'
ho # !! pipeline input took precedence

虽然在技术上可以将$input用作常规变量(而不是参数变量(,但只要不跨越范围边界,就应该避免自定义使用$input

& {
$input = 'foo'   # TO BE AVOIDED
"[$input]"       # Technically works: -> '[foo]'
& { "[$input]" } # FAILS, due to child scope: -> '[]'
}

最新更新