The ability to implement trace logging within CRM plug-ins has been around since CRM 2011, so it’s something that CRM developers should be well aware of. Writing to the trace log is useful for when a plug-in has failed or hit an exception, as within the ErrorDetails.txt file (available to download from the error message box window) will be a list of everything that has been written to the log, up to that point. One issue with this is, if a user encounters an error and does not choose to download this file, then this file is lost – not so much of an issue if the exception can be re-produced, but this may not always the case.

For those who are now working on CRM Online 2015 Update 1 or CRM 2016, then a new feature has been added which further expands this feature – the Plug-in Trace Log. Now, plug-in exceptions can be configured to write to a new system entity, containing full details of the exception, that can be accessed at any time in order to support retroactive debugging. The introduction of this feature means now is the best time to start using trace logging within your plugins, if you are not already. This weeks blog post will take a look at the feature in more detail, assessing its pros & cons and providing an example of how it works in practice.

So, before we begin, why you would want to implement tracing in the first place?

Using tracing as part of CRM Online deployments makes sense, given that your options from a debugging point of view are restricted compared to an On-Premise Deployment. It is also, potentially, a lot more straightforward then using the Plug-in Registration Tool to debug your plugins after the event, particularly if you do not have ready access to the SDK or to Visual Studio. Tracing is also useful in providing a degree of debugging from within CRM itself, by posting either your own custom error messages or feeding actual error messages through to the tracing service.

Just remember the following…

Writing to the tracing service does add an extra step that your plug-in has to overcome. Not so much of an issue if your plugin is relatively small, but the longer it gets, and more frequent you are writing to the service, means there is a potential performance impact. You should use your best judgement when writing to the service; not every time you do something within the plugin, but where there is a potential for an error to occur. Writing to the tracing log can also have an impact on your CRM storage capacity, something we will take a look at later on in this post.

Now that we have got that out of the way, lets begin by setting up an example plugin! 

To start writing to the Tracing service depends on how you are implementing your plugin. If you have used the Visual Studio template, then simply use this line of code within the “TODO: Implement your custom Plug-In business logic.” section:

ITracingService tracingService = localContext.TracingService;

Otherwise, you will need to ensure that your plugin is calling the IServiceProvider, and then use a slightly longer code snippet to implement the service. An example of the code that you’d need to use to setup this is as follows:

using System;

//Be sure to add references to Microsoft.Xrm.Sdk in order to use this namespace!

using Microsoft.Xrm.Sdk;

namespace MyPluginProject
{
    public class MyPlugin : IPlugin
    {
        public void Execute(IServiceProvider serviceProvider)
        {
            //Extract the tracing service for use in debugging sandboxed plug-ins.
            
            ITracingService tracingService = (ITracingService)serviceProvider.GetService(typeof(ITracingService));
        }
    }
}

Once you’ve implemented the ITracingService within your code, you can then write to Trace Log at any time in your code using the following snippet:

tracingService.Trace("Insert your text here...");

Activating Tracing

Even though we have configured our plugin for tracing, this does not automatically mean that our plugin will start writing to the log. First, we must configure the Plug-in and custom workflow activity tracing setting within the System Settings page:

TracingSettings

You have three options that you can set:

  • Off – Nothing will be written to the trace log, even if the plugin encounters an exception.
  • Exception – When the plugin hits an exception, then a trace will be written to the log.
  • All – Whenever the plugin is executed and the trace log is called, then a trace log record will be created. This is equivalent to Verbose logging.

As mentioned earlier, individual records will be written to CRM whenever the tracing service is called. It is therefore recommended only to turn on ‘All’ for temporary periods; leaving it on for ‘Exception’ may be useful when attempting to initially diagnose plugin errors. Review the amount of storage available to you on your CRM Online/On-Premise deployment in order to determine the best course of action.

Tracing in Practice

Now that we’ve configured tracing on our CRM and we know how to use the Tracing, lets take a look at an example plugin. The below plugin will be set to fire on the Post-Operation event of the Update message on the Account entity. It will create a new contact record, associate this Contact record to the Account and then populate the Description field on the Contact with some information from the Account record:

