Working with Dynamics CRM can present some interesting challenges. What you tend to find is that you can pretty much say “Yes!” when it comes to doing most things you would expect from a CRM/database system, but there is a learning curve involved in figuring out the best approach to take. Often, as well, you may  over-complicate matters and overlook a much easier solution to achieve what you need.

Take, for example, modifying the FetchXML queries in a Public View that you have created programmatically. Let’s say you’ve created your own view within CRM using the following C# code snippet (adapted from the SDK sample):

SavedQuery sq = new SavedQuery
     {
        Name = "My New View",
        Description = "My view created in C# for the Account entity",
        ReturnedTypeCode = "account",
        FetchXml = fetchXml,
        LayoutXml = layoutXml,
        QueryType = 0
    };

_customViewId = _serviceProxy.Create(sq);
Console.WriteLine("A new view with the name {0} was created.", sq.Name);

A few things to point out first with the above:

  • In order for this code to work, you would need to declare System.String values for fetchXml and layoutXml, as well as first connecting to CRM using the OrganizationServiceProxy (_serviceProxy).
  • As well as specifying the FetchXML query you would like to use, you also have to specify a LayoutXML as a parameter in order to. Although Microsoft do have dedicated articles on MSDN that goes over the schema for this, there is a potential learning curve involved here for those who are unfamiliar with working with XML.
  • ReturnedTypeCode is your entity logical name, which will need changing depending on the entity you are attempting to query
  • Be sure to add in the appropriate namespace references, otherwise this code will not work.

The code example above is all very well and good if you are just wanting to create a brand new view. But what happens if you need to change it in the future? We can modify the base properties of a view (Name, Description etc.) as well as the column layout via the CRM GUI, but when we attempt to modify the filter criteria (i.e. the FetchXML query), we will notice that the option is not available to use:

View_NoFilterCriteriaButton

The next logical step would therefore be to look at creating some C# code that would take the existing view and modify the fetchXML query property. Unfortunately, Microsoft have not provided code examples on how this can be done, although it is in theory possible via the many methods at your disposal through the SDK.

Rather then spend days and potentially weeks writing a bespoke piece of code to do the job, it was then that I realised that I was being a little dense (as tends to happen) and that the Solution was sitting right in front of me. See what I did there?

Whilst the general rule of thumb is “DON’T DO IT!!” when it comes to modifying an exported solution file, it is possible to do and pretty much anything within a solution file can be changed or modified to suit a particular requirement. And, as luck would have it, modifying Public Views (either ones created by yourself or system ones) is a supported task that you can perform on the solution file:

Definitions of views for entities are included in the customizations.xml file and may be manually edited. The view editor in the application is the most commonly used tool for this purpose. Editing customizations.xml is an alternative method

Source: https://msdn.microsoft.com/en-gb/library/gg328486.aspx

So, in order to modify a custom Public Views FetchXML query, all you would need to do is:

  1. Create a temporary, unmanaged solution file containing the entity with the custom Public View you want to change.
  2. Export as an unmanaged solution, unzip and open the customizations.xml file either in Notepad, Visual Studio or the XML editor program of your choice
  3. Use Ctrl + F to locate the savedquery node of the view you wish to change. It should look like this:
