Sonoma Partners Microsoft CRM and Salesforce Blog

Deleting Fields? Be Wary of Personal Views.

Today's blog post was written by Mike Dearing, Principal Developer at Sonoma Partners.

Dynamics System Administrators have free reign to do just about anything in a Dynamics organization… except with personal views. While you can manage your own of course, the personal views of others are locked down for those of us with even the greenest of bubbles in our privilege lists. And while the restriction itself makes sense I suppose – with 10s, 100s, or even 1000s of users, you can imagine how cluttered a System Administrator’s view lists would become if subjected to the whims of their user base’s individual views – this limitation does pose a problem when paired with the desire to delete custom fields.

Dearing 1v2
Behold the cursed yellow in a field of green, clipping our System Administrator wings, humbling us down to the level of a standard user.

Issue

You’ve been tasked with deleting a field in your organization - an easy feat for any System Administrator to accomplish. Or is it? Remember the 1000s of users mentioned before? Although this field may no longer serve a purpose for your organization, there was a point in time when it did, and someone is bound to have leveraged it as a column or criteria for one of their views. Dynamics will not notify you of this. It will tell you when the field is on a form, a system view, even a plugin image, but it won’t even warn of the possibility of this field being a part of a personal view – even your own.

Solution

Before I get into my code-based solution, there are several adequate non-code alternatives here, ones which most us have already been employing when facing a field deletion request. This can range from simply warning users of the upcoming deletion, and having them take it upon themselves to clean up any potentially affected personal views before the deletion occurs, or even tagging the field with a z_ at the front and setting it to non-searchable, making the field fairly out of sight for the average user.

But I wanted to take a different approach this time. A generic, programmatic approach, to clean any and all personal views of upcoming field deletions, without being bottlenecked by users, or corrupting their views in the process. My goal wasn’t to make the most optimized or prettiest resulting view definitions, but to safely eliminate references to fields with minimal disturbance to users.

Caveats

  1. It is possible to programmatically create personal views that introduce situations that this code may not reliably clean.
  2. Microsoft may update advanced find view creation to incorporate functionality that this code does not anticipate, and therefore cannot reliably clean.
  3. You cannot impersonate and perform actions on behalf of disabled users. This means any personal views belonging to a disabled user will be uncleanable – so be careful of re-enabling users without running this script again.
  4. If the fields being cleaned are the primary criteria or columns of a view, the view may no longer serve much of a purpose. Views are never fully deleted as a part of this script, just cleaned, so users may still want to go clean out views that are no longer useful to them post-cleanup.

Prerequisites

  1. This script was built to be run by Linqpad 5, a free tool that can execute C# code amongst other things. With minor adjustments this can be run from Visual Studio or your code editor of choice.
  2. You’ll need to reference the Microsoft.CrmSdk.CoreAssemblies nuget package, or the Microsoft.Xrm.Sdk assembly directly. This was written as of version 8.2.0.2.
  3. The user executing this code will need to be able to impersonate other users, meaning they will need the ‘ActOnBehalfOf’ privilege. If unsure if you’ll possess enough privileges, just run as a System Administrator.

Code Summary

  1. Use the Organization Service Proxy class to impersonate all enabled system users for the organization by setting the Caller Id
  2. Iterate over all personal views, for all entities, for these users
  3. Use XPath expressions to detect and clean view fetchxml and layoutxml based upon inputted entity and field combos. A first pass is done on the primary entity’s fetchxml, then a secondary pass for linked entities. Fields are matched by their entity context, so fields with the same schema across different entities will not be incorrectly cleaned in the process, and layoutxml leverages the proper entity aliases to ensure it is cleaned correctly. Multiple levels of links are also cleaned properly.
  4. Executes view updates per user, if supplied that a cleanup should be performed

Code

Example

I've created a contact personal view with a link to account and referencing a few fields specified in the code to be cleaned for both entities:

Dearing 2

And here are the accompanying view columns: 

Dearing 3
Click the image to expand.

FetchXml:

LayoutXml:

Result

The cleaned view definition:

Dearing 4

And the cleaned view columns:

Dearing 5

FetchXml:

LayoutXml:

After the script executes, we’re left with a functioning, albeit not fully optimized, view. I think we can all agree that it may not be the prettiest result given the sample we were fed, but we can now safely delete our fields without users receiving errors, and let the users decide what to do with their affected views on their own timetables.

Topics: Microsoft Dynamics 365