protected void ExecutePostAccountUpdate(LocalPluginContext localContext)
    {
        if (localContext == null)
        {
            throw new ArgumentNullException("localContext");
        }

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

        ITracingService tracingService = localContext.TracingService;
        tracingService.Trace("Implemented tracing service succesfully!");

        // Obtain the execution context from the service provider.

        IPluginExecutionContext context = localContext.PluginExecutionContext;

        // Get a reference to the Organization service.

        IOrganizationService service = localContext.OrganizationService;

        if (context.InputParameters.Contains("Target"))

        {
            //Confirm that Target is actually an Entity

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

            {
                Guid contactID;
                string phone;

                Entity account = (Entity)context.InputParameters["Target"];
                tracingService.Trace("Succesfully obtained Account record" + account.Id.ToString());

                try

                {
                    tracingService.Trace("Attempting to obtain Phone value...");
                    phone = account["telephone1"].ToString();
                            
                }
                    
                catch(Exception error)

                {
                    tracingService.Trace("Failed to obtain Phone field. Error Details: " + error.ToString());
                    throw new InvalidPluginExecutionException("A problem has occurred. Please press OK to continue using the application.");

                }

                if (phone != "")

                {

                    //Build our contact record to create.

                    Entity contact = new Entity("contact");

                    contact["firstname"] = "Ned";
                    contact["lastname"] = "Flanders";

                    contact["parentcustomerid"] = new EntityReference("account", account.Id);

                    contact["description"] = "Ned's work number is " + phone + ".";

                    contactID = service.Create(contact);

                    tracingService.Trace("Succesfully created Contact record " + contactID.ToString());

                    tracingService.Trace("Done!");

                }

                else

                {

                    tracingService.Trace("Phone number was empty, Contact record was not created.");

                }
            }
        }
    }

After registering our plugin and with tracing configured for “All” in our CRM instance, we can now see our custom messages are being written to the Trace Log – when we both update the A. Datum Corporation (sample) record Phone field to a new value and when we clear the field value:

Plugin_1

Plugin_2

Plugin_3

Most importantly, we can also see that our test Contact record is being created successfully when we populate the Phone field with data 🙂

 

Plugin_4

Now, to see what happens when an error is invoked, I have modified the code above so that it is expecting a field that doesn’t exist on the Account entity:

Plugin_5

Now, when we attempt to update our Account record, we receive a customised Business Process Error message and window:

Plugin_6

And we can also see that the precise error message has been written to the trace log, at the point we specified:

Plugin_7

Last, but not least, for On-Premise deployments…

One thing to point out is, if you are using On-Premise CRM 2016 (both 8.0 and 8.1), then for some reason the trace log will not work if you do not run you plugin within sandbox isolation mode. I’m not the only one experiencing this, according to this post on the Dynamics CRM Community forum. Switching my test plugin to sandbox isolation resolved this issue. A bit of a strange one, and as Srikanth mentions on the post, it is not clear if this a bug or not.

Conclusions or Wot I Think

Trace logging is one of those things where time and place matter greatly. Implementing them within your code obsessively does not return much benefit, and could actually be detrimental to your CRM deployment. Used prudently and effectively though, they can prove to be incredibly useful. The scenarios where I can see them returning the most benefit is if your plugin is making a call to an external system and, if an error is encountered during this process, you can use the Trace Log to capture and store the external application error message within CRM for further investigation. Trace logging can also prove useful in scenarios where an issue cannot be readily replicated within the system, by outputting error messages and the steps leading up to them within the Trace Log.

In summary, when used in conjunction with other debugging options available to you via the SDK, Trace Logging can be a powerful weapon to add to your arsenal when debugging your code issues in CRM.

Anyone working within the CRM space will have already soaked up the news regarding Dynamics 365. Jujhar Singh’s announcement just a week before WPC 2016 helped to set the stage for Dynamics 365 & AppSource to steal the show as part of the conference, no doubt pleasing Dynamics professionals the world over. This is a major step forward for Microsoft, as they seek to quash the dominance of Salesforce, SAP & Oracle within the CRM/ERP space; having long been the underdog within this sector, Dynamics 365 could be what Microsoft needs to tip the scales in their favour.

So, if you are working with CRM closely at the moment, what does the above announcement mean for you? Is CRM still relevant or is it time to pivot across to some of the new offerings within Dynamics 365? In this week’s blog post, I take a closer look at what has emerged from the above announcement thus far, to see where the future may lie for CRM:

Is CRM now an Enterprise-level product?

At this stage, Microsoft are speaking in very high-level terms in respect to how the Dynamics 365 product will be licensed. But I was interested to see the following slide on show at WPC (picture courtesy of Peter Cutts):

