I’ve gone on record previously saying how highly I rate the Dynamics CRM/Dynamics 365 Customer Engagement (CRM/D365CE) community. Out of all the groups I have been a part of in the past, you couldn’t ask for a more diverse, highly passionate and – most importantly of all – helpful community. There are a lot of talented individuals out there which put a metric tonne of effort into providing the necessary tools, know-how and support to make our daily journey with CRM/D365CE that much easier to traverse.

An excellent case in point comes from the CRM DevOps extraordinaire himself, Ben Walker, who reached out me regarding my recent post on default SiteMap areas vanishing mysteriously. Now, when you are working with tools like XrmToolbox, day in, day out, the propensity towards generating facepalm moments for not noticing apparent things can increase exponentially over time. With this in mind, Ben has very kindly demonstrated a much more simplistic way of restoring missing SiteMap areas and, as he very rightly points out, the amount of hassle and time-saving the XrmToolbox can provide when you fully understand its capabilities. With this in mind, let’s revisit the scenario discussed in the previous post and go through the insanely better approach to solving this issue:

  1. Download and run XrmToolbox and select the SiteMap Editor app, logging into your CRM/D365CE instance when prompted:

After logging in, you should see a screen similar to the below:

  1. Click on the Load SiteMap button to load the SiteMap definition for the instance you are connected to. It should bear some resemblance to the below when loaded:

  1. Expand the Area (Settings) node. It should resemble the below (i.e. no Group for Process Center):

  1. Right click on the Area (Settings) node and select Add Default SiteMap Area button. Clicking this will launch the SiteMap Component Picker window, which lists all of the sitemap components included by default in the application. Scroll down, select the ProcessCenter option. Then, after ticking the Add child components too checkbox, press OK. The SiteMap Editor will then add on the entire group node for the ProcessCenter, including all child nodes:

  1. When you are ready, click on the Update SiteMap button and wait until the changes upload/publish into the application. You can then log onto CRM/D365CE to verify that the new area has appeared successfully.

I love this alternative solution for a number of reasons. There are fewer steps involved, there is no requirement to resort to messing around with the SiteMap XML files (which has its own set of potential pitfalls, if done incorrectly) and the solution very much looks and feels like a “factory reset”, without any risk of removing other custom SiteMap areas that you may have added for alternate requirements. A huge thanks to Ben for reaching out and sharing this nifty solution and for rightly demonstrating how fantastic the CRM/D365CE community is 🙂

UPDATE 02/09/2018: It turns out that there is a far better way of fixing this problem. Please click here to find out more.

I thought I was losing my mind the other day. This feeling can be a general occurrence in the world of IT, when something completely random and unexplainable happens – emphasised even more so when you have a vivid recollection of something behaving in a particular way. In this specific case, a colleague was asking why they could no longer access the list of Workflows setup within a version 8.2 Dynamics 365 Customer Engagement (D365CE) Online instance via the Settings area of the system. Longstanding CRM or D365CE professionals will recall that this has been a mainstay of the application since Dynamics CRM 2015, accessible via the Settings -> Processes group Sitemap area:

Suffice to say, when I logged on to the affected instance, I was thoroughly stumped, as this area had indeed vanished entirely:

I asked around the relatively small pool of colleagues who a) had access to this instance and b) had knowledge of modifying the sitemap area (more on this shortly). The short answer, I discovered, was that no one had any clue as to why this area had suddenly vanished. It was then that I came upon the following Dynamics 365 Community forum post, which seemed to confirm my initial suspicions; namely, that something must have happened behind the scenes with Microsoft or as part of an update that removed the Processes area from the SiteMap. Based on the timings of the posts, this would appear to be a relatively recent phenomenon and one that can be straightforwardly fixed…if you know how to. 😉

