CRM 2013 Programmatically Comparing User Privileges

When debugging security issues it can be useful to compare the privileges of a functioning user with a non-functioning user.

The code in this post will print out all the privilege differences between two given users.

Differences between and has BU:root, PRIV:prvCreateAccount, DEPTH:Global has BU:root, PRIV:prvCreateActivity, DEPTH:Global has BU:root, PRIV:prvCreateArticle, DEPTH:Global has BU:sub, PRIV:prvCreateActivity, DEPTH:Deep has BU:sub, PRIV:prvCreateArticle, DEPTH:Global

class Program
	static Dictionary<Guid, String> privilegeNames;
	static Dictionary<Guid, String> businessUnits;

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

	static StreamWriter file;               

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

		privilegeNames = GetPrivilegeNames(service);
		businessUnits = GetBusinessUnits(service);

		Console.WriteLine("Enter domain name of first user...");
		String userA = Console.ReadLine();

		Console.WriteLine("Enter domain name of second user...");
		String userB = Console.ReadLine();
		using (file = new StreamWriter(@"C:\temp\User Comparision.txt"))
			CompareUsers(service, userA, userB);


	static void CompareUsers(IOrganizationService service, String userA, String userB)
		List<String> a = GetPrivileges(service, userA);

		List<String> b = GetPrivileges(service, userB);

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

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

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

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

	static List<String> GetPrivileges(IOrganizationService service, String userName)
		Guid userId = GetUserId(service, userName);

		RetrieveUserPrivilegesRequest q = new RetrieveUserPrivilegesRequest();
		q.UserId = userId;

		RetrieveUserPrivilegesResponse r = (RetrieveUserPrivilegesResponse)service.Execute(q);

		return r.RolePrivileges.OrderBy(rp => privilegeNames[rp.PrivilegeId])
			.Select(rp => String.Format("BU:{0}, PRIV:{1}, DEPTH:{2}", businessUnits[rp.BusinessUnitId], privilegeNames[rp.PrivilegeId], rp.Depth))

	static Guid GetUserId(IOrganizationService service, String userName)
		QueryExpression q = new QueryExpression("systemuser");
		q.Criteria.AddCondition("domainname", ConditionOperator.Equal, userName);

		return service.RetrieveMultiple(q).Entities.First().Id;

	static Dictionary<Guid, String> GetBusinessUnits(IOrganizationService service)
		QueryExpression q = new QueryExpression("businessunit");
		return service.RetrieveMultiple(q).Entities.ToDictionary(e => e.Id, e => (String)e["name"]);

	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 void WriteLine(String message)

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