Taking the above at face-value, Microsoft are now classifying CRM as an Enterprise-only product, a potentially concerning development. Some implications of this decision could be:

  • Price rise on all CRM licensing plans as part of Dynamics 365: I think in the short-term, it is incredibly unlikely that we will see a major jump in price (in order to help drive early adoption), but since CRM is now classed as an enterprise level product, it would be very surprising if pricing is not eventually adjusted, in order to take this into account.
  • Rise in minimum license purchase for CRM Online: This is currently set to 5 Professional licenses, whereas the above slide indicates a minimum seat purchase of 20 users. If we assume the same price under Dynamics 365, the minimum monthly cost to start using CRM Online rises up to £810 ex. VAT, which equates to a whopping rise of £607.50 per month! [UPDATE: Since this post, I have had it confirmed that CRM Online minimum seat purchase will not be affected by Dynamics 365. More info can be found here. Big thanks to CRM MVP Jukka Niiranen for pointing this out!]
  • The future of CRM within SMB’s: I am hoping that some further detail will help to clarify the position of CRM within the overall offer, but one of my major concerns at this juncture is the future position of CRM Online within small to medium size businesses. One of the huge benefits of the current structure is that is tailored for both extremes; a major shift of the CRM product towards an enterprise-only approach (i.e. in the sense that the price point precludes any other, smaller organisation from justifying the cost of adopting CRM) could spell the end of CRM within the small business. One would assume that Project ‘Madeira’ would be the alternative offer for SMB’s in this instance; but the challenge would be in convincing these organisations to migrate across to this.

Looking at this another way, Microsoft have promised that the Dynamics 365 offering will be flexible and adaptable for any kind of business. So it may well be the case that we see no major changes to how the CRM Online product is offered, something that I would welcome.

Time to say goodbye to CRM On-Premise?

One of the persistent questions, considering the increased focus on CRM Online in recent years and the Dynamics 365 announcement as a whole, is just where does On-Premise CRM sit in Microsoft’s long-term plans. Some colleagues I have spoken to recently have predicted that Dynamics 365 is the nail in the coffin for CRM On-Premise. I take a slightly more pessimistic view. With many large-scale organisations within the public/private sector still requiring the ability to literally point to a server rack in a data centre and say “This is where our data is stored!”, it will be difficult for Microsoft to convince them to migrate across to the Office 365/Azure platform, when such requirements may prove difficult to match. The UK is currently an excellent case in point, as we are still waiting on the promised arrival of UK based Azure data centres. Until Microsoft are in a position to offer commitments to every country in the world that they have data centres based within the country in question (or, in the case of Europe, within the European Economic Area), CRM On-Premise will continue to have a market for organisations who need specific assurances in regards to data storage and location.

The future of XRM

The XRM framework is a developers skeleton key, in terms of unlocking further potential from CRM and extending it to suit specific business requirements. So does the Dynamics 365 announcement mean that this key is now useless? Microsoft have provided some re-assurance that XRM is not going away anytime soon…

To extend the functionality of individual Dynamics 365 apps, partners may continue to use native application extensibility frameworks built-in to the CRM and the AX platforms.

But they have also indicated that there is a new sheriff in town…

The common data model is a cloud-resident business database, built on years of experience with our enterprise customers. It will come with hundreds of standard business entities spanning both business process (Dynamics 365) and productivity (Office 365). The standardization and consistency of schema enables partners to build innovative applications and to automate business processes spanning the entire business process spectrum with confidence their solutions can be easily deployed and used across Microsoft’s entire customer base.

Source: https://community.dynamics.com/b/msftdynamicsblog/archive/2016/07/06/insights-from-the-engineering-leaders-behind-microsoft-dynamics-365-and-microsoft-appsource

Clearly, the new “common data model” is something that CRM professionals are going to have to familiarise themselves with, as well having a general awareness of the other products sitting within Dynamics 365. One good thing to note, according to this blog post, is that there is some familiar terminology! I potentially see this as a positive step forward, particularly if your organisation is developing ISV solutions that sit within CRM and the constraints of CRM Solutions mean that you cannot leverage the desired functionality from the application.

A Fork in the Road – How Dynamics 365 could lead to CRM Specialist Roles

The Dynamics 365 announcement would also look to confirm that the Sales and Service side of CRM are starting to be treated as separate offerings, within one common environment. We’ve already seen that Microsoft have segregated out the Sales and Service side of CRM into different exams, and also that, when requesting a CRM demo, you can choose to have a Sales or Service focused trial experience. I can foresee a scenario where existing CRM professionals are having to “evolve” into one of three types of roles:

  • CRM Service Specialists
  • CRM Sales Specialists
  • Dynamics 365 Specialists

Without wishing to continue the references to Pokemon much further, we can then see situations where businesses are saying, for example, “CRM Service Specialist, I choose you!” for a particular project. Having focused roles along the lines of the above will undoubtedly lead to greater specialist knowledge of certain aspects of CRM, but could mean that professionals are no longer getting a good look over the garden fence at what’s going on within Dynamics 365 or within CRM itself.

Always Look on the Bright Side: Why Dynamics 365 could be awesome

