For those looking to use a "parallel" workflow (no recursion) in a module, the solution is similar but a little different.
for example, this workflow can be used to start/stop service in parallel
Workflow Invoke-ServiceInParallelWF
{
<#
.SYNOPSIS
Workflow to stop/start services in parallel on a server.
.DESCRIPTION
Utilizes a workflow to start/stop services running on a server in parallel to shorten the start/stop duration.
#>
Param(
[Parameter(Mandatory=$true)]
[string[]]$Name,
[Parameter(Mandatory=$true)]
[ValidateSet("Start","Stop")]
[string]$Action
)
if (!($Name.Count -gt 0))
{
throw "No services provided!"
}
# run parrallel on services argument
foreach -parallel ($svc in $Name){
InlineScript{
#build object first for consistency
$props=[ordered]@{
Service=$using:svc;
Action=$using:action
Result=$null
Error=$null
}
# Wrap in exception handler
Try{
#Perform the desired service action
if ($using:action -eq 'stop') {
Stop-Service -name $using:svc -ErrorAction stop
} elseif ($using:action -eq 'start') {
Start-Service -name $using:svc -ErrorAction stop
} else {
$Action='unknown'
}
$props.Result='Success'
}
Catch{
$props.Result='Fail'
$props.Error="$_"
}
# generate object back to workflow
New-Object -TypeName PSCustomObject -Property $props
}
}
}
if you put this in your psm1 file and try to import it, it will fail with this error:
At C:\Source\Powershell\Common\Modules\MyModule\MyModule.psm1:1 char:1
+ #
+ ~
A workflow cannot use recursion.
+ CategoryInfo : ParserError: (:) [], ParseException
+ FullyQualifiedErrorId : RecursiveWorkflowNotSupported
To embed this in the module, do NOT put it in the .psm1 file, create a separate ps1 file and place it in the module folder.
e.g. Invoke-ServiceInParallelWF.ps1
Then in your manifest (psd1) file, modify the ScriptsToProcess to include the ps1 file.
@{
# Script module or binary module file associated with this manifest.
RootModule = 'MyModule.psm1'
# Version number of this module.
ModuleVersion = '1.47.1'
# ID used to uniquely identify this module
GUID = 'bd4390dc-a8ad-4bce-8d69-f53ccf8e4163'
# Author of this module
Author = 'Justin Marshall'
# Script files (.ps1) that are run in the caller's environment prior to importing this module.
ScriptsToProcess = @('Invoke-ServiceInParallelWF.ps1')
}
finally, import your module and test the function:
PS C:\source\powershell> Import-Module MyModule -force
PS C:\source\powershell> Invoke-ServiceInParallelWF -Action Start -Name w3svc
Service : w3svc
Action : Start
Result : Success
Error :
PSComputerName : localhost
PSSourceJobInstanceId : 1a564d5d-f363-44b7-a27e-88670764de2d