Power Automate: Adding run-only users to a Flow with Flow

One of my previous posts was about listing a user’s Resource Assignments using Power Automate. As the Flow in question is a “personal productivity Flow” that needs to be fired off in a user’s context, a challenge I faced was distributing the Flow to the masses. Well… in my case there’s only me in my tenant and test environment but you get the picture if you have 100 not to mention 1000 people to share a Flow with. So how can we easily make a user in an environment a run-only user for a Flow? Read on to find out.

To learn more about run-only users, I encourage you to read this blog post by MVP Kent Weare. In short, run-only users can be added to a Flow with a manual trigger. Those users can run Flows they’re added to as run-only users but they can’t edit the Flows.

Adding run-only users with Flow

The Flow that I’m describing on this blog post is what I call an “admin Flow”: It’s a Flow that’s only shared with admins. Normal users should have no use or need for the Flow. I’ve included the Flow in a solution so that the CDS current environment connector can be used and so that I can easily transport the Flow from one environment to another as part of ALM. Let’s dissect the Flow:

As run-only users are added on-demand, the Flow naturally has a manual trigger. Adding run-only users is done per Flow so the trigger’s input asks for a Flow’s id (GUID). If a value isn’t given, the Flow will terminate as cancelled. The list records action lists all users (systemuser) in an environment. As my domain contains anttipajunen, I’ve used a filter query to narrow down the results:

  • User Name must include my domain anttipajunen.
  • Access Mode must be Read Write. This will rule out integration users, application users and administrative users.
  • Primary Email must include my domain anttipajunen.
Initial steps.

If your environment has a large number of users, it’s a good idea to use pagination for the list records action. This way the action will list all your users. Pagination can be turned on and off as you please and the threshold can be changed based on your needs.


The apply to each loop starts with a condition. I wasn’t successful in filtering the status (isdisabled) of a user in the filter query of the list records action so a condition will check that only active users are added to the Flow. As the status field is isdisabled, the condition checks if a record’s status is equal to false.

If there are hundreds (not to mention thousands) of users, running the Flow can take a while. To make it run faster, Concurrency Control can used for the apply to each loop. As the loop contains fairly simple actions, I’ve taken a bold approach and have turned the degree of parallelism all the way to the max. I recommend you do some testing in your environment before cranking it up all the way.

Concurrency Control for the apply to each loop.

Azure AD Object Id is stored in a compose action for use in upcoming actions. I’ve included a few extra compose actions in case the Flow is extended. As the owners of the Flow are not added as run-only users, a List Flow Owners action is used. A Select action is used to pick values for principal. It will get us the id (GUID) of a user. The output of the select action is an array. To use the output in a condition, a join action converts the array into a string.

Next, a condition checks if the composed Azure AD Object Id is included in the string output of the join action. If it is, the loop in question is for the Flow’s owner. If the output of join doesn’t contain the Azure AD Object Id from the compose, then the the user in question will be added as a run-only user.

Apply to each loop.

The final actions require a small trick. For some reason the Modify Run-Only Users action throws a fit and completely loses all its values, if the Add User field doesn’t have a dynamic value for a compose action’s output. Not a huge problem; all we need is a compose action then. The JSON that needs to be composed should contain the output of the compose action for Azure AD Object Id. The JSON is as follows:

    "properties": {
      "principal": {
        "id": @{outputs('Compose_azureactivedirectoryobjectid')},
        "type": "User"

The composed JSON can now be used in the final action, which adds a user to the Flow as a run-only user. That’s it folk! Happy distributing! This small, simple but powerful Flow should make adding run-only users for your manual trigger Flows a lot easier.

Adding a user to a Flow as a run-only user.
All my blog posts reflect my personal opinions and findings unless otherwise stated.

Leave a Reply

Your email address will not be published. Required fields are marked *