<savedquery>
    <IsCustomizable>1</IsCustomizable>
    <CanBeDeleted>1</CanBeDeleted>
    <isquickfindquery>0</isquickfindquery>
    <isprivate>0</isprivate>
    <isdefault>0</isdefault>
    <returnedtypecode>1</returnedtypecode>
    <savedqueryid>{8e736028-47c7-e511-8107-3863bb345ac8}</savedqueryid>
    <layoutxml>
        <grid name="resultset" object="1" jump="firstname" select="1" preview="1" icon="1">
            <row name="result" id="accountid">
                <cell name="name" width="150" />
                <cell name="statecode" width="150" />
                <cell name="statuscode" width="150" />
                <cell name="ownerid" width="150" />
                <cell name="createdon" width="150" />
            </row>
        </grid>
    </layoutxml>
    <querytype>0</querytype>
    <fetchxml>
        <fetch version='1.0' output-format='xml-platform' mapping='logical' distinct='true'>
            <entity name='account'>
                <attribute name='createdon' />
                <attribute name='statuscode' />
                <attribute name='ownerid' />
                <attribute name='name' />
                <attribute name='statecode' />
                <attribute name='accountid' />
                <order attribute='name' descending='false' />
                <link-entity name='email' from='regardingobjectid' to='accountid' alias='ab' link-type='outer'>
                    <attribute name='regardingobjectid' />
                </link-entity>
                <link-entity name='lead' from='parentaccountid' to='accountid' alias='al' link-type='outer'>
                    <link-entity name='email' from='regardingobjectid' to='leadid' alias='lp' link-type='outer'>
                        <attribute name='regardingobjectid' />
                    </link-entity>
                </link-entity>
            <filter type='and'>
                <condition entityname='ab' attribute='regardingobjectid' operator='null' />
                <condition entityname='lp' attribute='regardingobjectid' operator='null' />
                <filter type='or'>
                    <condition entityname='ab' attribute='createdon' operator='olderthan-x-weeks' value='1' />
                    <condition entityname='ab' attribute='createdon' operator='null' />
                </filter>
            </filter>
            </entity>
        </fetch>
    </fetchxml>
    <IntroducedVersion>1.0</IntroducedVersion>
    <LocalizedNames>
        <LocalizedName description="My New View" languagecode="1033" />
    </LocalizedNames>
    <Descriptions>
        <Description description="My view created in C# for the Account entity" languagecode="1033" />
    </Descriptions></savedquery>
  1. Modify the FetchXML query within the <fetchxml> node to your updated query
  2. (Optional) If your FetchXML query is simply making changes to the filter criteria, you can skip this step. Otherwise, if you have new fields that you would like to be displayed as part of the changes, you will also need to modify the <layoutxml> node so that it contains your new fields.
  3. Save the changes back into the solution file and then import the solution back into CRM.
  4. Test your view by opening it within the application and confirm everything looks OK.

I’m sure you’ll agree that this is definitely a much easier and simple way to make changes to your view. Just be careful when working within the solution file that you don’t accidentally delete/overwrite something!

One of our company directors has a big thing for Americanisms and American spellings over the “proper” English spellings/pronunciations. So it came as no surprise that when we first showed him CRM, he immediately pointed out the default names on the Address field composite box:

CompositeAddressControl

Specifically, he didn’t like “State/Province” or “Zip/Postal Code” (for those of you who are not aware, “State/Province is the equivalent to a County over here and we refer to “Zip/Postal Code” generally as Postcode).

Being good and sympathetic fellow Englanders, our team went away to investigate. Changing the display name of each individual address field didn’t work, as you may have expected. It turns out that that the composite address fields can instead be accessed and changed using the Xrm.Page.getControl JScript method to return each individual field and then set the label accordingly. But how do we find out the name of each control to access? Microsoft have a very informative article on MSDN that goes through Composite Controls and how they operate:

From the article:

You can access the individual constituent controls displayed in the flyout by name. These controls use the following naming convention: <composite control name>_compositionLinkControl_<constituent attribute name>. To access just the address_line1 control in the address1_composite control you would use: Xrm.Page.getControl(“address1_composite_compositionLinkControl_address1_line1”).

Source: https://msdn.microsoft.com/en-gb/library/dn481581.aspx

All we need therefore is the attribute logical name for each of the constituent fields on the control and to then add this to the getControl method!

So after a quick 5-10 minutes of coding, we now how the following nice little Jscript function that fires OnLoad for all entity forms that use the Composite Address control for Address 1 and Address 2 fields:

function changeAddressLabels() {

    Xrm.Page.getControl("address1_composite_compositionLinkControl_address1_line1").setLabel("Address 1");
    Xrm.Page.getControl("address1_composite_compositionLinkControl_address1_line2").setLabel("Address 2");
    Xrm.Page.getControl("address1_composite_compositionLinkControl_address1_line3").setLabel("Address 3");
    Xrm.Page.getControl("address1_composite_compositionLinkControl_address1_city").setLabel("Town");
    Xrm.Page.getControl("address1_composite_compositionLinkControl_address1_stateorprovince").setLabel("County");
    Xrm.Page.getControl("address1_composite_compositionLinkControl_address1_postalcode").setLabel("Postal Code");
    Xrm.Page.getControl("address1_composite_compositionLinkControl_address1_country").setLabel("Country");
    Xrm.Page.getControl("address2_composite_compositionLinkControl_address2_line1").setLabel("Address 1");
    Xrm.Page.getControl("address2_composite_compositionLinkControl_address2_line2").setLabel("Address 2");
    Xrm.Page.getControl("address2_composite_compositionLinkControl_address2_line3").setLabel("Address 3");
    Xrm.Page.getControl("address2_composite_compositionLinkControl_address2_city").setLabel("Town");
    Xrm.Page.getControl("address2_composite_compositionLinkControl_address2_stateorprovince").setLabel("County");
    Xrm.Page.getControl("address2_composite_compositionLinkControl_address2_postalcode").setLabel("Postal Code");
    Xrm.Page.getControl("address2_composite_compositionLinkControl_address2_country").setLabel("Country");
}

