Powershell 工作流:工作流被终止活动终止

Powershell 工作流:工作流被终止活动终止

我有一个 PowerShell 脚本,它使用 Powershell Workflow 在多个远程服务器上同时运行许多 msdeploy。

一切工作正常,除了在每个“Foreach -Parallel”循环结束时,我得到这个异常:

Microsoft.PowerShell.Utility\Write-Error : The workflow was terminated by a Terminate activity.
At Execute-Bootstrapper:28 char:28
+ 
    + CategoryInfo          : NotSpecified: (:) [Write-Error], WorkflowReturnException
    + FullyQualifiedErrorId : Microsoft.PowerShell.Workflow.WorkflowReturnException,Microsoft.PowerShell.Commands.Writ 
   eErrorCommand
    + PSComputerName        : [localhost]

我该如何解决这个问题?有没有特定的方法来结束工作流程?

以下是与并行执行相关的部分:

foreach -Parallel ($remoteHost in $selectedHosts) {
    if($Env:FULL -eq "true") {
        $process = Start-Process -PassThru -Wait -NoNewWindow "C:\Program Files\IIS\Microsoft Web Deploy V3\msdeploy.exe" "xxx --full"
    } else {
        $process = Start-Process -PassThru -Wait -NoNewWindow "C:\Program Files\IIS\Microsoft Web Deploy V3\msdeploy.exe" "xxx"
    }
    if($process.ExitCode -ne 0) {
        Exit $process.ExitCode
    }
}

谢谢。

答案1

工作流与 Windows PowerShell 不同……工作流看起来像一个函数使用不同的关键字,但...不要被愚弄——了解工作流最重要的一点是,它们看起来像 Windows PowerShell,但实际上不是。

来源:工作流程:基础知识(在下面作业和工作流程主要文章位于嘿,脚本小伙!博客)。

以下部分注释的脚本可能会有所帮助。使用传递给MSDeploy.exe以下非常简单的参数进行测试:

  • -help -verb有效,退出代码 = 0,而其他
  • -help -brew并且-help -bubu不是,退出代码= -1。
  • 还要注意,-NoNewWindow如果没有-RedirectStandardOutput-RedirectStandardError会引发以下错误(考虑-NoNewWindow完全省略该参数):

Microsoft.PowerShell.Utility\Write-Error:处理来自后台进程的数据时出错。报告错误:无法处理节点类型为“Text”的元素。仅支持 Element 和 EndElement 节点类型。

workflow procWorkflow {

    ## workflow parameter
    param( $selectedHosts )

    ## $using: prefix allows us to call items that are in the workflow scope
    ##         but not in the function / inlinescript scope.
    Function myStartProcess {
        param( [string] $lineargs )
        $process = Start-Process `
            -FilePath "C:\Program Files\IIS\Microsoft Web Deploy V3\msdeploy.exe" `
            -PassThru -Wait -NoNewWindow `
            -RedirectStandardOutput "$env:TEMP\$using:remoteHost`Out.txt" `
            -RedirectStandardError  "$env:TEMP\$using:remoteHost`Err.txt" `
            -ArgumentList $lineargs
        $process.ExitCode                  # function return value
    }
    ## parallel foreach loop on workflow parameter
    foreach -Parallel ($remoteHost in $selectedHosts) {
        if($Env:FULL -eq "true") {
            # omitted as I know that there is no $Env:FULL variable defined on my comp
        } else {
            $processEx = myStartProcess "-help -$remoteHost"
            ###              tried instead above function call:
            ### $lineargs = "-help -$remoteHost"
            ### $process  = Start-Process -FilePath "C:\Program Files\IIS\Microsoft Web Deploy V3\msdeploy.exe" -PassThru -Wait -NoNewWindow -RedirectStandardOutput "$env:TEMP\$remoteHost`Out.txt" -RedirectStandardError "$env:TEMP\$remoteHost`Err.txt" -ArgumentList $lineargs
            ###     and then tried following output alternatives:
            ### $processEx = $process.ExitCode            # null  !!!
            ### $processEx = $process.HasExited           # false !!!
            ### $processEx = $process.GetType().FullName  # System.Management.Automation.PSObject
            ### $processEx = $process                     # System.Diagnostics.Process (msdeploy)
        }
        Write-Output  @{ $remoteHost = $processEx }  # workflow return value
    }
}

上述工作流程返回一个哈希表数组(大致hostname: exitcode成对),因为裸退出代码是不够的,因为它是并行运行的,所以输出顺序是随机的。

## example call to above workflow would look like
$procWorkflow = procWorkflow 'verb','brev','bubu'

## example output processing
"`n=== procWorkflow raw:"
$procWorkflow

"`n=== procWorkflow processed:`n"
for ($i=0; $i -lt $procWorkflow.Count; $i++) {
    $procWorkflow[$i].Keys | ForEach-Object {
        $procExitcode = $procWorkflow[$i][$_]
        if ( $procExitcode -eq 0 ) {
            $procOutFile = Get-Item "$env:TEMP\$_`Out.txt"
        } else {
            $procOutFile = Get-Item "$env:TEMP\$_`Err.txt"
        }
        '{0,-6} {1,6} {2,12}    {3}' -f 
            $_, $procExitcode, $procOutFile.Length, $procOutFile.Name
    }
}

输出

PS D:\PShell> D:\PShell\SF\805314_workflow.ps1

=== procWorkflow raw:

Name                           Value                                                 
----                           -----                                                 
bubu                           -1                                                    
brev                           -1                                                    
verb                           0                                                     

=== procWorkflow processed:

bubu       -1           56    bubuErr.txt
brev       -1           56    brevErr.txt
verb        0          537    verbOut.txt

相关内容