Fluxo de trabalho do Powershell: o fluxo de trabalho foi encerrado por uma atividade Terminate

2

Eu tenho um script do PowerShell que está executando muitos msdeploy simultaneamente em vários servidores remotos usando o Powershell Workflow.

Tudo funciona bem, exceto que no final de cada loop "Foreach -Parallel", recebo esta exceção:

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]

Como posso consertar isso? Existe uma maneira específica de encerrar um fluxo de trabalho?

Aqui está a parte relacionada à execução paralela:

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
    }
}

Obrigado.

    
por Kedare 26.09.2016 / 12:47

1 resposta

2

Workflows differ from the Windows PowerShell … a workflow may look like a function with a different keyword but … don’t be fooled — the most important point to understand about workflows is that they look like Windows PowerShell but they aren’t.

Fonte: Fluxos de trabalho: noções básicas (em Jobs e Workflows artigo principal em < a href="https://blogs.technet.microsoft.com/heyscriptingguy"> Ei, cara de scripts! Blog ).

O seguinte script parcialmente comentado pode ajudar. Testado usando parâmetros muito simples passados para MSDeploy.exe tal que

  • -help -verb é válido, código de saída = 0 enquanto outro
  • -help -brew e -help -bubu não são, código de saída = -1.
  • Observe também que -NoNewWindow sem -RedirectStandardOutput e -RedirectStandardError aumentariam o erro a seguir (considere omitir o parâmetro -NoNewWindow ):

Microsoft.PowerShell.Utility\Write-Error: There is an error processing data from the background process. Error reported: Cannot process an element with node type "Text". Only Element and EndElement node types are supported..

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
    }
}

O fluxo de trabalho acima retorna uma matriz de hash-tables (aproximadamente hostname: exitcode pairs) porque um código de saída simples não seria suficiente, pois a ordem de saída é aleatória, já que foi executada em paralelo.

## 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
    }
}

Saída :

PS D:\PShell> D:\PShell\SF5314_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
    
por 26.01.2017 / 21:38