Private/PowerAutomateFlows.ps1
function Invoke-FlowAction { Param( [Microsoft.Xrm.Tooling.Connector.CrmServiceClient] $CRMConn, [bool] [Parameter(Mandatory = $true)] $AnyImportSuccessful, [bool] [Parameter(Mandatory = $true)] $AlwaysTryActivate, [bool] [Parameter(Mandatory = $true)] $FailonError, [string] [Parameter(Mandatory = $true)] $SolutionName, [string] [Parameter(Mandatory = $true)] $SolutionFolder, [string] [Parameter(Mandatory = $true)] $PipelinePath, [bool] [Parameter(Mandatory = $false)] $RunLocally = $false, [System.Collections.Hashtable] [Parameter(Mandatory = $true)] $Deploy ) if ($AnyImportSuccessful -or $AlwaysTryActivate -eq $true) { Write-Host "Activating Power Automate flows" -ForegroundColor Green $ProgressPreference = "SilentlyContinue" # Activate Flows and Establish Connection References Write-Host "Getting Environment Id" $orgs = Get-CrmRecords -conn $CRMConn -EntityLogicalName organization -TopCount 1 -Fields "organizationid" if ($orgs.Count -gt 0) { $orgId = $orgs.CrmRecords[0].organizationid $Environment = Get-AdminPowerAppEnvironment | Where-Object OrganizationId -eq $orgId.Guid if ($null -eq $Environment) { $PermissionsErrorMessage = "To use this function, the service principal needs registered as a Management Application in Azure. You can do so when running PPDO locally." if ($FailonError -eq $true) { Write-PPDOMessage -Message $PermissionsErrorMessage -Type error -RunLocally $RunLocally -LogError $true } else { Write-PPDOMessage -Message $PermissionsErrorMessage -Type warning -RunLocally $RunLocally -LogWarning $true } } $EnvId = $Environment.EnvironmentName Write-Host "Environment Id - $EnvId" if ($Deploy.ConnectionReferences.SetConnections -eq $true) { Invoke-SetConnectionReferences -CRMConn $CRMConn -SolutionName $SolutionName -EnvId $EnvId -FailOnError $Deploy.ConnectionReferences.FailOnError -RunLocally $RunLocally } else { Write-PPDOMessage -Message "Skipping setting Connection References per configuration in deployPackages.json" -type "warning" -LogWarning $true -RunLocally $RunLocally } Invoke-FlowActivation -CRMConn $CRMConn -PipelinePath $PipelinePath -RunLocally $RunLocally -Deploy $Deploy -SolutionFolder $SolutionFolder -EnvId $EnvId -SolutionName $SolutionName } else { $NoOrganizationsError = "There are no organization records in CRM, unable to set Connection References or activate flows." if ($FailonError -eq $true) { Write-PPDOMessage -Message $NoOrganizationsError -Type error -RunLocally $RunLocally -LogError $true } else { Write-PPDOMessage -Message $NoOrganizationsError -Type warning -RunLocally $RunLocally -LogWarning $true } } } } function Invoke-FlowActivation { Param( [Microsoft.Xrm.Tooling.Connector.CrmServiceClient] [Parameter(Mandatory = $true)] $CRMConn, [string] [Parameter(Mandatory = $true)] $PipelinePath, [string] [Parameter(Mandatory = $true)] $SolutionFolder, [bool] [Parameter(Mandatory = $false)] $RunLocally = $false, [System.Collections.Hashtable] [Parameter(Mandatory = $true)] $Deploy, [string] [Parameter(Mandatory = $true)] $EnvId, [string] [Parameter(Mandatory = $true)] $SolutionName ) function Invoke-Activate { Param( [Microsoft.Xrm.Tooling.Connector.CrmServiceClient] [Parameter(Mandatory = $true)] $CRMConn, [System.Object] [Parameter(Mandatory = $true)] $FlowsToActivate, [ref] [Parameter(Mandatory = $true)] $ErrorCount, [switch] $CatchChildFlowActivationErrors ) $FlowsToRetry = @() $FlowsToActivate | ForEach-Object { $FlowStore = $_ try { $workflow = Get-CrmRecord -conn $CRMConn -EntityLogicalName "workflow" -Id $_.FlowId -Fields "statecode", "name" if ($workflow.statecode -ne "Activated") { Write-Host "Workflow status is $($workflow.statecode), attempting to activate flow." $activationConnection = $CRMConn if ($_.ActivateAsUser) { Write-Host "ActivateAsUser defined and set to: $($_.ActivateAsUser), attempting to activate flow as this user" $systemuserResult = Get-CrmRecords -conn $CRMConn -EntityLogicalName "systemuser" -FilterAttribute "domainname" -FilterOperator "eq" -FilterValue $_.ActivateAsUser -TopCount 1 -Fields "systemuserid" if ($systemuserResult.Count -gt 0) { $activationConnection.OrganizationWebProxyClient.CallerId = $systemuserResult.CrmRecords[0].systemuserid } else { Write-PPDOMessage -Message "$($_.Exception.Message)" -Type "error" -RunLocally $RunLocally Throw "User $($_.ActivateAsUser) was not found in $($Deploy.EnvironmentName), unable to impersonate them to activate flow $($workflow.name)" } } Write-PPDOMessage "Enabling Flow '$($workflow.name)'" -Type command -RunLocally $RunLocally try { Set-CrmRecordState -conn $activationConnection -EntityLogicalName "workflow" -Id $_.FlowId -StateCode "Activated" -StatusCode "Activated" Write-Host "...Activated" -ForegroundColor Green } catch { if ($_.ToString().Contains("ChildFlowNeverPublished") -and $CatchChildFlowActivationErrors) { $FlowsToRetry += $FlowStore } else { Throw $_ } } } } catch { Write-PPDOMessage "$($_.Exception.Message)" -Type "error" -RunLocally $RunLocally $ErrorCount.Value++ } } return $FlowsToRetry } Write-Host "Checking if there are Flows that need to be activated" if ($Deploy.Flows.ActivateFlows -ne $true) { Write-PPDOMessage -Message "Skipping flow activation, per 'ActivateFlows' flag being false in deployPackages.json" -RunLocally $RunLocally return } # Use Override File if it is set if ($Deploy.Flows.OverrideFile) { $FlowsJSONFilePath = "$PipelinePath\$SolutionFolder\$($Deploy.Flows.OverrideFile)" } else { $FlowsJSONFilePath = "$PipelinePath\$SolutionFolder\Flows_Default.json" } Write-PPDOMessage -Message "Using list of flows to activate at location '$FlowsJSONFilePath'" -RunLocally $RunLocally # Get list of flows to activate from JSON try { $FlowsToActivate = Get-Content -Path $FlowsJSONFilePath | ConvertFrom-Json } catch { Write-PPDOMessage -Message "$($_.Exception.Message)" -Type "error" -LogError $true -RunLocally $RunLocally Throw "An error occurred when trying to get list of flows to activate at location '$FlowsJSONFilePath'." } Write-PPDOMessage -Message "There are $($FlowsToActivate.Count) Flows to activate." -RunLocally $RunLocally if ($FlowsToActivate.Count -le 0) { return } $ErrorCount = 0 $FlowsToRetry = Invoke-Activate -CRMConn $CRMConn -ErrorCount ([ref]$ErrorCount) -FlowsToActivate $FlowsToActivate -CatchChildFlowActivationErrors if ($FlowsToRetry.Count -gt 0) { Invoke-Activate -CRMConn $CRMConn -ErrorCount ([ref]$ErrorCount) -FlowsToActivate $FlowsToRetry } if ($Deploy.Flows.FailOnError -eq $true -and $ErrorCount -gt 0) { Write-PPDOMessage "There were $ErrorCount Flow activation errors and FailOnError is set to True... exiting." -Type error -RunLocally $RunLocally -LogError $true exit 1 } } |