Dynamics 365 can be seen as yet another gesture of love and attention towards the Dynamics CRM product. CRM has developed in leaps and bounds in recent history; this announcement would appear to be the cherry on the cake, designed to convince organisations across the globe that having CRM within their business can precipitate major benefits and return on investment. Dynamics 365 also gives those working with CRM an excellent excuse to start familiarising themselves with the other products in the Dynamics family. Typically, despite the shared name, these products have stood in distinct isolation from each other. Bringing them together as part of Dynamics 365 will hopefully lead to greater shared knowledge and awareness of what products, such as NAV, can deliver. Finally, the common data model, if designed correctly, could offer a much effective and less restrictive means of configuring CRM to interact with other products/systems.

There will no doubt be more news on Dynamics 365 in the months ahead, culminating with its release as part of Summit 2016 in October. For now, we will have to wait patiently, but I am eager to get my hands on it, as Dynamics 365 will undoubtedly be an important string on the bow of CRM professionals in the years ahead.

I was working within CRM recently, attempting to configure some form level logic in order to display/hide fields, based on certain conditions on the form itself. I went into it rather gung-ho and immediately started writing the following JScript function:

function hideFormFields() 

{

    var myField = Xrm.Page.getAttribute("jg_myfield").getValue();

    if (myField = "Value1") {

        Xrm.Page.getControl("jg_myfieldtohide1").setVisible(false);
        Xrm.Page.getControl("jg_myfieldtohide2").setVisible(false);
        Xrm.Page.getControl("jg_myfieldtohide3").setVisible(false);
        Xrm.Page.getControl("jg_myfieldtohide4").setVisible(true);
        Xrm.Page.getControl("jg_myfieldtohide5").setVisible(true);
        Xrm.Page.getControl("jg_myfieldtohide6").setVisible(true);

    }

    else if (myField = "Value2") {

        Xrm.Page.getControl("jg_myfieldtohide1").setVisible(true);
        Xrm.Page.getControl("jg_myfieldtohide2").setVisible(true);
        Xrm.Page.getControl("jg_myfieldtohide3").setVisible(true);
        Xrm.Page.getControl("jg_myfieldtohide4").setVisible(false);
        Xrm.Page.getControl("jg_myfieldtohide5").setVisible(false);
        Xrm.Page.getControl("jg_myfieldtohide6").setVisible(false);

    }
}

I then suddenly thought “Hang on – can’t this be done via a Business Rule instead?”. For CRM Administrators who do not have any previous development skills, Business Rules were a godsend when Dynamics CRM 2013 was first released, having been continually improved since. They essentially enable you to implement conditional logic and actions on your entity forms, without the need of writing a single line of code. Business Rules are, in fact, a form of JScript, utilising many of the capabilities available as part of the XRM framework. As an excellent case in point, we can very easily replicate the above code into a Business Rule, like so:

BusinessRule

There is an important lesson here, that anyone who works extensively within CRM needs to always remember; if it can be done out of the box within CRM, then why would you go to the trouble and effort to write a JScript function? Here are some reasons why CRM Developers should always think twice before typing away on that new form-level JScript function:

Business Rules actually do a lot more than you’d expect

This is something I am guilty of forgetting, and I’m having to train myself to consider this more carefully in future. In the above example, I made the immediate assumption that showing/hiding form fields on a conditional basis was not possible via a Business Rule – how very wrong I was! This seems to underline a general theme with how CRM customisers/developers approach Business Rules, assuming a glass half-empty approach. As of 2016 Update 1, as well as being able to modify a fields visibility, Business Rules can also support the following scenarios:

  • Show Error Message
  • Set Field Value – Fields can be set to match the value of another field, a specific value (including lookups), the result of a formula (Date/Number fields only) or be cleared of data.
  • Set Business Requirement.
  • Set Default Value – Fields can be set to match the value of another fields, a specific value (including lookups) or as the result of a formula (Date/Number fields only).
  • Lock or unlock field

What emerges, when combined with the conditional logic builder, is a means of utilising some of the most frequently used methods available to you via the SDK. And we can also hope and anticipate that as part of future releases of CRM, this list will be expanded on further.

Business Rules are supported, whereas your JScript may not be

To summarise another way, although you can do lots of things via Jscript within CRM, that doesn’t mean that you should. One thing I have observed with those who work with CRM, but have had more of a developer background, is that there is tendency to utilise methods/code which is not officially supported by Microsoft within CRM. Looking around the CRM community, and you often see that an unsupported solution is provided to a specific requirement, but often with no warning label attached to stress what it is doing. A good example of something which is unsupported is manipulating the Document Model Object (DOM) of the current page. Just because it works now doesn’t mean it will in the future, potentially causing major problems for your CRM deployment. If you are ever in doubt, be sure to review the supported extensions article on MSDN for CRM, and always think twice before you start using that nice bit of code you find on a Google search.