A victory for our team and for England – cup of tea, anyone?

Does anyone else have any experience doing interesting things with Composite Controls? Please leave a comment below if you have.

Microsoft Dynamics CRM comes with a number of out of the box Security Roles that can be used in order to give users the correct permissions. Whilst this is helpful, they generally won’t be a good fit for most organisations and a custom security role will be required in order to get the correct mix of permissions. These can be either created from scratch or be based off one of the system defaults. Regardless of how you go about it, the dreaded risk of permissions errors is ever present and it can be very difficult at times to figure out which CRM feature relates to what security permission; it doesn’t help as well when some of the system entity logical names are entirely different from their display names!

A good case in point is Server-Side Synchronisation, a brilliant feature that takes a lot of the headache out of setting up your colleague’s e-mail addresses on CRM. But, if you decide to create your own custom security role in Dynamics CRM 2015 or earlier, you may end up running into this very frustrating error message when attempting to test and enable your users’ mailbox:

ServerSideSyncError

Well, at least we’ve got an error message – what does our best friend Google say? Rather annoyingly, there isn’t much that comes back search wise, not even an official page from Microsoft that provides a list of the permissions that are needed in order to use this feature.

A (not so quick) support case with Microsoft in order to find out just what permissions I need to increase/add onto my role will likely result in an answer similar to this:

“In order to resolve the issue, make a copy of an existing security role and then reduce the privileges accordingly, as there are some hidden privileges within these roles that affect this feature.”

“Hidden permissions” you say? That smells suspicious and is something that I have never come across in my working with CRM (though I am of course happy to be stood corrected). Also, what if in reducing the permissions to suit my businesses requirement, I accidentally remove the privileges that are needed for this work? Looks like I’m going to have to find out which privileges are needed the hard way.

So, after some trial and error, I can now provide a complete list of all the permissions that you need to have on your security role in order to Server Side Sync to work successfully. Please note the below assumes that you already have a separate security role setup that gives relevant permissions on the Appointment, Contacts and Activities entities within CRM:

Incoming/Outgoing E-mail

  • Email Server Profile
    • Organization level Read
  • Mailbox
    • User level Create, Read & Write

ServerSideSync_IncomingOutcomingPrivileges

Appointments, Contacts and Tasks

  • Organization
    • Organization level Read
  • Sync to Outlook
    • Full Privileges

ServerSideSync_ACTPrivileges_1

ServerSideSync_ACTPrivileges_2

 

With all of the these privileges assigned, our test and enable of the mailbox works successfully:

ServerSideSync_SuccessAlerts

Hopefully this helps someone who has spent countless hours pulling their hair out on how to get this working.

For those of you that are upgrading to CRM 2016 in the near future, there’s some good news relating to this: an extra button has been added on the error message that lets you expand it and view the system privilege name that is missing:

ServerSideSyncError_2016ErrorDetails

So based on the above message of “prvReadOrganization privilege”, we know that we need to give Read Privilege on the Organization entity! This is definitely a big help and a welcome new feature to have, as you can then go through and gradually add the permissions missing until everything is working. It’s little things like this which is making me more and more excited about upgrading to 2016 in the near future.

Does anyone else have any tips or advice on how to get certain features within CRM and what privileges are needed? Please use the comments below to share.

First of all, I cannot take credit for the solution in this post. My thanks to the awesome guys over at iTG Technologies for researching and finding the fix for this.

If your organisation is on Office 365 and is still currently running Office 2013, then you may have noticed the following message has suddenly popped up on your Office programs recently:

Office2016UpgradeMessage

The bad news is that this message turns up of it’s own accord. This is not so much a problem if you are a home/single user, but could cause huge issues for enterprise IT departments who are holding off on upgrading due to add-in compatibility, not yet being able to test the applications themselves and problems with the computer environment itself (e.g. computers not meeting the minimum/recommended specifications).

The good news is that this error message can be disabled either via a Group Policy or by making the following change within the registry on the affected computers:

HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\office\15.0\common\officeupdate

Add the following value under the office update subkey:

