I have a script that requires a number of parameters:
param ([string]$FOO="foo",[string]$CFG='\ps\bcpCopyCfg.ps1', [string]$CFROM="none", `
[string]$CTO="none", [switc开发者_C百科h]$HELP=$FALSE, [switch]$FULL=$FALSE, [string]$CCOL="none" `
,[string]$CDSQUERY="none", [string]$CMSSRV="none" `
,[string]$CSYBDB="none", [string]$CMSDB="none")
when called from the command prompt e.g.
powershell .\bcpCopy.ps1 -CFROM earn_n_deduct_actg -CTO fin_earn_n_deduct_actg -CCOL f_edeh_doc_id
everything works fine. I need however to start several (dozens) instances of the script in parallel and I've written a wrapper script that calls the one doing the actual work as a job: I prepare an array with the arguments (including the keywords like "-CFG") anhd pass it to 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
Unfortunately, the called script does not receive the arguments: the caller prints the array and it looks fine:
Argument array:
-CFG \ps\bcpCopyCfgOAH.ps1 -CSYBDB vnimisro -CMSDB IMIS_UNOV -CFROM earn_n_deduct_ref -CTO fin_earn_n_deduct_ref -FULLbut the output from the called scripts says that the only parameter received is the configuration file -- all the rest are at their default values.
PS C:\ps> receive-job 1391
12/17/2010 10:54:14 Starting the upload of table none; source db none; 12/17/2010 10:54:14 Target table is none; target db is none; 12/17/2010 10:54:14 Config file is \ps\bcpCopyCfg.ps1. 12/17/2010 10:54:14 Target server (MS SQL) is secap900-new 12/17/2010 10:54:14 Source database must be specified. Exiting...
Can you please point me what am I doing wrong?
I'm not sure what exactly you're trying to do, but this looks wrong:
start-job -scriptblock {
powershell.exe -file '\ps\bcpCopy.ps1'} -ArgumentList $ARGS
You are creating an entirely new powershell process needlessly. Try this instead:
start-job -scriptblock {
& 'c:\ps\bcpCopy.ps1' @args } -ArgumentList $ARGS
The "@args" syntax is called "splatting." This will expand the passed arguments and ensure each element is treated as a parameter. The ampersand (&) is the "call" operator.
Another way is to put the @ before the array. I changed the $ARGS variable to $flags to differentiate $args in the scriptblock from $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
精彩评论