Your JScript may cause problems for end users

So your JScript is supported – great! But that doesn’t necessarily mean it’s going to work well from an end users perspective. If your JScript code, for example, does not provide a sufficient level of error handling, your end users could end up receiving error messages frequently. Or perhaps consider a scenario where your code is handling your errors well and outputting them correctly for potential debugging; this can lead to more lines of code that are unnecessary, and cause an impact when running the application on certain machines/browsers. With Business Rules, you don’t have to worry about addressing that careful balancing act between form loading times versus JScript library sizes. And, you can be assured that the CRM application as a whole will be able to handle your custom logic without affecting the performance of your deployment.

Jscript should have a time, place and bespoke requirement

What I mean by this is that JScript should only really begin to factor in when you are dealing with very specific, business requirements that the application “as-is” has no means of satisfying. An example of this is if you need to provide specific data validation to a field (such as a telephone number or bank sort code number). The only way this is ever going to be possible is via some kind of Regular Expression (RegEx) validation, which can only be performed via JScript. As one the key takeaways from this blog post, I would stress that you should always first attempt to build a Business Rule that is designed to meet the requirement that you are looking for, utilising other out of the box elements where appropriate (fields, workflows etc.). When it starts to become pretty obvious that a Business Rule is not going to cut it, then you can “give yourself permission” to start writing a JScript function 🙂

A “No Code First” approach should always prevail

I was recently introduced to this simple concept, but it is one that got me thinking and re-evaluating many of my previous solutions that I have built within CRM and elsewhere. When attempting to provide a potential solution to a requirement within CRM, you should try and put forward two solutions (where possible): a solution that can be achieved using out of the box functionality and one that requires bespoke coding to resolve. It may be that the first solution requires considerable time to build within CRM, but doing it this way could mean your solution is a lot more readable and understandable for those going into the system in future. By comparison, your 3-6 lines of code could prove to be virtually indecipherable.

So, in conclusion, can you guess what your new “Rule” should be moving forward?

Going back to my earlier example of your CRM Developer, AKA Former Application Developer, person, you can anticipate that they will have a very good knowledge of what CRM is capable from an SDK point of view. What may be lacking is a good understanding and knowledge of application as a whole, and specific features (such as SLA’s, Business Process Flows etc.). I would invite these people, and in fact anyone who works extensively with CRM, to focus their learning efforts towards the functional side of the application, so that they can ensure they have a good grasp of what CRM is capable of doing with, potentially, just a few mouse clicks. And, finally, to always think twice and consider alternative solutions before deciding on the best option – for everyone involved.

I was having a chat with a colleague recently about the new Interactive Service Hub (ISH) in CRM, in particular the new entity forms that are used as part of this. One of the questions that came up was “From a form scripting point of view, do ISH forms let you utilise all of the same references, properties and methods available as part of a Main form?”. As is generally the case in these situations, we can turn to our good friends TechNet and MSDN for answers. Specifically, we are able to find out the following on MSDN:

All the form scripting events and methods supported by the CRM mobile clients (phone and tablet) are supported in the interactive service hub.

If your organisation is fortunate enough to be using CRM 2016 Update 1 or CRM 2016 Service Pack 1, then you can also utilise the following methods/events as well:

Source: https://msdn.microsoft.com/en-us/library/mt671135.aspx#Anchor_1

So what does this mean in practical terms and how should this factor into your decision to utilise Interactive Forms over standard CRM forms? Here are a few things to consider, as well as my own thoughts on the best way to proceed:

If you are on CRM 2016, then get yourself Update 1/Service Pack 1 ASAP

There are a number of important new methods that can be used for interactive forms as part of this update. For example, you get much better options when it comes to working with IFRAME controls, interacting with the currently loaded record you are working with (via getID), loading a new record form (via openEntityForm or openQuickCreate) and setting focus to a particular field on a form (via setFocus). This goes above and beyond what is currently supported via the CRM tablet apps, and it is good to see that this CRM update has added these in. Having access to these methods may help to decide whether you can safely migrate or start using ISH forms within your organisation. And, as we have seen previously, the update process to SP1 for CRM 2016 is relatively straightforward, so why wouldn’t you look at upgrading?

Be sure you familiarise yourself with Interactive Form debugging

Anyone who works with CRM form scripting will be familiar with the trials and tribulations of browser debugging your scripts via Developer Tools on your browser of choice: open up your script library, set your breakpoints and then perform the actions needed to trigger your script. Try this with the new Interactive Forms, and you will notice that your custom library is not loaded onto the form. What the fudge?!?