For those who are unfamiliar with how SiteMaps work within the application, these are effectively XML files that sit behind the scenes, defining how the navigation components in CRM/ D365CE operate. They tell the application which of the various Entities, Settings, Dashboards and other custom solution elements that need to be displayed to end users. The great thing is that this XML can be readily exported from the application and modified to suit a wide range of business scenarios, such as:

  • Only make a specific SiteMap area available to users who are part of the Sales Manager Security Role.
  • Override the default label for the Leads SiteMap area to read Sales Prospect instead.
  • Link to external applications, websites or custom developed Web Resources.

What this all means is that there is a way to fix the issue described earlier in the post and, even better, the steps involved are very straightforward. This is all helped by quite possibly the best application that all D365CE professionals should have within their arsenal – the XrmToolBox. With the help of a specific component that this solution provides, alongside a reliable text editor program, the potentially laborious process of fiddling around with XML files and the whole export/import process can become streamlined so that anybody can achieve wizard-like ability in tailoring the applications SiteMap. With all this in mind, let’s take a look on how to fix the above issue, step by step:

  1. Download and run XrmToolbox and select the SiteMap Editor app, logging into your CRM/D365CE instance when prompted:

After logging in, you should be greeted with a screen similar to the below:

  1. Click on the Load SiteMap button to load the SiteMap definition for the instance you are connected to. Once loaded, click on the Save SiteMap button, saving the file with an appropriate name on an accessible location on your local computer.
  2. Open the file using your chosen text editor, applying any relevant formatting settings to assist you in the steps that follow. Use the Find function (CTRL + F) to find the Group with the node value of Customizations. It should look similar to the image below, with the Group System_Setting specified as the next one after it:

  1. Copy and paste the following text just after the </Group> node (i.e. Line 415):
<Group Id="ProcessCenter" IsProfile="false">
    <Titles>
        <Title LCID="1033" Title="Processes" />
    </Titles>
    <SubArea Entity="workflow" GetStartedPanePath="Workflows_Web_User_Visor.html" GetStartedPanePathAdmin="Workflows_Web_Admin_Visor.html" GetStartedPanePathAdminOutlook="Workflows_Outlook_Admin_Visor.html" GetStartedPanePathOutlook="Workflows_Outlook_User_Visor.html" Id="nav_workflow" AvailableOffline="false" PassParams="false">
        <Titles>
          <Title LCID="1033" Title="Workflows" />
        </Titles>
    </SubArea>
</Group>

It should resemble the below if done correctly:

  1. Save a copy of your updated Sitemap XML file and go back to the XrmToolbox, selecting the Open SiteMap button. This will let you import the modified, copied XML file back into the Toolbox, ready for uploading back onto CRM/D365CE. At this stage, you can verify the SiteMap structure of the node by expanding the appropriate area within the main SiteMap window:

When you are ready, click on the Update SiteMap button and wait until the changes are uploaded/published into the application. You can then log onto CRM/D365CE to verify that the new area has appeared successfully. Remember when I said to save a copy of the SiteMap XML? At this stage, if the application throws an error, then you can follow the steps above to reimport the original SiteMap to how it was before the change, thereby allowing you to diagnose any issues with the XML safely.

It is still a bit of mystery precisely what caused the original SiteMap area for Processes to go walkies. The evidence would suggest that some change by Microsoft forced its removal and that this occurred not necessarily as part of a major version update (the instance in our scenario has not been updated to a major release for 18 months at least, and this area was definitely there at some stage last year). One of the accepted truths with any cloud CRM system is that you at the mercy of the solution vendor, ultimately, if they decide to modify things in the background with little or no notice. The great benefit in respect to this situation is that, when you consider the vast array of customisation and development options afforded to us, CRM/D365CE can be very quickly tweaked to resolve cases like this, and you do not find yourself at the mercy of operating a business system where your bespoke development options are severely curtailed.

