Skip to content

Month: October 2021

Bulk active Flows from a solution

Posted in Power Automation, Dynamics 365, and Power Platform

Scenario

We start our projects with our best practice solution and add further value over time to that solution. We also try to let benefit existing customers from the innovations and optimizations that get implemented in the solution over time, since their project has started.
Knowing our goal, you can imagine our setup. A source instance in our tenant and several target instances at different customers.
On top, some customers receive manual, an unmanaged version of the solution and other customers receive a managed version with an Azure Pipeline.

Issue

Flows can only be turned on if the user turning them on has permissions to connections being referenced by the connection reference.

Marc Schweigert: https://gist.github.com/devkeydet/f31554566b2e53ddd8e7e1db4af555a6

This causes no issues when importing manually, but as we use Application User to connect the Azure Pipeline, this ends with all Flows in the solution turned off after solution import.

Solution – Bulk active Flows

One solution would be to create a PowerShell script in the Azure Pipeline that impersonate the owner of a connection reference (Source).
I decided to create a Power Automated based solution to bulk active Flows, with an Environment Variable that contains Flows that should not be enabled automatically.

Step by step

Step 1 – Environment Variable:
Create an Environment Variable of type JSON to store the Flows that should not be activated automatically. Doing this as an Environment Variable enables you to define this per instance.

To enable our Flow to find the right Flows by name, workflowid or workflowuniqueid, the structure should be:

{
  "Flow 1": "worklowid",
  "Flow 2": "workflowidunique"
}

Step 2: The Trigger of the Flow

A managed solution only get modified when you import an update of it. Therefore, this is my trigger, filtered on my solution.

The dataverse flow trigger on table 'Solutions'.

Step 3: Some vars and const

Vars and const for the Flow.

Step 4: Get the exclusion list

I needed to put it in a compose action. Working directly with the environment variable did not work for me.

Load the exclusion list in a compose.

Step 5: Get inactive Flows from the solution

Get the inactive Flows from the solution with a fetch to bulk active flows later.

I found the FetchXml in the Dynamics Community, it was an answer from Scott Durow where he helped someone. By that way, thank you, Scott, that inspired me to my solution.

<fetch>
  <entity name="workflow">
    <attribute name="category" />
    <attribute name="name" />
    <attribute name="statecode" />
    <attribute name="workflowidunique" />
    <filter>
      <condition attribute="category" operator="eq" value="5" />
      <condition attribute="statecode" operator="eq" value="0" />
    </filter>
    <link-entity name="solutioncomponent" from="objectid" to="workflowid">
      <link-entity name="solution" from="solutionid" to="solutionid">
        <filter>
          <condition attribute="uniquename" operator="eq" value=@{outputs('Solution')} />
        </filter>
      </link-entity>
    </link-entity>
  </entity>
</fetch>

Step 6: Loop over fetched Flows

Loop to bulk active Flows.

Step 6.1 Check inside the loop if the current Flow is not excluded

Condition to excluded flows from the environment variable.
contains(string(outputs('Get_ExclusionList')), string(items('Loop_fetched_Processes_from_Solution')?['workflowid']))


contains(string(outputs('Get_ExclusionList')), string(items('Loop_fetched_Processes_from_Solution')?['workflowidunique']))


contains(string(outputs('Get_ExclusionList')), string(items('Loop_fetched_Processes_from_Solution')?['name']))

Step 6.1.1 Activate the current Flow in the TRUE path of the condition

Update the record in Dataverse to activate the flow.

Step 6.1.2 Log if an error happens after activating the current Flow

A counter and string for error logging.

Click the three dots on the “Counter++” action and choose “Configure run after”.

Open the 'run after' menu.
Configure the 'run after' option.

Step 7: Check if an error occurred, after the loop is completed

Condition to inform about errors.

Step 7.1 If an error occurred, get the URL of the CRM instance

Get the CRM URL from OData.Id.

I described how to get it in my post: Get CRM URL in Power Automate

Step 7.2 Send a notification

Send an email with Power Automate.

Let me a comment if you find this helpful or how you solved this or a similar problem.