可以* .ps1脚本作为后台作业运行自己执行* .ps1脚本吗?

时间:2011-03-03 20:51:51

标签: powershell powershell-jobs

我想运行一个脚本的15个实例,它将5个脚本连接在一起,到目前为止,我已经错过了小精灵的尘埃。我把这个问题归结为一个带有主脚本的测试用例,该脚本调用一个从属脚本,该脚本又调用一个sub_slave脚本(不需要管道来重现失败。)

如果master.ps1调用slave.ps1,则每个后台作业将无限期挂起slave.ps1调用sub_slave.ps1。如果我将slave.ps1中的调用注释掉到sub_slave.ps1,则master.ps1将运行完成。如果我直接启动slave.ps1,它会运行对sub_slave.ps1的调用就好了。如果我尝试双链,问题似乎难以处理。我没有在文档中看到任何东西说你不能将这些脚本连接到任意深度,但也许我读的不够深入?

您会看到我通过将内容添加到简单文本文件来跟踪脚本的进度。

d:\作业\ master.ps1

$indexes = @(0,1,2)

$initString = "cd $pwd"
$initCmd = [scriptblock]::create($initString)

set-content -path out.txt -value "Master started"
foreach ($index in $indexes)
{
    add-content -path out.txt -value "job  starting"
    start-job -filepath slave.ps1 -InitializationScript $initCmd -ArgumentList @("master index $index originated")
}

add-content -path out.txt -value "master completed"

d:\作业\ slave.ps1

#requires -version 2.0

param (
    [parameter(Mandatory=$false)]
    [string]$message = "slave_originated"
)

begin
{
    Set-StrictMode -version Latest
    add-content -path out.txt -value "slave beginning in $pwd"
}

process
{
    add-content -path out.txt -value "slave processing $message"
    invoke-expression "D:\jobs\sub_slave.ps1 -message $message" 
}

end
{
    add-content -path out.txt -value "slave ending"
}

d:\作业\ sub_slave.ps1     #requires -version 2.0

param (
    [parameter(Mandatory=$false)]
    [string]$message = "sub_slave originated"
)

begin
{
    Set-StrictMode -version Latest

    add-content -path out.txt -value "sub_slave beginning"
}

process
{
    add-content -path out.txt -value "sub_slave processing $message"
}

end
{
    add-content -path out.txt -value "sub_slave ending"
}

当代码以书面形式运行时,没有任何注释,我在out.txt中得到这个: d:\作业\ out.txt

Master started
job  starting
job  starting
job  starting
master completed
slave beginning in D:\jobs
slave processing master index 0 originated
slave beginning in D:\jobs
slave processing master index 1 originated
slave beginning in D:\jobs
slave processing master index 2 originated

请注意,每个告别消息之后的下一个命令是对sub_slave.ps1的调用,并且根本没有来自sub_slave.ps1的消息。系统将挂起3个powershell.exe进程永远运行愉快。获取作业报告3个进程仍在运行和HasMoreData。

我得到的唯一线索是,如果我崩溃挂起的进程,我看到:

Number of exceptions of this type:        2
Exception MethodTable: 79330e98
Exception object: 012610fc
Exception type: System.Threading.ThreadAbortException
Message: <none>
InnerException: <none>
StackTrace (generated):
<none>
StackTraceString: <none>
HResult: 80131530
-----------------

Number of exceptions of this type:        2
Exception MethodTable: 20868118
Exception object: 01870344
Exception type: System.Management.Automation.ParameterBindingException
Message: System error.
InnerException: <none>
StackTrace (generated):
<none>
StackTraceString: <none>
HResult: 80131501
-----------------

也许我有某种参数问题?如果我从sub_slave.ps1中删除所有参数,行为将保持不变,所以我有点怀疑,但这是可能的。我对任何想法持开放态度。

2 个答案:

答案 0 :(得分:3)

您正在调用sub_slave.ps1错误。这样:

invoke-expression "D:\jobs\sub_slave.ps1 -message $message" 

应该是这样的:

D:\jobs\sub_slave.ps1 -message $message

消息被评估并成为多个参数。

答案 1 :(得分:0)

这里只是猜测,但是多个线程/作业写入同一个文件out.txt可能会导致问题。