Powershell:将参数传递给作业

6

我有一个需要多个参数的脚本:

param ([string]$FOO="foo",[string]$CFG='\ps\bcpCopyCfg.ps1', [string]$CFROM="none", `
[string]$CTO="none", [switch]$HELP=$FALSE, [switch]$FULL=$FALSE, [string]$CCOL="none" `
,[string]$CDSQUERY="none", [string]$CMSSRV="none" `
,[string]$CSYBDB="none", [string]$CMSDB="none")

当从命令提示符调用时,例如:

powershell .\bcpCopy.ps1 -CFROM earn_n_deduct_actg -CTO fin_earn_n_deduct_actg -CCOL f_edeh_doc_id

一切正常。但是我需要同时启动几个(数十个)脚本实例,并编写了一个包装脚本,将执行实际工作的脚本作为作业调用: 我准备了一个包含参数的数组(包括像“-CFG”这样的关键字),并将其传递给start-job:

    # Prepare script block to be released
    $ARGS=("-CFG ", $CFG, "-CSYBDB ", $SYBDB, "-CMSDB ",$MSDB, "-CFROM ", $SYBTBL, "-CTO ",$MSTBL)
    if ($FULL) {
        $ARGS = $ARGS + " -FULL"
    } else { 
        $ARGS = $ARGS + " -CCOL $($args[5])  "
    } 
    "Argument array:"
    $ARGS

    start-job  -scriptblock {powershell.exe -file '\ps\bcpCopy.ps1'} -ArgumentList $ARGS

很不幸,被调用的脚本没有接收到参数:调用者打印出来的数组看起来很好:

参数数组:
-CFG
\ps\bcpCopyCfgOAH.ps1
-CSYBDB
vnimisro
-CMSDB
IMIS_UNOV
-CFROM
earn_n_deduct_ref
-CTO
fin_earn_n_deduct_ref
-FULL

但是被调用脚本的输出表示只有配置文件这一个参数被接收了——其他所有参数都在它们的默认值状态下。

PS C:\ps> receive-job 1391
12/17/2010 10:54:14 开始上传表 none;源数据库 none;
12/17/2010 10:54:14 目标表为 none;目标数据库为 none;
12/17/2010 10:54:14 配置文件是 \ps\bcpCopyCfg.ps1。
12/17/2010 10:54:14 目标服务器(MS SQL)为 secap900-new
12/17/2010 10:54:14 必须指定源数据库。正在退出...

请问我做错了什么?

2个回答

6

我不确定你想要做什么,但是这看起来是错误的:

start-job  -scriptblock {
    powershell.exe -file '\ps\bcpCopy.ps1'} -ArgumentList $ARGS

你正在不必要地创建一个全新的PowerShell进程。请尝试使用以下方法代替:
start-job  -scriptblock {
    & 'c:\ps\bcpCopy.ps1' @args } -ArgumentList $ARGS

"@args"语法被称为"splatting"。这将扩展传递的参数并确保每个元素都被视为一个参数。符号"&"是"调用"运算符。


谢谢您的建议。现在工作已经发布,但似乎卡住了,没有做任何事情。即使我在脚本开始后立即放置一个退出命令并打印参数,它仍然挂起。顺便说一下,使用这种启动任务的方式,任务管理器仍然显示15个PowerShell进程 - 正好是我启动的数量。 - Lubo
在手动停止作业后,receive-job 不会返回任何内容。 - Lubo
正如我所说,&(调用)会启动一个PowerShell进程,但该进程会挂起。 - Lubo
@args(扩展)在脚本名称后面的使用是一个启示——解决了我的参数传递问题——非常感谢。所以“最终”的版本是: start-job -scriptblock {powershell.exe -file 'c:\ps\bcpCopy.ps1' @args} -ArgumentList $ARGS - Lubo

0
另一种方法是在数组前面加上@。我将$ARGS变量更改为$flags,以区分脚本块中的$args和$flags。
$flags = @("-CFG ", $CFG, "-CSYBDB ", $SYBDB, "-CMSDB ",$MSDB, "-CFROM ", $SYBTBL, "-CTO ",$MSTBL)

If($FULL) {
    $flags = $flags + " -FULL"
}
Else {
   $flags = $flags + " -CCOL $($args[5])  "
}
"Argument array:"
$flags

start-job  -scriptblock {powershell.exe -file '\ps\bcpCopy.ps1' $args} -ArgumentList $flags

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接