The Voice of the Customer (VoC) solution, available as part of Dynamics 365 Customer Engagement (D365CE), works most effectively when you are tightly integrating your survey’s around other features or datasets stored within the application. That’s not to say that it must only ever be utilised in tandem as opposed to isolation. If you have the requirement to quickly send out a survey to a small list of individuals (regardless of whether they are D365CE Contact records), VoC presents a natural choice if you are already paying for D365CE Online, as it is included as part of your subscription cost. As services such as SurveyMonkey tend to charge money to let you develop more complex, bespoke branded surveys, VoC, by comparison, offers all of this to you at no additional cost. Just don’t be buying licenses to use only this specific piece of functionality. 🙂 Ultimately, the upside of all this is that VoC represents a solid solution in and of itself, but working with the solution in this manner is just the icing on top of the cake. When you start to take into account the myriad of different integration touchpoints that VoC can instantly support, thanks to its resident status within D365CE, this is where things start to get really exciting. With this in mind, you can look to implement solutions that:

  • Send out surveys automatically via e-mail.
  • Route survey responses to specific users, based on answers to certain questions or the Net Promoter Score (NPS) of the response.
  • Tailor a specific email to a customer that is sent out after a survey is completed.
  • Include survey data as part of an Azure Data Export Profile and leverage the full power of T-SQL querying to get the most out of your survey data.

It is in the first of these scenarios – sending out surveys via a WorkFlow – that you may find yourself encountering the error referenced in the title of this post. The error can occur when you look to take advantage of the survey snippet feature as part of an Email Template – in laymen’s terms, the ability to send out a survey automatically and tag the response back to the record that it is triggered from. To implement this, you would look towards creating a WorkFlow that looks similar to the below:

With then either the desired email message typed out or a template specified that contains the survey snippet code, available from a published survey’s form:

All of this should work fine and dandy up until the user in question attempts to trigger the workflow; at which point, we see the appropriate error message returned when viewing the workflow execution in the System Jobs area of the application:

Those who are familiar with errors like these in D365CE will instantly realise that this is a security role permission issue. In the above example, the user in question had not been granted the Survey User role, which is included as part of the solution and gives you the basic “set menu” of permissions required to work with VoC. A short while following on from rectifying this, we tried executing the workflow again and the error still occurred, much to our frustration. Our next step was to start combing through the list of custom entity privileges on the Security Role tab to see if there was a permission called Azure Deployment or similar. Much to our delight, we came across the following permission which looked like a good candidate for further scrutiny:

When viewing this security role within the Survey User role, the Read permission for this organization-owned custom entity was not set. By rectifying this and attempting to run the workflow again, we saw that it executed successfully 🙂

It seems a little odd that the standard user security role for the VoC module is missing this privilege for an arguably key piece of functionality. In our situation, we simply updated the Survey User security role to include this permission and cascaded this change accordingly across the various dev/test/prod environments for this deployment. You may also choose to add this privilege to a custom security role instead, thereby ensuring that it is properly transported during any solution updates. Regardless, with this issue resolved, a really nice piece of VoC functionality can be utilised to streamline the process of distributing surveys out to D365CE customer records.

After going through a few separate development cycles involving Dynamics 365 Customer Engagement (D365CE), you begin to get a good grasp of the type of tasks that need to be followed through each time. Most of these are what you may expect – such as importing an unmanaged/managed solution into a production environment – but others can differ depending on the type of deployment. What ultimately emerges as part of this is the understanding that there are certain configuration settings and records that are not included as part of a Solution file and which must be migrated across to different environments in an alternate manner.

The application has many record types that fit under this category, such as Product or Product Price List. When it comes to migrating these record types into a Production environment, those out there who are strictly familiar with working inside the application only may choose to utilise the Advanced Find facility in the following manner:

  • Generate a query to return all of the records that require migration, ensuring all required fields are returned.
  • Export out the records into an Excel Spreadsheet
  • Import the above spreadsheet into your target environment via the Data Import wizard.

