<?xml version="1.0" encoding="UTF-8"?>
<rss xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/"
    xmlns:atom="http://www.w3.org/2005/Atom" xmlns:media="http://search.yahoo.com/mrss/" version="2.0">
    <channel>
        
        <title>
            <![CDATA[ Power Apps - freeCodeCamp.org ]]>
        </title>
        <description>
            <![CDATA[ Browse thousands of programming tutorials written by experts. Learn Web Development, Data Science, DevOps, Security, and get developer career advice. ]]>
        </description>
        <link>https://www.freecodecamp.org/news/</link>
        <image>
            <url>https://cdn.freecodecamp.org/universal/favicons/favicon.png</url>
            <title>
                <![CDATA[ Power Apps - freeCodeCamp.org ]]>
            </title>
            <link>https://www.freecodecamp.org/news/</link>
        </image>
        <generator>Eleventy</generator>
        <lastBuildDate>Sun, 17 May 2026 19:48:53 +0000</lastBuildDate>
        <atom:link href="https://www.freecodecamp.org/news/tag/power-apps/rss.xml" rel="self" type="application/rss+xml" />
        <ttl>60</ttl>
        
            <item>
                <title>
                    <![CDATA[ How to Assign Dataverse Security Roles at Scale ]]>
                </title>
                <description>
                    <![CDATA[ Assigning Dataverse security roles manually works pretty well – until it doesn't. Whether you are onboarding 50 new hires or rolling out access to a new app, managing roles by hand can be tedious and  ]]>
                </description>
                <link>https://www.freecodecamp.org/news/how-to-assign-dataverse-security-roles-at-scale/</link>
                <guid isPermaLink="false">68557b4d4b011b57124c6b6b</guid>
                
                    <category>
                        <![CDATA[ Power Apps ]]>
                    </category>
                
                    <category>
                        <![CDATA[ Dataverse ]]>
                    </category>
                
                    <category>
                        <![CDATA[ power-automate ]]>
                    </category>
                
                    <category>
                        <![CDATA[ C# ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ Brandon Wozniewicz ]]>
                </dc:creator>
                <pubDate>Fri, 20 Jun 2025 15:16:29 +0000</pubDate>
                <media:content url="https://cdn.hashnode.com/res/hashnode/image/upload/v1750432574148/b3cfaebe-7566-4795-b00e-5da9d65dd8f4.png" medium="image" />
                <content:encoded>
                    <![CDATA[ <p>Assigning Dataverse security roles manually works pretty well – until it doesn't.</p>
<p>Whether you are onboarding 50 new hires or rolling out access to a new app, managing roles by hand can be tedious and error-prone.</p>
<p>In this article, you will learn about three scalable ways to assign security roles across multiple users or teams, with low-code and pro-code options.</p>
<h3 id="heading-table-of-contents">Table of Contents</h3>
<ol>
<li><p><a href="#heading-aside-teams">Aside: Teams</a></p>
</li>
<li><p><a href="#heading-canvas-apps-relate-unrelate-functions">Canvas Apps Relate / Unrelate Functions</a></p>
</li>
<li><p><a href="#heading-power-automate-with-the-relate-rows-in-dataverse-action">Power Automate with the Relate Rows in Dataverse Action</a></p>
</li>
<li><p><a href="#heading-c-console-app-using-the-dataverse-sdk">C# Console App: Using the Dataverse SDK</a></p>
</li>
<li><p><a href="#heading-final-thoughts">Final Thoughts</a></p>
</li>
</ol>
<h2 id="heading-aside-teams">Aside: Teams</h2>
<p>Teams are the simplest way to assign roles to multiple users.</p>
<p>Dataverse admins and team owners can add users to one or more teams. Rather than assigning roles to individual users, the security role is assigned to the team.</p>
<p>But there are caveats: record ownership and team management can introduce their own complexity. In environments with many teams, updating security roles can become just as tedious as assigning them individually.</p>
<p>This article focuses on <strong>programmatic individual assignments</strong>, but keep in mind that all three methods described below can be adapted to work with teams as well.</p>
<h2 id="heading-canvas-apps-relate-unrelate-functions">Canvas Apps Relate / Unrelate Functions</h2>
<p>Canvas app developers can use Power FX to assign security roles across users or teams. Minimal code is required, and the result can serve as a lightweight security role management portal.</p>
<p>While not ideal for massive batches, this approach is suitable for assigning roles to a few hundred users.</p>
<pre><code class="language-plaintext">ForAll(
    colSelectedUsers As User,
    Relate(
        User.'Security Roles (systemuserroles_association)',
        cbx_securityRoles.Selected
    )
)
</code></pre>
<p>Here:</p>
<ul>
<li><p><code>colSelectedUsers</code> is a collection of users.</p>
</li>
<li><p><code>cbx_securityRoles</code> is a Combobox control holding the security role to assign.</p>
</li>
</ul>
<p>The <code>Relate</code> function connects each user with the selected security role. The first parameter is the many-to-many relationship (<code>systemuserroles_association</code>) between <code>systemuser</code> and <code>role</code>.</p>
<p>To find relationship names, open the User table &gt; <strong>Relationships</strong>. Then, look for many-to-many connections to the role table.</p>
<img src="https://scripted-bytes.ghost.io/content/images/2025/05/Snag_1e2ee592.png" alt="Image of user table relationships highlighting the system user roles association relationship" width="600" height="400" loading="lazy">

<p>The security role/user relationship is a many-to-many relationship.</p>
<h2 id="heading-power-automate-with-the-relate-rows-in-dataverse-action">Power Automate with the Relate Rows in Dataverse Action</h2>
<p>The <strong>Relate Rows in Dataverse</strong> action allows you to assign roles dynamically in cloud flows.</p>
<img src="https://scripted-bytes.ghost.io/content/images/2025/05/power-automate.jpg" alt="Image of cloud flow assigning security roles" width="600" height="400" loading="lazy">

<h3 id="heading-how-it-works">How it works:</h3>
<ul>
<li><p>Trigger a flow (for example, manually or via Dataverse trigger).</p>
</li>
<li><p>Fetch a list of users based on a condition.</p>
</li>
<li><p>Loop through each user with <strong>Apply to Each</strong>.</p>
</li>
<li><p>Assign a static or dynamic security role.</p>
</li>
</ul>
<h2 id="heading-c-console-app-using-the-dataverse-sdk">C# Console App: Using the Dataverse SDK</h2>
<p>This method offers maximum control and supports complex, high-scale role assignments – but it requires pro-code skills.</p>
<p><strong>Example:</strong></p>
<p>This console app:</p>
<ol>
<li><p>Connects to the environment via client credentials.</p>
</li>
<li><p>Retrieves all users with the title "Salesperson"</p>
</li>
<li><p>Builds a batch of associate requests.</p>
</li>
<li><p>Executes the batch transactionally – if one fails, all fail.</p>
</li>
</ol>
<pre><code class="language-csharp">using Microsoft.PowerPlatform.Dataverse.Client;
using Microsoft.Xrm.Sdk;
using Microsoft.Xrm.Sdk.Messages;
using Microsoft.Xrm.Sdk.Query;

class Program
{
    static void Main(string[] args)
    {
        string dataverseUrl = "https://your-org.crm.dynamics.com";
        string clientId     = "client-id-here";
        string clientSecret = "client-secret-here";
        string tenantId     = "tenant-id-here";

        string connectionString = $@"
            AuthType=ClientSecret;
            Url={dataverseUrl};
            ClientId={clientId};
            ClientSecret={clientSecret};
            TenantId={tenantId};
        ";
        // Connect to our environment
        using var serviceClient = new ServiceClient(connectionString);

        if (!serviceClient.IsReady)
        {
            Console.WriteLine("Failed to connect.");
            return;
        }

        // Fetch a list of users that we intend to associate a role with
        var query = new QueryExpression("systemuser")
        {
            ColumnSet = new ColumnSet("systemuserid"),
            Criteria = new FilterExpression
            {
                Conditions =
                {
                     new ConditionExpression(
                        "title",
                        ConditionOperator.Equal,
                        "Salesperson"
                     ),
                }
            }
        };

        var users = serviceClient.RetrieveMultiple(query);

        // Role to assign (pretend guid for demo purposes)
        var securityRoleId = new Guid(
            "00000000-0000-0000-0000-000000000ABC"
        );

        // Prepare our transaction
        var transaction = new ExecuteTransactionRequest
        {
            ReturnResponses = true,
            Requests = new OrganizationRequestCollection()
        };

        // For each user we fetched above, we add an associate request 
        // to the transaction
        foreach (var user in users.Entities)
        {
            var userId = (Guid)user["systemuserid"];

            var relationship = new Relationship(
                "systemuserroles_association"
            );

            var relatedReferences = new EntityReferenceCollection
            {
                new EntityReference(
                    "role",
                    securityRoleId
                )
            };
            // build the associate request
            var request = new AssociateRequest
            {
                Target = new EntityReference(
                    "systemuser",
                    userId
                ),
                RelatedEntities = relatedReferences,
                Relationship = relationship
            };
            // add the request to the transaction
            transaction.Requests.Add(request);
        }

        // Finally, execute the batch as a transaction
        serviceClient.Execute(transaction);
    }
}
</code></pre>
<p>You can even utilize this logic within a Custom API, allowing Power Automate or Canvas Apps to call it, blending low-code and pro-code capabilities.</p>
<h2 id="heading-final-thoughts">Final Thoughts</h2>
<p>If your teams are already well-structured and manageable in number, <strong>teams remain the easiest way</strong> to assign roles at scale.</p>
<p>But when teams aren't feasible –&nbsp;or when assigning directly to users is required – each method we discussed here offers a viable alternative:</p>
<ul>
<li><p>Use <strong>Canvas Apps</strong> for lightweight, user-facing management portals</p>
</li>
<li><p>Use <strong>Power Automate</strong> when complexity is low and there is a need to trigger it in a variety of ways.</p>
</li>
<li><p>Use <strong>C# and the Dataverse SDK</strong> for full control and batch efficiency.</p>
</li>
</ul>
<p>Ready to automate your role assignments? Start small –&nbsp;build a simple Power App or Flow – and scale your approach from there.</p>
<p>Found this helpful? I write about practical automation, productivity systems, and building smarter workflows — without the jargon. Visit me at <a href="http://brandonwoz.com">brandonwoz.com</a>.</p>
 ]]>
                </content:encoded>
            </item>
        
    </channel>
</rss>