Before panicking too much, the good news is that scripts can still be debugged, but you just have to go down a slightly different route. The CRM Team have written an excellent blog post that covers not just debugging for interactive forms, but for all forms as well. The first two options suggested seem to be the most straight-forward way of debugging interactive forms, but you can’t help but laugh at the fact that one of the suggested options is to use functionality within Google Chrome! 🙂 Joking aside, using Dynamic JScript in the manner outlined looks to be an effective way of setting breakpoints in a familiar manner. I may have to look at trying this at some point in the future.

You cannot programmatically switch to a different entity form in the Interactive Service Hub

It is sometimes useful to change the currently loaded form that a user is presented with depending on certain conditions. For example, if a user enters certain data within a Lead form to indicate the record should be treated as high priority, you may want a new form to be opened that contains additional fields, subgrids etc. that need to be completed in order to progress the record accordingly. Within the Xrm.Page.Ui reference, we have two methods that help us achieve this objective: formSelector.getCurrentItem, which returns the GUID for the currently loaded form, and formSelector.items, which returns a list of GUID’s for all forms that the current user has access to. The bad news is that, because these two methods are not supported in the mobile app, you will also be unable to use them within the ISH. This is likely due to the fact that, similar to Mobile Forms, only one form is presented to user when using the ISH, which is dictated by the form order and the users security permissions.

ISH forms do not contain a Ribbon

This may be one of the major reasons that prevent against an en masse adoption of ISH forms in the near future. One of the benefits of using the default CRM forms is the ability to modify the the CRM ribbon in order to add, remove or modify button behaviours across the application. This is great if you decide that you don’t want your users to have access to the Delete button, need to modify the order of the buttons to match the ones that are used the most or you need to setup a custom button that performs a web server call to an external system. Again, similar to the mobile application, there is no ribbon anywhere on the ISH, which means you may be missing out on key functionality going down this route.

ISH can only currently be used with a limited list of entities

If you are hoping to get your CRM setup to use ISH for your Sales related entities, then don’t get too carried away at this stage. You are currently limited to using ISH with a specific list of CRM entities. The full list, courtesy of our good friends again, is as follows:

  • Account
  • Contact
  • Case
  • All Activity Entities (System/Custom)
  • Social Profile
  • Queue Item
  • Knowledge Article
  • Custom Entities

Expect this to change in future, as one of the things that I have previously highlighted as part of Update 1/Service Pack 1 was the ability to add Feedback onto any entity within CRM, including custom ones. It would make sense that the Sales side of CRM gets some love and attention to include Leads, Opportunities etc. as part of ISH (so we may not even call it this if that happens!).

Conclusions or Wot I Think

It is clear that, whilst some of the headline benefits of using ISH are clear – visual experience, ability to drill down to individual records and efficient record filtering – , there are some very crucial and important technical limitations with the feature that need to be factored in before you decide to just completely migrate across to ISH. I would say that if your organisation has not been extensively customised to utilise form level scripting and other types of bespoke development work, then you can perhaps get away with making the jump. By contrary, you should be holding off and evaluating your existing customisations first to see if a) they are supported/unsupported by ISH or b) if there is some way to drop certain form scripting, ribbon customisations etc. in favour of using something default within CRM (for example, a Business Rule instead of a Jscript function). It could be that you can ditch a whole load of code that is not required as part of this exercise and instead utilise base functionality within CRM, something which is always preferable.

One thing I have been wondering about is the eventual aim with the ISH: is it intended that this will eventually replace the existing CRM user experience or will it continue to just be an alternative way of using CRM? It will be interesting to see how the feature is developed over the next couple of releases of CRM; one of the key indicators of this replacing the “old style” CRM forms is if we start to see all form scripting options made available in ISH and the introduction of the Ribbon.

In the meantime, make sure you do check out ISH at some stage, as the potential of setting up a visually attractive reporting and day-to-day application tool is huge. Just don’t let your Sales team see it yet, as you will end up disappointing them!

I was interested to read on TechNet that it is now supported to perform a Multiple-Server role installation of Dynamics CRM 2016 on Windows Server 2012 R2 instances that are configured in Core installation mode:

With the exception of the Microsoft Dynamics CRM Help Server and Microsoft Dynamics CRM Reporting Extensions roles, you can install any Microsoft Dynamics CRM 2016 Server server role on a Server Core installation of Windows Server.

Source: https://technet.microsoft.com/en-us/library/hh699671.aspx

At this stage you may be asking, “What is a Core installation of Windows Server 2012 R2?” or “Why would it be preferable to install CRM on a Core Server?”. Starting from Windows Server 2008, server admins can choose to install Windows Server without a GUI interface and without most of the common features that you would expect from a Windows Desktop environment. All you are able to see and interact with if you choose to log into a Windows Server core is the following:

ServerCore_Setup2

