Private/ActivateFlows.ps1
function Invoke-FlowActivation { Param( [Microsoft.Xrm.Tooling.Connector.CrmServiceClient] $CRMConn, [string] [Parameter(Mandatory = $true)] $PipelinePath, [bool] [Parameter(Mandatory = $false)] $RunLocally = $false ) Write-Host "Checking if there are Flows that need to be activated" if ($Deploy.Flows.ActivateFlows -eq $true) { if ($Deploy.Flows.OverrideFile) { Write-Host "Using $($Deploy.Flows.OverrideFile) for Flow activation" try { $FlowsToActivate = Get-Content -Path $PipelinePath\$SolutionFolder\$($Deploy.Flows.OverrideFile) -ErrorAction SilentlyContinue | ConvertFrom-Json } catch { Write-PPDOMessage "$($_.Exception.Message)" -Type error -RunLocally $RunLocally } } else { Write-Host "Using Flows_Default.json for Flow activation" try { $FlowsToActivate = Get-Content -Path $PipelinePath\$SolutionFolder\Flows_Default.json -ErrorAction SilentlyContinue | ConvertFrom-Json } catch { $FlowsToActivate = $null } } Write-Host "There are $($FlowsToActivate.Count) Flows that need activating" $ErrorCount = 0 if ($FlowsToActivate.Count -gt 0) { $FlowsToActivate | ForEach-Object { $FlowStore = $_ try { $workflow = Get-CrmRecord -conn $CRMConn -EntityLogicalName workflow -Id $_.FlowId -Fields clientdata, category, statecode, name if ($_.ActivateAsUser) { Write-Host "ActivateAsUser defined and set to: $($_.ActivateAsUser), attempting to Active Flow as this user" $systemuserResult = Get-CrmRecords -conn $CRMConn -EntityLogicalName systemuser -FilterAttribute "domainname" -FilterOperator "eq" -FilterValue $_.ActivateAsUser if ($systemuserResult.Count -gt 0) { $systemUserId = $systemuserResult.CrmRecords[0].systemuserid # Activate the workflow using the owner if ($workflow.statecode -ne "Activated") { $impersonationConn = $CRMConn $impersonationCallerId = $systemUserId $impersonationConn.OrganizationWebProxyClient.CallerId = $impersonationCallerId Write-PPDOMessage "Enabling Flow '$($workflow.name)'" -Type command -RunLocally $RunLocally try { Set-CrmRecordState -conn $impersonationConn -EntityLogicalName workflow -Id $_.FlowId -StateCode Activated -StatusCode Activated } catch { Write-PPDOMessage "There was an error activating the Flow, please confirm that the user exists and that the appropriate connections have been created as this user in the Environment" -Type warning -RunLocally $RunLocally -LogWarning $true Write-Host $_ if ($_.ToString().Contains("ChildFlowNeverPublished")) { $FlowsToRetry += $FlowStore } else { $ErrorCount++ } } } } Write-PPDOMessage "User $($_.ActivateAsUser) was not found in $($Deploy.EnvironmentName)" -Type warning -RunLocally $RunLocally -LogWarning $true } else { Write-Host "Checking if '$($workflow.name)' needs Activating..." $solutions = Get-CrmRecords -conn $CRMConn -EntityLogicalName solution -FilterAttribute "uniquename" -FilterOperator "eq" -FilterValue "$($package.SolutionName)" $solutionId = $solutions.CrmRecords[0].solutionid $connRefs = (Get-CrmRecords -conn $CRMConn -EntityLogicalName connectionreference -FilterAttribute "solutionid" -FilterOperator eq -FilterValue $solutionid -Fields connectionreferencelogicalname, connectionid, connectorid, connectionreferenceid).CrmRecords $connRefToUse = $connRefs | Where-Object { $null -ne $_.connectionid } | Select-Object -First 1 -ErrorAction SilentlyContinue if ($null -ne $connRefToUse) { Write-Host "---- Connection Ref Details ----" Write-Host "Connection ID : " $connRefToUse.ConnectionId Write-Host $connRefToUse Write-Host "--------------------------------" $connection = Get-AdminPowerAppConnection -EnvironmentName $EnvId -Filter $connRefToUse.ConnectionId } else { Write-PPDOMessage "There was an error getting a Connection to use, please confirm that the user exists and that the appropriate connections have been created as this user in the Environment" -Type warning -RunLocally $RunLocally -LogWarning $true $ErrorCount++ } # Get Dataverse systemuserid for the system user that maps to the aad user guid that created the connection if ($null -ne $connection) { Write-Host "---- Connection Details -----" Write-Host "Connection UserID : " $connection[0].CreatedBy.id Write-Host $connection[0] Write-Host "-----------------------------" $systemusers = Get-CrmRecords -conn $CRMConn -EntityLogicalName systemuser -FilterAttribute "azureactivedirectoryobjectid" -FilterOperator "eq" -FilterValue $connection[0].CreatedBy.id } else { Write-PPDOMessage "There was an error getting the owner of the Connection to use, please confirm that the user exists and that the appropriate connections have been created as this user in the Environment" -Type warning -RunLocally $RunLocally -LogWarning $true $ErrorCount++ } if ($systemusers.Count -gt 0) { # Impersonate the Dataverse systemuser that created the connection when updating the connection reference $impersonationCallerId = $systemusers.CrmRecords[0].systemuserid if ($workflow.statecode -ne "Activated") { Write-PPDOMessage "Enabling Flow '$($workflow.name)' as Owner of Connection Reference" -Type command -RunLocally $RunLocally $impersonationConn = $CRMConn $impersonationConn.OrganizationWebProxyClient.CallerId = $impersonationCallerId try { Set-CrmRecordState -conn $impersonationConn -EntityLogicalName workflow -Id $_.FlowId -StateCode Activated -StatusCode Activated Write-Host "...Activated" -ForegroundColor Green } catch { Write-PPDOMessage "There was an error activating the Flow, please confirm that the user exists and that the appropriate connections have been created as this user in the Environment" -Type warning -RunLocally $RunLocally -LogWarning $true Write-Host $_ if ($_.ToString().Contains("ChildFlowNeverPublished")) { $FlowsToRetry += $FlowStore } else { $ErrorCount++ } } } } } } catch { # Catch in case the Get-CrmRecord returns null exception Write-PPDOMessage "$($_.Exception.Message)" -Type error -RunLocally $RunLocally } } } ########################## - Retry Flow $FlowsToRetry | ForEach-Object { Write-Host Write-Host "Retrying Flows that failed due to Child Flows" -ForegroundColor Green $workflow = Get-CrmRecord -conn $CRMConn -EntityLogicalName workflow -Id $_.FlowId -Fields clientdata, category, statecode, name if ($_.ActivateAsUser) { Write-Host "ActivateAsUser defined and set to : $($_.ActivateAsUser), attempting to Active Flow as this user" $systemuserResult = Get-CrmRecords -conn $CRMConn -EntityLogicalName systemuser -FilterAttribute "domainname" -FilterOperator "eq" -FilterValue $_.ActivateAsUser if ($systemuserResult.Count -gt 0) { $systemUserId = $systemuserResult.CrmRecords[0].systemuserid #Activate the workflow using the owner. if ($workflow.statecode -ne "Activated") { $impersonationConn = $CRMConn $impersonationCallerId = $systemUserId $impersonationConn.OrganizationWebProxyClient.CallerId = $impersonationCallerId Write-PPDOMessage "Enabling Flow '$($workflow.name)'" -Type command -RunLocally $RunLocally try { Set-CrmRecordState -conn $impersonationConn -EntityLogicalName workflow -Id $_.FlowId -StateCode Activated -StatusCode Activated } catch { Write-PPDOMessage "There was an error activating the Flow, please confirm that the user exists and that the appropriate connections have been created as this user in the Environment" -Type warning -RunLocally $RunLocally -LogWarning $true Write-Host $_ $ErrorCount++ } } } Write-PPDOMessage "User $($_.ActivateAsUser) was not found in $($Deploy.EnvironmentName)" -Type warning -RunLocally $RunLocally -LogWarning $true } else { Write-Host "Checking if '$($workflow.name)' needs Activating..." $solutions = Get-CrmRecords -conn $CRMConn -EntityLogicalName solution -FilterAttribute "uniquename" -FilterOperator "eq" -FilterValue "$($package.SolutionName)" $solutionId = $solutions.CrmRecords[0].solutionid $connRefs = (Get-CrmRecords -conn $CRMConn -EntityLogicalName connectionreference -FilterAttribute "solutionid" -FilterOperator eq -FilterValue $solutionid -Fields connectionreferencelogicalname, connectionid, connectorid, connectionreferenceid).CrmRecords $connRefToUse = $connRefs | Where-Object { $null -ne $_.connectionid } | Select-Object -First 1 -ErrorAction SilentlyContinue $connection = Get-AdminPowerAppConnection -EnvironmentName $EnvId -Filter $connRefToUse.ConnectionId # Get Dataverse systemuserid for the system user that maps to the aad user guid that created the connection $systemusers = Get-CrmRecords -conn $CRMConn -EntityLogicalName systemuser -FilterAttribute "azureactivedirectoryobjectid" -FilterOperator "eq" -FilterValue $connection[0].CreatedBy.id if ($systemusers.Count -gt 0) { # Impersonate the Dataverse systemuser that created the connection when updating the connection reference $impersonationCallerId = $systemusers.CrmRecords[0].systemuserid if ($workflow.statecode -ne "Activated") { Write-PPDOMessage "Enabling Flow '$($workflow.name)' as Owner of Connection Reference" -Type command -RunLocally $RunLocally $impersonationConn = $CRMConn $impersonationConn.OrganizationWebProxyClient.CallerId = $impersonationCallerId try { Set-CrmRecordState -conn $impersonationConn -EntityLogicalName workflow -Id $_.FlowId -StateCode Activated -StatusCode Activated } catch { Write-PPDOMessage "There was an error activating the Flow, please confirm that the user exists and that the appropriate connections have been created as this user in the Environment" -Type warning -RunLocally $RunLocally -LogWarning $true Write-Host $_ $ErrorCount++ } } } } } 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 } } else { Write-Host "No Flows were specified for activation. If you wish to include flows for activation, please add the following in deployPackages.json ""Flows"": { ""ActivateFlows"": ""true"", ""OverrideFile"" : """", ""FailOnError"" : ""false"" }" } } |