Scripts/Get-BPAWorkflow.ps1

function Get-BPAWorkflow {
    <#
        .SYNOPSIS
            Gets AutoMate BPA workflows.
 
        .DESCRIPTION
            Get-BPAWorkflow gets workflow objects from AutoMate BPA. Get-BPAWorkflow can receive items on the pipeline and return related objects.
 
        .PARAMETER InputObject
            The object(s) use in search for workflows.
 
        .PARAMETER Name
            The name of the workflow (case sensitive). Wildcard characters can be escaped using the ` character. If using escaped wildcards, the string
            must be wrapped in single quotes. For example: Get-BPAWorkflow -Name '`[Test`]'
 
        .PARAMETER ID
            The ID of the workflow.
 
        .PARAMETER FilterSet
            The parameters to filter the search on. Supply hashtable(s) with the following properties: Property, Comparator, Value.
            Valid values for the Comparator are: =, !=, <, >, contains (default - no need to supply Comparator when using 'contains')
 
        .PARAMETER FilterSetMode
            If multiple filter sets are provided, FilterSetMode determines if the filter sets should be evaluated with an AND or an OR
 
        .PARAMETER Parent
            Get workflows that contain the specified workflow. This parameter is only used when a workflow is piped in.
 
        .PARAMETER SortProperty
            The object property to sort results on. Do not use BPAServer or TypeName, since those are custom properties added by this module, and not exposed in the API.
 
        .PARAMETER SortDescending
            If specified, this will sort the output on the specified SortProperty in descending order. Otherwise, ascending order is assumed.
 
        .PARAMETER BPAServer
            The AutoMate BPA management server.
 
        .INPUTS
            Workflows related to the following objects can be retrieved by this function:
            Workflow
            Task
            Process
            Condition
            Folder
            Agent
            AgentGroup
 
        .EXAMPLE
            # Get workflow "My Workflow"
            Get-BPAWorkflow "My Workflow"
 
        .EXAMPLE
            # Get sub-workflows in workflow "My Workflow"
            Get-BPAWorkflow "My Workflow" | Get-BPAWorkflow
 
        .EXAMPLE
            # Get workflows in folder "My Folder"
            Get-BPAFolder "My Folder" -Type TASKS | Get-BPAWorkflow
 
        .EXAMPLE
            # Get workflows using a filter set
            Get-BPAWorkflow -FilterSet @{ Property = "Name"; Value = "FTP"}
 
        .EXAMPLE
            # Get workflows that have started in the last hour
            Get-BPAWorkflow -FilterSet @{Property = "StartedOn"; Comparator = ">"; Value = (Get-Date).AddHours(-1)}
 
        .NOTES
            Author(s): : David Seibel
            Contributor(s) :
            Date Created : 08/24/2016
            Date Modified : 06/07/2018
 
        .LINK
            https://github.com/davidseibel/PoshBPA
    #>

    [CmdletBinding(DefaultParameterSetName = "All")]
    [OutputType([System.Object[]])]
    param(
        [Parameter(ValueFromPipeline = $true, ParameterSetName = "ByPipeline")]
        [ValidateNotNullOrEmpty()]
        $InputObject,

        [Parameter(Position = 0)]
        [ValidateNotNullOrEmpty()]
        [string]$Name,

        [Parameter(ParameterSetName = "ByID")]
        [ValidateNotNullOrEmpty()]
        [string]$ID,

        [Hashtable[]]$FilterSet,

        [ValidateSet("And","Or")]
        [string]$FilterSetMode = "And",

        [Parameter(ParameterSetName = "ByPipeline")]
        [switch]$Parent = $false,

        [ValidateNotNullOrEmpty()]
        [string[]]$SortProperty = "Name",

        [switch]$SortDescending = $false,

        [ValidateNotNullOrEmpty()]
        [string]$BPAServer
    )

    BEGIN {
        # If the server is specified, or only 1 server is connected, don't show it. Otherwise, show the server.
        if ($PSCmdlet.ParameterSetName -eq "ByID" -and (-not $PSBoundParameters.ContainsKey("BPAServer")) -and ($global:BPAConnectionInfo.Count -gt 1)) {
            throw "When searching by ID: 1) BPAServer must be specified, OR 2) only one server can be connected."
        }
        $splat = @{
            RestMethod = "Get"
            BPAServer  = $BPAServer
        }
        $result = @()
        $workflowCache = @{}
        if ($PSBoundParameters.ContainsKey("Name") -and (-not [System.Management.Automation.WildcardPattern]::ContainsWildcardCharacters($Name))) {
            $FilterSet += @{Property = "Name"; Comparator = "="; Value = [System.Management.Automation.WildcardPattern]::Unescape($Name)}
        } elseif ($PSBoundParameters.ContainsKey("Name") -and [System.Management.Automation.WildcardPattern]::ContainsWildcardCharacters($Name)) {
            try   { "" -like $Name | Out-Null } # Test wildcard string
            catch { throw }                     # Throw error if wildcard invalid
            $splat += @{ FilterScript = {$_.Name -like $Name} }
        }
    }

    PROCESS {
        switch($PSCmdlet.ParameterSetName) {
            "All" {
                $splat += @{ Resource = Format-BPAUri -Path "workflows/list" -FilterSet $FilterSet -FilterSetMode $FilterSetMode -SortProperty $SortProperty -SortDescending:$SortDescending.ToBool() }
                $result = Invoke-BPARestMethod @splat
            }
            "ByID" {
                $splat += @{ Resource = "workflows/$ID/get" }
                $result = Invoke-BPARestMethod @splat 
            }
            "ByPipeline" {
                foreach ($obj in $InputObject) {
                    $tempSplat = $splat
                    if (-not $tempSplat.ContainsKey("BPAServer")) {
                        $tempSplat += @{ BPAServer = $obj.BPAServer } 
                    } else { 
                        $tempSplat["BPAServer"] = $obj.BPAServer
                    }
                    if (-not $workflowCache.ContainsKey($obj.BPAServer)) {
                        Write-Verbose "Caching workflow objects for server $($obj.BPAServer) for better performance"
                        $workflowCache.Add($obj.BPAServer, (Get-BPAWorkflow -FilterSet $FilterSet -FilterSetMode $FilterSetMode -SortProperty $SortProperty -SortDescending:$SortDescending.ToBool() -BPAServer $obj.BPAServer))
                    }
                    switch ($obj.TypeName) {
                        "Workflow" {
                            if ($Parent) {
                                $result += $workflowCache[$obj.BPAServer] | Where-Object {$_.Items.ConstructID -contains $obj.ID}
                            } else {
                                # Get workflows contained within the provided workflow(s)
                                foreach ($item in $obj.Items) {
                                    switch ($item.ConstructType -as [BPAConstructType]) {
                                        "Workflow"   {
                                            if ($item.ConstructID -ne "") {
                                                $result += Get-BPAWorkflow -ID $item.ConstructID -BPAServer $obj.BPAServer
                                            } else {
                                                Write-Warning "Workflow '$($obj.Name)' contains an unbuilt workflow!"
                                            }
                                        }
                                    }
                                }
                            }
                        }
                        {($_ -in @("Task","Process"))} {
                            $result += $workflowCache[$obj.BPAServer] | Where-Object {$_.Items.ConstructID -contains $obj.ID}
                        }
                        "Condition" {
                            $result += $workflowCache[$obj.BPAServer] | Where-Object {($_.Items.ConstructID -contains $obj.ID) -or ($_.Triggers.ConstructID -contains $obj.ID)}
                        }
                        "Folder" {
                            # Get workflows located within the provided folder(s)
                            $result += $workflowCache[$obj.BPAServer] | Where-Object {$_.ParentID -eq $obj.ID}
                        }
                        {($_ -in @("Agent","AgentGroup","SystemAgent"))} {
                            # Get workflows configured to run on the provided agent(s) or agent group(s)
                            :workflowloop foreach ($workflow in $workflowCache[$obj.BPAServer]) {
                                foreach ($item in $workflow.Items) {
                                    if (($item.AgentID -eq $obj.ID) -and ($item.ConstructType -as [BPAConstructType]) -in @("Condition","Process","Task") -and (($item.TriggerType -as [BPATriggerType]) -ne [BPATriggerType]::Schedule)) {
                                        $result += $workflow
                                        break workflowloop
                                    }
                                }
                                foreach ($trigger in $workflow.Triggers) {
                                    if (($trigger.AgentID -eq $obj.ID) -and (($trigger.TriggerType -as [BPATriggerType]) -ne [BPATriggerType]::Schedule)) {
                                        $result += $workflow
                                        break workflowloop
                                    }
                                }
                            }
                        }
                        default {
                            $unsupportedType = $obj.GetType().FullName
                            if ($_) { 
                                $unsupportedType = $_ 
                            } elseif (($null -ne $obj.Type) -and ($obj.Type -ne "")) {
                                $unsupportedType = $obj.Type
                            }
                            Write-Error -Message "Unsupported input type '$unsupportedType' encountered!" -TargetObject $obj
                        }
                    }
                }
            }
        }
    }

    END {
        $SortProperty += "BPAServer", "ID"
        return $result | Sort-Object $SortProperty -Unique -Descending:$SortDescending.ToBool()
    }
}