Private/ConnectionReferences.ps1

function Invoke-SetConnectionReferences {
    Param(
        [System.Object] $CRMConn,
        [string] [Parameter(Mandatory = $true)] $SolutionName,
        [bool] [Parameter(Mandatory = $true)] $FailOnError,
        [bool] [Parameter(Mandatory = $false)] $RunLocally = $false,
        [string] [Parameter(Mandatory = $true)] [AllowEmptyString()] $EnvironmentURL
    )

    try {
        Write-PPDOMessage -Message "Checking for Connections References in $SolutionName" -RunLocally $RunLocally
        $solutionId = (Get-CrmRecords -conn $CRMConn -EntityLogicalName "solution" -FilterAttribute "uniquename" -FilterOperator "eq" -FilterValue $SolutionName -Fields "solutionid" -TopCount 1).CrmRecords[0].solutionid
        $connRefs = (Get-CrmRecords -conn $CRMConn -EntityLogicalName "connectionreference" -FilterAttribute "solutionid" -FilterOperator "eq" -FilterValue $solutionid -Fields "connectionreferencelogicalname", "connectionid", "connectorid", "connectionreferenceid").CrmRecords
        Write-PPDOMessage "$($connRefs.Count) Connection Reference(s) found."
        
        # Stop if there are no Connection References
        if ($connRefs.Count -eq 0) {
            return
        }

        if ([string]::IsNullOrWhiteSpace($EnvironmentURL)) {
            Throw "EnvironmentURL is missing from the selected environment in Environments.json."
        }

        $pacOutput = Invoke-PPDOExternalCommand -FilePath (Get-PPDOPacPath) -Arguments @('connection', 'list', '--environment', $EnvironmentURL) -ThrowOnError
        $headerFound = $false
        $connections = @(
            foreach ($line in $pacOutput) {
                if ($line -match '^\s*Id\s+Name\s+API Id\s+Status\s*$') {
                    $headerFound = $true
                    continue
                }
                if (-not $headerFound -or [string]::IsNullOrWhiteSpace($line)) {
                    continue
                }
                # Display names can contain spaces; the API path delimits the last two columns.
                if ($line -notmatch '^\s*(?<ConnectionName>\S+)\s+(?<DisplayName>.*?)\s*(?<ConnectorId>/providers/Microsoft.PowerApps/apis/\S+)\s+(?<Status>.+?)\s*$') {
                    Throw "Unable to parse pac connection list row: $line"
                }
                [pscustomobject]@{
                    ConnectionName = $Matches.ConnectionName
                    DisplayName    = $Matches.DisplayName.Trim()
                    ConnectorId    = $Matches.ConnectorId
                    Status         = $Matches.Status
                }
            }
        )
        if (-not $headerFound) {
            Throw "Unable to find the expected Id, Name, API Id and Status columns in pac connection list output."
        }

        foreach ($connReference in $connRefs) {
            try {
                $connectionType = $connReference.connectorid.Replace("/providers/Microsoft.PowerApps/apis/", "")
                Write-PPDOMessage -Message "Found Connection Reference $($connReference.connectionreferencelogicalname), searching for related Connection" -RunLocally $RunLocally

                $connection = $connections | Where-Object { (($_.Status -split ',\s*') -contains "Connected") -and ($_.ConnectorId -eq $connReference.connectorid) } | Select-Object -First 1

                if (!$connection) {
                    Throw "Unable to find a Connection in this environment of type $connectionType."
                }
                Write-PPDOMessage -Message "Found Connection: $connection" -RunLocally $RunLocally
                
                Write-PPDOMessage -Message "Setting Connection Reference to use $($connection.DisplayName)" -Type "command" -RunLocally $RunLocally
                Set-CrmRecord -conn $CRMConn -EntityLogicalName "connectionreference" -Id $connReference.connectionreferenceid -Fields @{"connectionid" = $connection.ConnectionName }
            }
            catch {
                Write-PPDOMessage -Message $_ -type "error" -RunLocally $RunLocally
                $message = "An error occurred for Connection Reference $($connReference.connectionreferencelogicalname)."
                if ($FailOnError) {
                    Throw $message
                }
                else {
                    Write-PPDOMessage -Message $message -type "warning" -LogWarning $true -RunLocally $RunLocally
                }
            }
        }
    }
    catch {
        if ($FailOnError) {
            Throw $_
        }
        else {
            Write-PPDOMessage -Message $_ -type "warning" -LogWarning $true -RunLocally $RunLocally
        }
    }
}