“enableautomaticupgrade”=dword:00000000

Source: https://support.microsoft.com/en-us/kb/3097292

Whilst it is generally better to ensure you are on the latest versions of software, Office 2016 is still very early in its overall life-cycle and it makes prudent sense to delay rolling this out across organisations for a few more months at least.

Has anyone already upgraded or rolled out Office 2016 across their organisations yet? I would be interested in hearing your views/comments on how it is working for you.

Microsoft have recently released four new exams for Dynamics CRM 2016. The first thing to point out is that these exams do not replace/supersede the exams for 2015, which are likely to stay around for at least another 2-3 years. Therefore, passing these exams should be a definite goal for anyone who works extensively with CRM or is planning on upgrading to 2016 in the near future. The four new exams are as follows:

There’s some interesting things to point out here. Microsoft have chosen not to provide an updated exam for MB2-708: Microsoft Dynamics CRM Installation, which focuses on On-Premise CRM installation and configuration. I’ve not yet been through a Dynamics CRM 2016 Server installation, so I would assume that not much has changed on this side of things. This would appear to be match up with the look and feel of CRM 2016, which is very much the same at first glance to CRM 2015 Update 1. No major changes must mean no new exam, in which case.

On first glance, the new CRM Online Deployment exam looks exactly the same – even down to the title! Look more closely however and you will see there are some major differences in the learning objectives. This bit in particular stuck out for me:

Manage related services (10% – 15%)

  • Describe related services
    • Identify related online services; integrate Microsoft Social Engagement with Microsoft Dynamics CRM Online; manage campaigns with Microsoft Dynamics Marketing
  • Integrate Yammer and SharePoint Online
    • Describe Yammer and SharePoint Online; identify SharePoint Online integration types; describe the integration process

Integrate OneNote, Skype, Skype for Business, Office 365 Groups, and OneDrive for Business

  • Compare Dynamics CRM Notes and OneNote; identify storage location for OneNote notebooks; configure OneNote integration; integrate Skype and Skype for Business; identify limitations for Skype and Skype for Business; describe Office 365 Groups; identify requirements for Office 365 Groups; integrate Office 365 Groups with Microsoft Dynamics CRM Online

As well as some of the expected mentioned platforms such as Yammer and SharePoint, the relatively recent Office 365 Groups also makes an appearance. Suffice to say, the integration element with other Microsoft applications plays a much bigger role this time around, fitting in with the general strategy behind CRM Online/Office 365. That’s great news if you are familiar with the Office 365 platform, but this may present a challenge for those who primarily have CRM On-Premise experience and are looking to make the jump onto CRM Online. Fortunately, Microsoft offers free trials of both Office 365 and CRM Online, so you can quite easily spin up a CRM Online instance and Exchange Online, SharePoint etc. so you can get up to speed.

Lastly, something which I’m disappointed about, there is no updated version of MB2-701: Extending Microsoft Dynamics CRM 2013 AKA the CRM Developers exam. The name of the exam tells you everything you need to know, it’s for CRM 2013! Whaaaaat!?! Unfortunately, CRM developers don’t seem to be getting much love these days… 🙁 Admittedly, from a developers point of view, there hasn’t been too much that has changed, however CRM 2015 Update 1 rather sneakily altered some of the supported methods for form level JScript. This has caused some issues with coding that was written pre-update 1. On the balance of things therefore, an updated Developers exam is definitely something that would be great to see and I was very much looking forward to seeing this as part of the new refreshed exam list. Looks like I will have to attempt to sit MB2-701 at some point this year instead.

I’ve already been able to sit and successfully pass MB2-712, so I’ve got my fingers crossed that I will be able to pass all three of other exams too. Better start hitting the books soon!

Do you have any advice or tips for these exams?

Due to Microsoft’s NDA relating to each of the exams, I cannot disclose any details relating to the exam and its contents (as a result, any discussion in the comments that are in breach of this will be promptly removed). My best advice is to really focus on the learning objectives for each exam and, ideally, have a CRM instance open whilst you are revising so you can get some practice as you learn new concepts. PartnerSource has some great resources to download and test your knowledge on, or you could look at attending one of the many training courses out there from Microsoft Training Providers. Those of you who have passed previous exams shouldn’t have any major trouble, but it’s always good to refresh your memory or go over things within CRM that you don’t use that often.

Good luck to anyone who is sitting these exams – particularly if it’s you first time sitting them. Let me know how you get on in the comments below.