And there would be nothing wrong with doing things this way, particularly if your skillset sits more within a functional, as opposed to technical, standpoint. Where you may come unstuck with this approach is if you have a requirement to migrate Subject record types across environments. Whilst a sensible (albeit time-consuming) approach to this requirement could be to simply create them from scratch in your target environment, you may fall foul of this method if you are utilising Workflows or Business Rules that reference Subject values. When this occurs, the application looks for the underlying Globally Unique Identifier (GUID) of the Subject record, as opposed to the Display Name. If a record with this exact GUID value does not exist within your target environment, then your processes will error and fail to activate. Taking this into account, should you then choose to follow the sequence of tasks above involving Advanced Find, your immediate stumbling block will become apparent, as highlighted below:

As you can see, there is no option to select the Subject entity for querying, compounding any attempts to get them exported out of the application. Fortunately, there is a way to get overcome this via the Configuration Migration tool. This has traditionally been bundled together as part of the applications Solution Developer Kit (SDK). The latest version of the SDK for 8.2 of the application can be downloaded from Microsoft directly, but newer versions – to your delight or chagrin – are only available via NuGet. For those who are unfamiliar with using this, you can download version 9.0.2.3 of the Configuration Migration tool alone using the link below:

Microsoft.CrmSdk.XrmTooling.ConfigurationMigration.Wpf.9.0.2.3

With everything downloaded and ready to go, the steps involved in migrating Subject records between different D365CE environments are as follows:

  1. The first step before any export can take place is to define a Schema – basically, a description of the record types and fields you wish to export. Once defined, schemas can be re-used for future export/import jobs, so it is definitely worth spending some time defining all of the record types that will require migration between environments. Select Create schema on the CRM Configuration Migration screen and press Continue.

  1. Login to D365CE using the credentials and details for your specific environment.

  1. After logging in and reading your environment metadata, you then have the option of selecting the Solution and Entities to export. A useful aspect to all of this is that you have the ability to define which entity fields you want to utilise with the schema and you can accommodate multiple Entities within the profile. For this example, we only want to export out the Subject entity, so select the Default Solution, the entity in question and hit the Add Entity > button. Your window should resemble the below if done correctly:

  1. With the schema fully defined, you can now save the configuration onto your local PC. After successfully exporting the profile, you will be asked whether you wish to export the data from the instance you are connected to. Hit Yes to proceed.

  1. At this point, all you need to do is define the Save to data file location, which is where a .zip file containing all exported record data will be saved. Once decided, press the Export Data button. This can take some time depending on the number of records being processed. The window should update to resemble the below once the export has successfully completed. Select the Exit button when you are finished to return to the home screen.

  1. You have two options at this stage – either you can either exit the application entirely or, if you have your target import environment ready, select the Import data and Continue buttons, signing in as required.

  1. All that remains is to select the .zip file created in step 5), press the Import Data button, sit back and confirm that all record data imports successfully.

It’s worth noting that this import process works similarly to how the in-application Import Wizard operates with regards to record conflicts; namely, if a record with the same GUID value exists in the target instance, then the above import will overwrite the record data accordingly. This can be helpful, as it means that changes to records such as the Subject entity can be completed safely within a development context and promoted accordingly to new environments.

The Configuration Migration tool is incredibly handy to have available but is perhaps not one that it is shouted from the rooftops that often. It’s usefulness not just extends to the Subject entity, but also when working with the other entity types discussed at the start of this post. Granted, if you do not find yourself working much with Processes that reference these so-called “configuration” records, then introducing the above step as part of any release management process could prove to be an unnecessary administrative burden. Regardless, there is at least some merit to factor in the above tool as part of an initial release of a D365CE solution to ensure that all development-side configuration is quickly and easily moved across to your production environment.

Typically, when working with Dynamics 365 for Customer Service entities, you expect a certain type of behaviour. A good example of this in practice is entity record activation and the differences between Active and Inactive record types. In simple terms, you are generally restricted in the actions that can be performed against an Inactive record, most commonly being the modification of a field value. You can, however, perform actions such as deleting and reassigning records to other users in the application. The latter of these can be particularly useful if, for example, an individual leaves a business and you need to ensure that another employee requires access to old, inactive records.

