我有一个PowerShell脚本,它使用Powershell Workflow在多个远程服务器上同时运行多个msdeploy。
一切工作正常,除了在每个“Foreach -Parallel”循环的末尾,我得到这个exception:
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]
我怎样才能解决这个问题 ? 有没有特定的方式来结束工作stream程?
以下是与并行执行相关的部分:
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 } }
谢谢。
工作stream程与Windows PowerShell不同…工作stream程可能看起来像一个具有不同关键字的函数 ,但是…不要被愚弄 – 了解工作stream程最重要的一点是,它们看起来像Windows PowerShell,但它们不是。
来源: 工作stream程:基础知识 (在“ 工作stream程”和“工作stream程”主题下, 您好,脚本专家!博客 )。
以下部分评论脚本可以帮助。 testing使用非常简单的parameter passing给MSDeploy.exe ,如此
-help -verb有效,退出代码= 0而其他 -help -brew和-help -bubu不是,退出代码= -1。 -NoNewWindow没有-RedirectStandardOutput和-RedirectStandardError会引发下面的错误(考虑完全忽略-NoNewWindow参数):
Microsoft.PowerShell.Utility\Write-Error:处理来自后台进程的数据时出错。 报告错误:无法处理节点types为“文本”的元素。 只支持Element和EndElement节点types。
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 } }
上面的工作stream程返回一个哈希表数组(大致是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