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.
Source: Workflows: The Basics (under Jobs and Workflows main article at Hey, Scripting Guy! Blog).
The following partially commented script could help. Tested using very simple parameters passed to MSDeploy.exe
such that
-help -verb
is valid, exit code = 0 while other
-help -brew
and -help -bubu
aren't, exit code = -1.
- Also note that
-NoNewWindow
without -RedirectStandardOutput
and -RedirectStandardError
would raise following error (consider omitting the -NoNewWindow
parameter at all):
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
}
}
Above workflow returns an array of hash-tables (roughly hostname: exitcode
pairs) because a bare exit code would not suffice as the output order is random since it was run in parallel.
## 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
}
}
Output:
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