I would imagine that most novice service admins (like me!) would start panicking at this stage…

The idea behind Core installations is that the server would be administered remotely from a server/desktop environment (using Server Manager, Powershell etc.), with it being really unlikely that you would need to logon or remotely connect to the server via remote desktop connection. As a Core installation is missing pretty much everything you would expect from a standard Windows working environment, it is potentially ideal for scenarios where you have limited resources within your virtualised server environment. Alternatively, if you are intending to deploy a resource-intensive application to the server (like Dynamics CRM!), ensuring that the application has access to as many system resources as possible could be desirable. More information about Core installations, including their supported roles/features, can be found on this helpful MSDN article.

So lets go through the process of setting up a Windows Server 2012 R2 Core Installation and then performing a CRM installation on the machine for all roles, with the exception of the ones highlighted above. We’ll take a look at some of the options available to us as part of a silent install and evaluate to see what the benefits are for an organisation to deploy On-Premise CRM in this manner:

  1. To start off, we need to get our Windows Server 2012 R2 instance setup. The installation of this is really straight-forward and simple, so will not be covered in-depth. The only thing you need to note is that Server Core Installation option needs to be specified, as opposed to Server with a GUI, as you go through the required steps:ServerCore_Setup
  2. Once your server is setup and you have logged in for the first time, you will need to get the server joined to the domain that will be used for your Dynamics CRM instance. Fortunately, this can be rather straightforwardly done in Server Core by using the SConfig command on the prompt window. Type in the following in the command prompt window and hit return:

sconfig

The command prompt window will turn blue and change to resemble the following (image courtesy of Technet):

IC632362

At this point, type 1 and hit enter, following the instructions in order get the Server connected to your target domain. A restart will be required as part of this. An (optional) step before restarting is to also rename the Computer to something more description e.g. CRM-SERVER.

  1. Once your server is on the Domain, you can disconnect from the Core server for now. In order to get underway with the installation, there is some prep work that needs completing first, which will require having the following files downloaded:
      • Microsoft Dynamics CRM Installation executable (.exe)
      • A configuration .xml file for the install. This is what the installer will refer to during the installation process for all of the required options. For this example, we will be using the following .xml file:

    <CRMSetup>
    <Server>
    <Patch update="true"></Patch>
    <LicenseKey>XXXXX-XXXXX-XXXXX-XXXXX-XXXXX</LicenseKey>
    <SqlServer>MySQLInstance</SqlServer>
    <Database create="true"/>
    <Reporting URL="http://MySSRSServer/MyReportServer"/>
    <OrganizationCollation>Latin1_General_CI_AI</OrganizationCollation>
    <basecurrency isocurrencycode="GBP" currencyname="GB Pound Sterling" currencysymbol="£" currencyprecision="2"/>
    <Organization>My CRM Organisation</Organization>
    <OrganizationUniqueName>MyCRMOrganisation</OrganizationUniqueName>
    <OU>DC=MyDomain,DC=local</OU>
    <WebsiteUrl create="true" port="5555"> </WebsiteUrl>
    <InstallDir>c:\Program Files\Microsoft Dynamics CRM</InstallDir>
    
    <CrmServiceAccount type="DomainUser">
      <ServiceAccountLogin>MyDomain\CRM-CRMSERVERr-A</ServiceAccountLogin>
      <ServiceAccountPassword>password</ServiceAccountPassword>
    </CrmServiceAccount>
    
    <SandboxServiceAccount type="DomainUser">
      <ServiceAccountLogin>MyDomain\CRM-CRMSERVER-SP</ServiceAccountLogin>
      <ServiceAccountPassword>password</ServiceAccountPassword>
    </SandboxServiceAccount>
    
    <DeploymentServiceAccount type="DomainUser">
      <ServiceAccountLogin>MyDomain\CRM-CRMSERVER-DW</ServiceAccountLogin>
      <ServiceAccountPassword>password</ServiceAccountPassword>
    </DeploymentServiceAccount>
    
    <AsyncServiceAccount type="DomainUser">
      <ServiceAccountLogin>MyDomain\CRM-CRMSERVER-AP</ServiceAccountLogin>
      <ServiceAccountPassword>password</ServiceAccountPassword>
    </AsyncServiceAccount>
    
    <VSSWriterServiceAccount type="DomainUser"> 
      <ServiceAccountLogin>MyDomain\CRM-CRMSERVER-VSSW</ServiceAccountLogin>
      <ServiceAccountPassword>password</ServiceAccountPassword>
    </VSSWriterServiceAccount>
      
    <MonitoringServiceAccount type="DomainUser">
      <ServiceAccountLogin>MyDomain\CRM-CRMSERVER-M</ServiceAccountLogin>
      <ServiceAccountPassword>password</ServiceAccountPassword>
    </MonitoringServiceAccount>
    
      <SQM optin="false"/>
     <muoptin optin="true"/>
     </Server>
    </CRMSetup>