When it comes to reporting on time intervals for when a record was last changed, I often – rightly or wrongly – see the Modified On field used for this purpose. This, essentially, stores the date and time of when the record was…well…last modified in the system! Since only more recent changes to the application have facilitated an alternative approach in reporting a record’s age and its current stage within a process, it is perhaps understandable why this field is often chosen when attempting to report, for example, the date on which a record was moved to Inactive status. Where you may encounter issues with this is if you a working in a similar situation highlighted above – namely, an individual leaving a business – and you need to reassign all of the inactive records owned by them. Doing either of these steps will immediately update the Modified On value to the current date and time, skewering any dependent reporting.

Fortunately, there is a way of getting around this, if you don’t have any qualms about opening up Visual Studio and putting together a plug-in in C#. Via this route, you can prevent the Modified On value of a record from being updated by capturing the original value and forcing the platform to commit this value to the database during the Pre-Operation stage of the transaction, as opposed to the date and time of when the record is reassigned. In fact, using this method, you can set the Modified On value to be whatever you want. Here’s the code that illustrates how to achieve both scenarios:

using System;

using Microsoft.Xrm.Sdk;

namespace Sample.OverrideCaseModifiedDate
{
    public class PreOpCaseAssignOverrideModifiedDate : IPlugin
    {
        public void Execute(IServiceProvider serviceProvider)
        {
            //Obtain the execution context from the service provider.

            IPluginExecutionContext context = (IPluginExecutionContext)serviceProvider.GetService(typeof(IPluginExecutionContext));

            //Extract the tracing service for use in debugging sandboxed plug-ins

            ITracingService tracingService = (ITracingService)serviceProvider.GetService(typeof(ITracingService));

            tracingService.Trace("Tracing implemented successfully!");

            if (context.InputParameters.Contains("Target") && context.InputParameters["Target"] is Entity)

            {
                Entity incident = (Entity)context.InputParameters["Target"];
                Entity preIncident = context.PreEntityImages["preincident"];

                //At this stage, you can either get the previous Modified On date value via the Pre Entity Image and set the value accordingly...

                incident["modifiedon"] = preIncident.GetAttributeValue<DateTime>("modifiedon");

                //Or alternatively, set it to whatever you want - in this example, we get the Pre Entity Image createdon value, add on an hour and then set the value

                DateTime createdOn = preIncident.GetAttributeValue<DateTime>("createdon");
                TimeSpan time = new TimeSpan(1, 0, 0);
                DateTime newModifiedOn = createdOn.Add(time);
                incident["modifiedon"] = newModifiedOn;

            }
        }
    }
}

When deploying out your plug-in code to the application (something that I hope regular readers of the blog will be familiar with), make sure that the settings you configure for your Step and the all-important Entity image resemble the images below:

Now, the more eagle-eyed readers may notice that the step is configured on the Update as opposed to the Assign message, which is what you (and, indeed, I when I first started out with this) may expect. Unfortunately, because the Input Parameters of the Assign message only returns two Entity Reference objects – the incident (Case) and systemuser (User) entities, respectively – as opposed to an Entity object for the incident entity, we have no means of interfering with the underlying database transaction to override the required field values. The Update message does not suffer from this issue and, by scoping the plug-in’s execution to the ownerid field only, we can ensure that it will only ever trigger when a record is reassigned.

With the above plug-in configured, you have the flexibility of re-assigning your Case records without updating the Modified On field value in the process or expanding this further to suit whatever business requirement is needed. In theory, as well, the approach used in this example could also be applied to other what we may term “system defined fields”, such as the Created On field. Hopefully, this post may prove some assistance if you find yourself having to tinker around with inactive Case records in the future.