CRM 2013 Programmatically Comparing Security Roles

This code will print out all the differences between two given security roles. Useful when you need to sanity check your work or debug security issues.

Differences between Marketing Manager and Marketing Professional
Marketing Manager has prvActivateBusinessProcessFlow: Global
Marketing Manager has prvActivateSynchronousWorkflow: Global
Marketing Manager has prvAppendCompetitor: Global

Marketing Professional has prvActivateSynchronousWorkflow: User
Marketing Professional has prvAppendEmailTemplate: Bu

class Program
    enum Depth
        User = 1,
        Bu = 2,
        Parent = 4,
        Global = 8

    static StreamWriter file;
    static Dictionary<String, Guid> roleIds;
    static Dictionary<Guid, String> privilegeNames;

    static void Main(string[] args)
        IOrganizationService service = new OrganizationService(new CrmConnection("Connection"));

        roleIds = GetRoleIds(service);

        privilegeNames = GetPrivilegeNames(service);

        using (file = new StreamWriter(@"C:\temp\Roles Comparison.txt"))
            CompareRoles(service, "Marketing Manager", "Marketing Professional");

    static void WriteLine(String message)

    static void CompareRoles(IOrganizationService service, String roleA, String roleB)
        List<Tuple<String, Depth>> a = GetRolePrivileges(service, roleIds[roleA], privilegeNames);

        List<Tuple<String, Depth>> b = GetRolePrivileges(service, roleIds[roleB], privilegeNames);

        WriteLine(String.Format("Differences between {0} and {1}", roleA, roleB));
        bool differences = false;

        foreach (var t in a.Except(b))
            differences = true;
            WriteLine(String.Format("{0} has {1}: {2}", roleA, t.Item1, t.Item2));

        foreach (var t in b.Except(a))
            differences = true;
            WriteLine(String.Format("{0} has {1}: {2}", roleB, t.Item1, t.Item2));

        if (!differences)
            WriteLine(String.Format("No differences between {0} and {1}", roleA, roleB));

    static List<Tuple<String, Depth>> GetRolePrivileges(IOrganizationService service, Guid role, Dictionary<Guid, String> privilegeNames)
        string fetch = @"<fetch version=""1.0"" output-format=""xml-platform"" mapping=""logical"">
	                        <entity name=""roleprivileges"">
                                <attribute name=""privilegeid""/>
                                <attribute name=""privilegedepthmask""/>
		                        <filter type=""and"">
			                        <condition attribute=""roleid"" operator=""eq"" value=""{0}""/>

        fetch = fetch.Replace("{0}", role.ToString());

        return service.RetrieveMultiple(new FetchExpression(fetch)).Entities
            .Select(e => new Tuple<String, Depth>(privilegeNames[(Guid)e["privilegeid"]], (Depth)((int)e["privilegedepthmask"])))
            .OrderBy(p => p.Item1)

    static Dictionary<Guid, String> GetPrivilegeNames(IOrganizationService service)
        QueryExpression q = new QueryExpression("privilege");
        q.ColumnSet = new ColumnSet("name");

        return service.RetrieveMultiple(q).Entities.ToDictionary(e => e.Id, e => (String)e["name"]);

    static Dictionary<String, Guid> GetRoleIds(IOrganizationService service)
        QueryExpression q = new QueryExpression("role")
            ColumnSet = new ColumnSet("name"),
            Criteria =
                Conditions = 
                    new ConditionExpression("businessunitid", ConditionOperator.EqualBusinessId)

        return service.RetrieveMultiple(q).Entities.ToDictionary(e => (String)e["name"], e => e.Id);

Leave a Reply

Fill in your details below or click an icon to log in: Logo

You are commenting using your account. Log Out /  Change )

Google+ photo

You are commenting using your Google+ account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )


Connecting to %s