Both files, once ready, should look something like this:

ServerCore_Setup3

  1. The next step, presumably the trickiest, is actually getting the installation files onto our Core server. As we saw, on the Core installation we have limited command line functionality, making it impractical to simply “copy & paste” the files across. Fortunately, Core installations are configured so that the root drive can be accessed over a network connection; meaning that we can drop our files anywhere on the C:\ drive and access them via the cd command on the prompt window. To begin with, we will navigate to our computer using Windows Explorer on our other machine, replacing the JG-CRM with the name of your Core server:ServerCore_Setup4We can then navigate through and create a temporary folder on the drive root where we can move across all of our required files:ServerCore_Setup5Finally, because the CRM2016-Server-ENU-amd64.exe file is a self-extracting executable, we need to first extract all of the files into a temporary location on our non-Core server; then, ensure that all of these files are copied across to our Core Server, along with our config. xml file:ServerCore_Setup6
  2. With everything copied across, we can begin the installation. Going back onto our Server Core, we first need to navigate to the location of our installation folder using the cd command:ServerCore_Setup7

Next, we can run the CRM setup executable (SetupServer.exe), specifying the following required parameters:

/Q – Quiet Mode installation

/config C:\CRMInstall\CRMServerInstall_Config.xml – The file path to the config XML file that was copied across earlier

ServerCore_Setup8

  1. Once we hit return on the above, the command will be accepted and you will immediately be given control back to the command prompt window: ServerCore_Setup9At this stage, you may assume that something has gone wrong. But don’t panic – this is just a result of specifying a quiet mode installation. CRM will begin installing in the background and stop if any errors are encountered. Progress can be monitored by reviewing the CRM setup log files from our other server, by navigating to the currently logged in users AppData\Roaming\Microsoft\MSCRM\Logs folder:ServerCore_Setup10
  2. Assuming your installation has been completed successfully, the following Server Roles will now be available on your Server Core:
    • Web Application Server
    • Organization Web Service
    • Discovery Web Service
    • Asynchronous Processing Service
    • Sandbox Processing Service
    • Deployment Web Service

The Help Server role will not have been installed, so therefore we must run the setup for this on another non-Server Core server. The Reporting Extensions role would need to be installed on the server that has your SSRS instance, so therefore it could not be installed on our Server Core server used above. I have also deliberately left out the Deployment Tools role as part of the above, which I would strongly recommend is installed on another Windows Server instance (for ease of access more than anything). The process is the same as part of any standard CRM installation and, therefore, will not be covered as part of this post.

Thoughts & Summary

Some of the more obvious benefits of having a Server Core CRM deployment have already been hinted at. For example, I think it is definitely useful to be a in a position where you can ensure that your CRM deployment is completely free from competing with other Server resources; a Server Core installation allows you to achieve this aim quickly and easily, in a way that is fully supported by Microsoft. Installing CRM in this manner also presents some interesting opportunities for managed hosting providers, as the manner of deployment and installation (via quiet mode installation) could be easily automated in order to enable re-sellers to quickly roll-out hosted CRM instances to their customers.

Taking a look at the other side of the coin, installing CRM via this route definitely requires some patience and perseverance. I encountered several issues during installation which cancelled the install entirely, due to incorrect Service Account Details, lack of account permissions etc. It will therefore take you a number of attempts before you can start to identify the common problems that need to be dealt with before commencing the silent installation, which would ideally need to be dealt with via PowerShell script automation or similar. I would also question why it is not possible to do a Full Install (minus Reporting Extensions) on a Server Core instance. My assumption would be that the Help Server & Deployment Tools rely on Windows Server features that are stripped out during a Core installation. If your ultimate aim is to minimise hardware costs by utilising Server Core, then having to factor in additional servers/hardware for an additional Windows Server on top of this seems excessive. You would then also begin to question why you would just not use a standardWindows Server instance to start with. Finally, there doesn’t appear to be any (obvious) means of specifying specific server roles to install as part of the silent installation. This kind of defeats the whole purpose of using Server Cores to scale out the workload of your CRM server across multiple Windows Servers.

In conclusion, should you be opting to have a CRM Server Core installation in the near future? I would say “not yet” for the simple reason that you cannot select specific Server Roles to install as part of installing CRM in this manner. In my mind, this eliminates one of the most obvious benefits of marrying together CRM and Server Core. Perhaps in future, when/if you can specify individual Server Roles in the config file (or if someone can correct me in the comments below!), this will become something that can be looked at more seriously. For now though, you can save yourself the hassle.