Scripts/Add-BPAWorkflowLink.ps1

function Add-BPAWorkflowLink {
    <#
        .SYNOPSIS
            Adds a link between two objects in a BPA workflow
 
        .DESCRIPTION
            Add-BPAWorkflowLink can add a link between two objects in a BPA workflow
 
        .PARAMETER InputObject
            The workflow to add the link to.
 
        .PARAMETER SourceItem
            The source object for the link. Object can only exist once in the workflow.
 
        .PARAMETER DestinationItem
            The destination object for the link. Object can only exist once in the workflow.
 
        .PARAMETER Type
            The type of link to add.
 
        .PARAMETER ResultType
            If a Result link type is used, the type of result (true/false/default/value).
 
        .PARAMETER Value
            If a Value result type is used, the value to set.
 
        .INPUTS
            The following BPA object types can be modified by this function:
            Workflow
 
        .EXAMPLE
            # Add a link between "Copy Files" and "Move Files"
            Get-BPAWorkflow "FTP Files" | Add-BPAWorkflowLink -SourceItem (Get-BPATask "Copy Files") -DestinationItem (Get-BPATask "Move Files")
 
        .NOTES
            Author(s): : David Seibel
            Contributor(s) :
            Date Created : 02/01/2018
            Date Modified : 02/08/2018
 
        .LINK
            https://github.com/davidseibel/PoshBPA
    #>

    [CmdletBinding(SupportsShouldProcess=$true,ConfirmImpact='Medium')]
    param(
        [Parameter(Mandatory = $true, ValueFromPipeline = $true)]
        $InputObject,

        [Parameter(Mandatory = $true)]
        $SourceItem,

        [Parameter(Mandatory = $true)]
        $DestinationItem,

        [BPALinkType]$Type = [BPALinkType]::Success,

        [BPALinkResultType]$ResultType = [BPALinkResultType]::Default,

        $Value = ""
    )

    BEGIN {
        if ($SourceItem.BPAServer -ne $DestinationItem.BPAServer) {
            throw "SourceItem and DestinationItem are not on the same BPA server!"
        }
        # Don't set ResultType and Value unless the appropriate parameters are supplied
        if ($Type -ne [BPALinkType]::Result) {
            $ResultType = [BPALinkResultType]::Default
            $Value = ""
        } elseif ($ResultType -ne [BPALinkResultType]::Value) {
            $Value = ""
        }
    }

    PROCESS {
        :workflowloop foreach ($obj in $InputObject) {
            if ($obj.TypeName -eq "Workflow") {
                if ($obj.BPAServer -ne $SourceItem.BPAServer) {
                    Write-Warning "SourceItem '$($SourceItem.Name)' ($($SourceItem.BPAServer)) is not on the same server as '$($obj.Name)' ($($obj.BPAServer))!"
                    continue workflowloop
                }
                if ($obj.BPAServer -ne $DestinationItem.BPAServer) {
                    Write-Warning "DestinationItem '$($DestinationItem.Name)' ($($DestinationItem.BPAServer)) is not on the same server as '$($obj.Name)' ($($obj.BPAServer))!"
                    continue workflowloop
                }
                $updateObject = Get-BPAWorkflow -ID $obj.ID -BPAServer $obj.BPAServer
                $source = @()
                $source += $updateObject.Items | Where-Object {$_.ConstructID -eq $SourceItem.ID}
                $source += $updateObject.Triggers | Where-Object {$_.ConstructID -eq $SourceItem.ID}
                $destination = @()
                $destination += $updateObject.Items | Where-Object {$_.ConstructID -eq $DestinationItem.ID}
                $destination += $updateObject.Triggers | Where-Object {$_.ConstructID -eq $DestinationItem.ID}
                if ($source.Count -gt 1) {
                    Write-Warning "Found more than one instance of SourceItem '$($SourceItem.Name)' in workflow '$($updateObject.Name)'!"
                    continue workflowloop
                } elseif ($source.Count -eq 0) {
                    Write-Warning "Found no instances of SourceItem '$($SourceItem.Name)' in workflow '$($updateObject.Name)'!"
                    continue workflowloop
                }
                if ($destination.Count -gt 1) {
                    Write-Warning "Found more than one instance of DestinationItem '$($DestinationItem.Name)' in workflow '$($updateObject.Name)'!"
                    continue workflowloop
                } elseif ($destination.Count -eq 0) {
                    Write-Warning "Found no instances of DestinationItem '$($DestinationItem.Name)' in workflow '$($updateObject.Name)'!"
                    continue workflowloop
                }
                foreach ($link in $updateObject.Links) {
                    if (($link.SourceID -eq $source.ID) -and ($link.DestinationID -eq $destination.ID)) {
                        Write-Warning "Workflow $($obj.Name) already has a link between '$($SourceItem.Name)' and '$($DestinationItem.Name)'!"
                        continue workflowloop
                    }
                }

                # Get the template object from the PoshBPA\ObjectTemplates folder, and configure the object
                $link = Get-BPAObjectTemplate -Type "WorkflowLink" -BPAServer $obj.BPAServer
                $link.ID                 = "{$((New-Guid).Guid)}"
                $link.ParentID           = $updateObject.ID
                $link.DestinationID      = $destination.ID
                $link.DestinationPoint.X = $destination.X
                $link.DestinationPoint.Y = $destination.Y
                $link.LinkType           = $Type.value__
                $link.ResultType         = $ResultType.value__
                $link.SourceID           = $source.ID
                $link.SourcePoint.X      = $source.X
                $link.SourcePoint.Y      = $source.Y
                $link.Value              = $Value
                $link.WorkflowID         = $updateObject.ID
                if ($updateObject.Links.Count -gt 0) {
                    $updateObject.Links += $link
                } else {
                    $updateObject.Links = @($link)
                }
                Set-BPAWorkflow -Instance $updateObject
            } else {
                Write-Error -Message "Unsupported input type '$($obj.TypeName)' encountered!" -TargetObject $obj
            }
        }
    }
}