Dynamics CRM Share a Personal View with SYSTEM User

Paul Nieuwelaar, 16 June 2016

Why would you want to do this? Well if you’re reading this you probably have a good enough reason. My reason was because we needed to retrieve a personal view in a plugin. It needed to be a personal view because certain users should be able to edit the view, and we can’t give users access to customize system views.

However because any user can trigger the plugin, all users would need to be shared at least read access for the personal view to actually retrieve it. I didn’t really want to do this either since it wouldn’t make sense if a normal user saw the view. Naturally you’d assume running the plugin in the SYSTEM context would allow you to retrieve the view regardless of sharing, but you’d be wrong.

Even though SYSTEM might have full admin privileges, the view still needs to be shared before it can be retrieved (same goes for any admin). So the solution seems simple enough, share the view with the SYSTEM user. Problem is, you can’t actually do that through the UI. Not only do all the system views for user filter out the SYSTEM user by default, but even if you create your own view which includes SYSTEM, when you try to select that view while sharing, it just excludes the SYSTEM user anyway for some reason!

image

However! While the UI prevents us sharing with the system user, the good ol' reliable SDK is here to save the day. I’m going to assume you already have access to a console app or something that can connect to CRM, since only a programmer would care about the SYSTEM user in the first place.

So basically just execute a Grant Access Request using the SYSTEM User ID and the Personal View ID (the user running the console app will need to already be shared with the view).

QueryExpression view = new QueryExpression("userquery"); view.Criteria.AddCondition("name", ConditionOperator.Equal, "<The Name of the View>"); Guid viewId = _sdk.RetrieveMultiple(view)[0].Id; QueryExpression user = new QueryExpression("systemuser"); user.Criteria.AddCondition("fullname", ConditionOperator.Equal, "SYSTEM"); Guid systemUserId = _sdk.RetrieveMultiple(user)[0].Id; var request = new GrantAccessRequest { PrincipalAccess = new PrincipalAccess { AccessMask = AccessRights.ReadAccess, Principal = new EntityReference("systemuser", systemUserId) }, Target = new EntityReference("userquery", viewId) }; _service.Execute(request);

Once that’s done, the view should be shared with SYSTEM, giving them Read access, which is enough for them to retrieve the view in a plugin, for example, while executing under system context.

image