我想使用启动作业来运行需要参数的.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: -> '[]'
}