Issue in editable grids: You must enter a number between -1000000 and 1000000

Last week, around June 30 2018, this bug showed up from nowhere. It’s thus a problem in editable grids, related to currency numbers apparently.

After searching the web and finding nothing, I reached the conclusion that it was a Microsoft bug… not always easy to convince the customers though. However, since this bug is online and showed up right after the update to Dynamics 365 Version 1612 (8.2.2.1960).

This is the link to the page describing the update in question, service update 14 for Dyamics 365 8.2.2.
https://support.microsoft.com/en-us/help/4338685/service-update-14-for-microsoft-dynamics-365-8-2-2

And, on July 2nd, a new thread appeared on community.dynamics.com discussing the issue, only confirming it.
https://community.dynamics.com/crm/f/117/t/286234

So as you can see, the only thing to do here is open a ticket to Microsoft support, and wait…
I hope they react quickly as for many customers, this is a show stopper for editable grids.

 

 

How to prevent meeting requests to be sent with Server Side Sync

What we did at my customer is the following:

  • Add a custom checkbox on the appointment: “Send meeting request”, unchecked by default
  • With a plugin, make sure that for every appointment, the subject is appended with a tag like ” – DONOTSENDMR”
  • Create an Exchange Transport Rule that prevents any calendaring message to be sent whenever the subject contains that tag
  • Make sure that when the checkbox is checked, the tag is removed, thus allowing the meeting request to be sent

Of course, doing so means that the tag will be synced as is in the calendar.

CRM 2011: Change disabled button tooltip text

Guys, this is a nice one, just finished it! And I am quite happy with it.
When a button is disabled, your users will – and with reason – sometimes wonder why. The most logical place to display the reasons is in the tooltip, at least I think so.

So, how to do that?

1. In the function enabling/disabling the button, prepare a string with the reason(s)

2. Find the button id, using chrome or firefox web developer tools

3. More difficult, find the existing tooltip box id. Not so easy as it disappears as soon as the mouse leaves the button… Simple anyway: with Chrome dev tools open in a separate window, bring that window just under your disabled button, even covering it a little. So that moving the mouse on the button shows the tooltip, and that you can then switch to the dev window with the tooltip still open. In the elements tab, scroll down to the bottom, and watch a nice <span> element show, that looks like below. Copy the id and replace TOOLTIPID with it in the javascript code.

 

<span unselectable=”on” class=”ms-cui-tooltip” id=”new_entity|NoRelationship|Form|ipm.Form.new_entity.MyButton_ToolTip” role=”tooltip” aria-hidden=”false” style=”visibility: visible; position: absolute; top: 135px; left: 286px; min-width: 210px;”>
<div unselectable=”on” class=”ms-cui-tooltip-body”>
<div unselectable=”on” class=”ms-cui-tooltip-glow”>
<h1 unselectable=”on”>Temporary Suspension</h1>
<div unselectable=”on” class=”ms-cui-tooltip-description”>Temporary Suspension Description</div>
<div unselectable=”on” class=”ms-cui-tooltip-clear”></div>
<hr unselectable=”on”>
<div unselectable=”on” class=”ms-cui-tooltip-footer”>
<span unselectable=”on” class=” ms-cui-img-16by16 ms-cui-img-cont-float” style=”vertical-align: top;”></span>
<div unselectable=”on”>This button is currently disabled.</div>
</div>
<div unselectable=”on” class=”ms-cui-tooltip-description” style=”width: 90%;”>You may not have selected the item that works with this feature. If you do not have permissions to use this feature, contact your system administrator.</div>
</div>
</div>
</span>

 

4. Before returning true or false, if false, call this function, with the message. Replace BUTTONID with the appropriate value. It will be something long and with pipes (|) in it

function showDisabledReason(msg) {

// Get button
var link = window.parent.document.getElementById(‘BUTTONID’);

// Add custom tooltip
$(link, window.parent.document).hover(
function() { tryShowReason(msg); },
function() { }
);
return;

}

 

function tryShowReason(msg) {

var tooltip = manageToolTip(msg);
if (!tooltip) {
setTimeout(function () {
tryShowReason(msg);
}, 200);
}

}
function manageToolTip(msg) {
var tip = window.parent.document.getElementById(‘TOOLTIPID’);
if (tip) replaceToolTip(tip, msg);
return tip;
}
function replaceToolTip(tooltip, msg) {
$(tooltip).find(‘.ms-cui-tooltip-description:nth(1)’).html(msg);
}

 

And you’re done!!!

In the contact entity, modify the related orders default view

That one is extremely tricky. My customer had this sweet, short request: change the default view of related orders, in the contact entity.

RelatedOrders

By default, the defaule view is set to “Active”, and the customer wanted it to be “All”. How to do that? Well, here’s the answer below. It took me 5 hours to come up with this solution, but it works.
Highly unsupported if course…

Here’s the code below:

function setDefaultView() {
var grid = document.getElementById(“crmGrid_order_customer_contacts”);
    if (grid) {
        XMLHttpRequest.prototype.reallysend = XMLHttpRequest.prototype.send;
        XMLHttpRequest.prototype.send = function (body) {
            var that = this;
            if (body) {
                body = body.replace(‘<statecode>0</statecode>’, ‘<statecode>All</statecode>’);
                body = body.replace(‘<statecode>1</statecode>’, ‘<statecode>All</statecode>’);
                body = body.replace(‘<statecode>2</statecode>’, ‘<statecode>All</statecode>’);
                body = body.replace(‘<statecode>3</statecode>’, ‘<statecode>All</statecode>’);
                body = body.replace(‘<statecode>4</statecode>’, ‘<statecode>All</statecode>’);
            }
            this.onreadystatechange = function () {
                if (this.responseXML && XMLHttpRequest.prototype.reallysend) {
                    XMLHttpRequest.prototype.send = XMLHttpRequest.prototype.reallysend;
                    XMLHttpRequest.prototype.reallysend = null;
                }
            }
            return this.reallysend(body);
        }
        $(‘#crmGrid_order_customer_contacts_statecode’).find(‘option[value=”All”]’).prop(‘selected’, ‘selected’);
        grid.control.refresh();
}
This deserves a few explanations and configurations:
  1. I use jQuery to change the selected option in the picklist. However, and of course, this doesn’t change the displayed data. And, a call to refresh after changing this value, does not get the right data. It still retrieves only the active records. So to access jquery in this code, as we are in the context of an associated view, I use the ribbon trick (could also have deleted the js web resource directly and evaled it).
  2. I use a global variable, ouch. So I name it carefully.
  3. I replace the send function of the XMLHttpRequest object… That becomes sweet… 🙂 The point is to replace, in the message sent to the server, the statecode 0, by All, so that all records are retrieved, instead of the active ones.
  4. After the first pass, I reset the original send function, otherwise the replace will be applied to all subsequent queries, always retrieving all the records…

And here you go, a nice related view, with the default filter being set on ‘All’ !

That one is my pride. 🙂

Dynamics CRM and SPNs

Maybe you’ve already heard of SPNs, also known as Service Principal Names. Most CRM technical people have heard of them, but not many can really explain WHY they are necessary. Some can say it is for ensuring “mutual authentication”, but few can really explain how this mechanism works.

Today, let me explain to you my understanding of SPN’s, based on this article.

The Kerberos mechanism by which a client authenticates a service works as follows:

  • When a service is installed, a service installer, running with administrator privileges, registers one or more unique SPNs for each service instance.
  • The names are registered in the Active Directory Domain Controller (DC) on the user or computer account object that the service instance will use to log on.
  • When a client requests a connection to a service, it composes an SPN for a service instance, using known data or data provided by the user.
  • The client then uses the SSPI negotiate package to present the SPN to the Key Distribution Center (KDC) for the client domain account.
  • The KDC searches the forest for a user or computer account on which that SPN is registered.
  • If the SPN is registered on more than one account, the authentication fails.
  • Otherwise, the KDC encrypts a message using the password of the account on which the SPN was registered.
  • The KDC passes this encrypted message to the client, which in turn passes it to the service instance.
  • The service uses the SSPI negotiate package to decrypt the message, which it passes back to the client and on to the client’s KDC.
  • The KDC authenticates the service if the decrypted message matches its original message.

Let me rephrase this in the CRM world:

  • When CRM is installed, SPNs are registered for the identity of the application pool CRMAppPool. It can be Network Service or some other account.
    • That’s why, when changing the identity of the application pool, you need to remove existing SPNs and create new ones.
  • When a client requests a connection to CRM, it composes an SPN for it.
    • That’s why you need to register SPNs for both server the server name and the FQDN, because you can’t be sure how the SPN will be composed by the client.
  • (1) The client presents the SPN to the KDC for the client domain account
  • (2) The KDC searches the domain for a user or computer account on which that SPN is registered
    • Here, the KDC must find the identity of the CRMAppPool
  • If the SPN is registered on more than one account, the authentication will fail
    • Indeed, because the KDC will not know which account to use
  • The KDC encrypts a message with the password of the CRMAppPool identity
  • (3 & 4) The KDC passes the message to the client, which passes it to the service instance, ie to the CRM server
  • (5 & 6) The CRM server can decrypt the message, passes it back to the client which passes it back to the KDC

So that’s why we talk about mutual authentication: not only is the client identified (this aspect is not described here), but also the service.

CRM 2011: how to know when the form is coming back from Save

To put it another way: how can you make the difference between a load when the form is first opened, and a reload after a save for example?

A simple way to achieve this is to use the status or defaultStatus properties of the window object. Both Status and defaultStatus can be used to set the text displayed in the status bar at the bottom of the browser. When setting one of these properties before a save is performed, you can access them upon reload and they will have kept the new value. Example:

window.status = “reload”;

That’s the easiest way I’ve found to achieve this!

The Plugin Profiler

I recently discovered the Dynamics CRM plugin profiler.

The Plug-in Profiler is a tool that profiles the execution of plug-ins for an enhanced debugging experience in Microsoft Visual Studio 2010. This tool, which can be run from the Command Prompt window or from within the Plug-in Registration tool, makes developing plug-ins against Microsoft Dynamics CRM 2011 and Microsoft Dynamics CRM Online quicker and easier. In addition, users can profile the execution of failing plug-ins and send the results to the plug-in developer or ISV for analysis. The developer can replay the plug-in execution and debug the plug-in remotely even when disconnected from the Microsoft Dynamics CRM server. The Plug-in Profiler is available in the 5.0.5 release and newer releases of the Microsoft Dynamics CRM SDK

The tool can be used in either the debug or replay mode. Each of these modes is described in the following sections.

1. Debug a Plug-in using the Plug-in Profiler

To debug a plug-in

  1. Build the Plug-in Registration tool according to the instructions in its Readme file. The tool can be found in the ToolsPluginRegistration folder of the SDK download.
  2. Run the Plug-in Registration tool.
  3. Connect to a Microsoft Dynamics CRM server and organization. For more information on connecting to a server and organization, refer to the SDK topic: Walkthrough: Register a Plug-in Using the Plug-in Registration Tool.
  4. Register a plug-in and step on the Microsoft Dynamics CRM server. Keep a copy of the debug compiled plug-in assembly on the computer where you are running the tool.
  5. In the tool’s main window, select Install Profiler. You will now see a Plug-in Profiler node in the list.
  6. Select a plug-in step and click Profile to enable profiling.
  7. Perform the operation in Microsoft Dynamics CRM that causes the plug-in to run. For example, if the step is configured for an update to an account, then update an account.
  8. After the plug-in throws an exception and the Business Process Error dialog is displayed, click Download Log File and save this file. Alternately, if the plug-in does not throw an exception, click Stop Profiling.
  9. In the Plug-in Registration tool, click Debug.
  10. In the Debug Existing Plug-in dialog box, provide the location of the previously saved log file.
  11. In Step #2, specify the location of the plug-in assembly.
  12. Launch Visual Studio 2010 and attach the debugger to the PluginRegistration.exe process.
  13. Set a breakpoint in the plug-in code.
  14. Click Start Plug-in Execution in the Debug Existing Plug-in dialog box.
  15. After a slight delay, the plug-in will execute using the same execution context that was passed to it by the Microsoft Dynamics CRM server and the debugger will stop execution on the breakpoint that you previously set.
  16. Continue debugging the plug-in as you would normally do. Any traces that the plug-in outputs are shown in the Debug Existing Plug-in dialog box.

At this point you can alter the plug-in code, build it, re-attach the debugger to the PluginRegistration.exe process, and click Start Plug-in Execution to continue with your debugging session. While performing these operations, you do not need to close the Debug Existing Plug-in form.

You do not need to re-deploy the plug-in to the Microsoft Dynamics CRM server until after you have fixed the code problem. This debugging scenario works even if you have an optimized version of the plug-in on the server and a debug version of the plug-in on the computer where you are debugging.

2. Replay Plug-in Execution

Replaying plug-in execution does not require a connection to a Microsoft Dynamics CRM server and organization. The advantage of this method is that you can obtain the plug-in execution profile from a customer and debug the plug-in remotely. A restriction of the replay feature is that you cannot change the sequence of calls your plug-in code makes in the debugger while you are debugging.

The replay feature provides the plug-in with a snapshot of the call data and event execution context from the Microsoft Dynamics CRM server. You are getting the same events, GUIDs, and so on from calls to the Organization service but no data is being modified on the server as you debug the plug-in. During the debugging procedure in the previous section, the plug-in actually connects to the server and makes calls in real time.

To replay plug-in execution

  1. Launch Visual Studio 2010 and attach the debugger to the PluginRegistration.exe process.
  2. Click Replay Plug-in Execution in the Debug Existing Plug-in dialog box.
  3. Enter the log and plug-in assembly locations in the dialog box.
  4. Click Start Plug-in Execution.
  5. Debug the plug-in as you would normally.

 

3. Run the Plug-in Profiler Standalone

The profiler can be executed from a Prompt window independent of the Plug-in Registration tool. This is useful to obtain the plug-in profile log from a customer’s Microsoft Dynamics CRM server to debug a failed plug-in. A developer can then use that log to replay the plug-in’s execution in the Plug-in Registration tool and debug the plug-in using Visual Studio 2010.

To run the plug-in profiler from a command prompt

  1. Open a Command Prompt window and set the working directory to the Bin folder in the SDK download.
  2. Type the command: PluginProfiler.Debugger.exe /?.
  3. Review the supported parameter list and re-run the PluginProfiler.Debugger.exe program with the appropriate parameters.

Optimizing and Maitaining the Peformance of a CRM 2011 Infrastructure – Part 2

Second part of the series: the Application tier.

Content:

  • 2.1 Optimizing and Maintaining Microsoft Windows Server
  • 2.2 Optimizing and Maintaining the Microsoft .NET Framework and Microsoft .NET Applications
  • 2.3 Optimizing and Maintaining Internet Information Services
  • 2.4 Optimizing the Performance of Microsoft Dynamics CRM Server 2011
  • 2.5 Optimizing Microsoft Dynamics CRM Reporting Services
  • 2.6 Optimizing Report Performance
  • 2.7 Best Practices for Optimizing Workflow

 

2. Optimizing and Maintaining the Application Tier

2.1 Optimizing and Maintaining Microsoft Windows Server

    • See the Performance Tuning Guidelines for Windows Server 2008 R2
    • Increasing the Ephemeral TCP Port Limit:
      • In some situations, you may want to reserve a range of ports so that a program or process that requests a random port will not be assigned a port that is in the reserved range. The ports in that range are called ephemeral ports. In rare cases there may be no free ephemeral ports available, which will cause the connection open to fail or time out.
      • To view the current range of ephemeral ports: netsh int <ipv4|ipv6> show dynamicport <tcp|udp>
      • To change the current range of ephemeral ports: netsh int <ipv4|ipv6> set dynamic <tcp|udp> start=number num=range
      • To increase the maximum number of ephemeral TCP ports: navigate to HKEY_LOCAL_MACHINESYSTEMCurrentControlSetServicesTcpipParameters.Create a registry entry by using the following information:
        Value Name: MaxUserPort
        Value Type: DWORD
        Value data: 65534
        Valid Range: 5000-65534 (decimal)
        Default: 0x1388 (5000 decimal)
        Description: Controls the maximum port number used when a program requests any available user port from the system. Typically, ephemeral (short-lived) ports are allocated between the values of 1024 and 5000, inclusive.
    • Monitoring the Performance of Microsoft Windows Server: Microsoft Windows Server provides performance counters that you can use to help identify potential performance bottlenecks associated with memory and the cache, processors (and multi-processor computers), physical disks, and the network infrastructure. Remember to monitor each disk and processor used by the operating system. Check the TechNet article Performance and Reliability Monitoring Step-by-Step Guide for Windows Server 2008.

 

2.2 Optimizing and Maintaining the Microsoft .NET Framework and Microsoft .NET Applications

      • Optimizing the Performance of the Microsoft .NET Framework: Configuring the .NET Framework for optimal performance involves tuning the common language runtime (CLR) and then, depending on the nature of any specific application, tuning the associated .NET Framework technology, for example ASP.NET-connected applications, Web services, Enterprise Services, and ADO.NET code. Consider the potential issues: (see here for more information)
Potential issue Description
Memory misuse Creating too many objects, or failing to properly release resources, pre-allocate memory, or explicitly force garbage collection can prevent the CLR from efficiently managing memory, which can lead to an increased working set size.
Resource cleanup Implementing finalizers unnecessarily, failing to suppress finalization in the Dispose method, or failing to release unmanaged resources can lead to unnecessary delays in reclaiming resources and can potentially create resource leaks.
Improper use of threads Creating threads on a per-request basis and not sharing threads using thread pools can cause performance and scalability bottlenecks for server applications.
Abusing shared resources Creating resources per request can lead to resource pressure, and failing to properly release shared resources can cause delays in reclaiming them.
Type conversions Implicit type conversions and mixing value and reference types leads to excessive boxing and unboxing operations.
Misuse of collections Each collection type in the .NET Framework class library is designed to meet specific storage and access requirements; they may not perform optimally outside of those requirements.
Inefficient loops Looping magnifies even the slightest coding inefficiency, and loops that access an object’s properties are a common culprit of performance bottlenecks, particularly if the object is remote or the property getter performs significant work.

 

2.3 Optimizing and Maintaining Internet Information Services

      • Optimizing the Performance of Internet Information Services: Optimizing the performance of Microsoft Internet Information Services (IIS) within a Microsoft Dynamics CRM 2011 implementation benefits not only the overall system, but also any custom applications, plug-ins, or add-ins that have been developed by using the Microsoft Dynamics CRM 2011 SDK.
      • Optimizing the Performance of Integrated Windows Authentication and Kerberos Authentication
        • In Internet Explorer, ensure that “Enable Integrated Windows Authentication” is set to enable use of Kerberos for integrated authentication.
        • There is a known issue where users are members of too many groups to be communicated in a UDP packet. It is possible to get Kerberos to use TCP rather than UDP, which enables larger packets of information.
        • To determine whether users are connecting via Kerberos, in the registry, enable Kerberos logging. If necessary, to help diagnose whether the user can obtain and use a Kerberos ticket, use applications such as Kerbtray
      • On IIS, tracing and debugging, while disabled by default, may cause performance issues if enabled.
      • Optimizing Microsoft .NET ThreadPool Settings: if each .aspx page makes a Web service call to a single IP address, it is recommended to adjust these parameters as shown in the following table.
Parameter Value
maxWorkerThreads 100
maxIoThreads 100
maxconnection 12*n (where n is the number of CPUs)
minFreeThreads 88*n
minLocalRequestFreeThreads 76*n
minWorkerThreads 50 (manually add this parameter and value to the file)
    • Monitoring the Performance of Internet Information Services: One of the key counters to monitor and measure against a baseline is the %Process Time for the inetinfo (IIS).

 

2.4 Optimizing the Performance of Microsoft Dynamics CRM Server 2011

      • Disable platform tracing
      • Verify that the computers meet the hardware and software requirements
      • Enhancing Performance by Distributing Server Roles on Multiple Servers
      • Throttling Client Synchronization Processes
      • Limiting the Number of Records Returned by Aggregate Queries
      • Applying RetrieveMultiple Query Optimizations for large data sets
      • Setting the Default View to a smaller view to limit the records that are displayed
      • Customizing Quick Find Views by Limiting Search Columns
      • Leveraging teams instead of an excessively complex business hierarchy because teams will provide better performance with a lower penalty for security checks
      • Use Field Level Security (FLS) wisely, since there is a performance impact associated with using FLS
      • When changing the order of records returned by a saved query, consider adding an index based on the new ordering to improve the performance of the query
      • Use an iterative process to determine which index best optimizes query performance
      • Disabling Auto-Complete on Lookups
      • To optimize the performance of queries on custom entities, ensure that all columns on the ORDER BY clause derive from a single table, and build an index that satisfies the ORDER BY requirements and as much of the query’s
      • A specific recommendation for any custom application is to limit any columns and rows retrieved to those required to achieve the application’s business goals.WHERE clause selection criteria as possible.

 

2.5 Optimizing Microsoft Dynamics CRM Reporting Services

  • Report processing and rendering are memory intensive operations, so ensure that the computer hosting the report server includes ample memory.
  • Host the report server and the report server database on separate computers rather than hosting both on a single high-end computer.
  • If all reports are processing slowly, consider a scale-out deployment with multiple report server instances. For best results, use load balancing software and hardware to distribute requests evenly across multiple report servers in the deployment. If load balancing is used, it is advisable to use client affinity to avoid loading the session cache in memory on multiple servers.
  • If a single report is processing slowly, tune the query if the report must run on demand. You might also consider caching the report or running it as a snapshot.
  • If all reports process slowly in a specific format (for example, while rendering to PDF), consider file share delivery, adding more memory, or using another format.

 

2.6 Optimizing Report Performance

  • Guidelines
    • Configure reports to display data from a specified time frame, for example the previous 90 days, rather than displaying all records in the Microsoft Dynamics CRM database.
    • Reports with a large dataset or a complex SQL query should not be available to all users on-demand. Instead, schedule a snapshot in Report Manager during a period when the system is lightly loaded.
    • Deploy reports through Microsoft Dynamics CRM, and then use Report Manager to run the reports and have the results posted at a scheduled time.
    • Reports should access the fewest datasets possible to meet business requirements.
    • When possible, use fetch based reports, which are much more efficient than SQL-based reports, to run against Filtered Views.
    • Consider using subreports. Show aggregated information in a report initially, and then use subreports for drilling down on aggregates to show non-aggregated values. Using this technique will prevent Report Server aggregations and improve performance.
    • Use explicit paging for reports that require bringing large amounts of data to the Reporting Services middle tier. Build reports so that they show only a page of the total records at one time and have explicit clickable links to bring in data for further pages. Although Report Viewer control shows paging control on reports, all the data needed for the full report has already been pulled from the middle tier.
  • Techniques
    • Use SQL “Group By”: This helps to prevent the computer running Microsoft SQL Server from being overtaxed with gathering, transmitting, and then processing large volumes of data. Instead, it uses the natural indexing and grouping ability of SQL Server to massively reduce this overhead.
    • Making Reports Pre-Filterable (CRMAF_)
    • Using Dynamic Excel or Filtered View Queries: make reports restrictive, verify that a non-clustered index exists on fields in the where clause
    • Throttling Resources used for Reports and Data Visualizations: If a query is sent for reporting purposes, it is tagged with MSCRMReportsGroup. If it is sent for data visualization, it is tagged with MSCRMVisualizationsGroup. See Managing SQL Server Workloads with Resource Governor.

2.7 Best Practices for Optimizing Workflow

  • Determine the appropriate security/permissions model for workflow.
  • Use the Scope property judiciously.
  • Review workflow logic carefully.
  • To improve performance in large deployments, scale out as necessary
  • Monitor the Microsoft Dynamics CRM 2011 database for excess workflow log records.

Optimizing and Maitaining the Peformance of a CRM 2011 Infrastructure – Part 1

This is a summary of this white paper, to use as a quick reference when necessary.
This summary will come in different parts. I’ll update this posts with links to the new posts as they come.

Part 1. Server-Side Techniques for Optimizing the Client Tier

1.1 Using Compression Techniques

    • Configuring HTTP Compression. Note: Compression of dynamic application responses can affect CPU resources because IIS does not cache compressed versions of dynamic output. So use it only on servers that have slow network connections but that have CPU time to spare. Note that caching compressed static responses does not consume CPU resources.
    • Using WAN Accelerator Hardware: To address latency issues, several vendors offer web-acceleration appliances that improve the performance of applications such as Microsoft Dynamics CRM, and using these devices can greatly improve Microsoft Dynamics CRM performance over the WAN. Using WAN accelerator hardware can help improve performance especially in on-premises scenarios with a geographically distributed deployment in which users are distributed around the world and performance for users in a specific location is not satisfactory.

1.2. Configuring Proxy Server Settings

    • Configuring Proxy Server Settings: For on-premises deployments of Microsoft Dynamics CRM 2011 within a local area network, client computers can achieve much higher throughput by completely bypassing the proxy server, as long as the fully qualified domain name of the Microsoft Dynamics CRM server is listed as an exception.

1.3 Reducing E-Mail Traffic by Modifying Outlook Rules:

    • For deployments with the E-mail router configured to use a forward mailbox strategy, when users only track Microsoft Dynamics CRM e-mails, then configure Outlook to forward only messages that include CRM: in the subject or body.


Optimizing and Maintaining the Performance of CRM Clients

 

This is the title of a White Paper that was published by Microsoft and that is available for download here.

I’d like to summarize this white paper, as a quick reference for a future use.

1. In general

  • Use IE9
  • Set Power Settings to “High Performance” (under “Show additional plans”)
  • Turn off other non-critical applications
  • Disable other Outlook add-ins
  • Exclude CRM pages from AntiVirus scans
  • Ensure network’s latency is under 150 milliseconds
  • Limit the number of columns, grids and subgrids, records per page, controls on a form, controls on the ribbon, client side events
  • Limit the complexity of Javascript, plugins, dashboards
2. For Internet Explorer:
  • Increase the amount of hard disk space that is reserved for temporary Internet files (the closer to 250 MB, the better)
  • Increase the number of files that can be downloaded at one time to 10
    • For IE7 and before: HKEY_CURRENT_USERSoftwareMicrosoftWindowsCurrentVersionInternet Settings, new dword values: MaxConnectionsPer1_0Server to 10, and MaxConnectionsPerServer to 10
    • For IE8 and later:
      HKEY_LOCAL_MACHINESOFTWAREMicrosoftInternet ExplorerMAINFeatureControlFEATURE_MAXCONNECTIONSPERSERVER
      new dword value: iexplore.exe, 10
    • This can also be done with group policy: under Local Group Policy, under User Configuration, navigate to: Administrative TemplatesWindows ComponentsInternet ExplorerSecurity FeaturesAJAX and specify the appropriate values for the Maximum number of connections per server (HTTP 1.0) and Maximum number of connections per server (HTTP 1.1)
  • Set ie zoom to 100%

3. For the Outlook Client:

  • Configure the Outlook filters to affect as few records as possible
  • Configure the synchronization process to occur as infrequently as possible
  • Modify the frequency of the background polling activities. The table below lists the registry keys associated with activity:
Registry Entry Unit of Measure Default Duration/Value Registry Subkey (in HKEY_CURRENT_USERSoftwareMicrosoft) Suggested Testing
NotificationPollInterval Msec 180000 (Decimal) MSCRMClient Increment to 3600000 (Decimal)
StateManagerPollInterval Min 5 (Decimal) MSCRMClient Increment to 10 (Decimal)
TagPollingPeriod Msec 300000 (Decimal) MSCRMClient{ORGGUID} Increment to 600000 (Decimal)
TagMaxAggressiveCycles Not Applicable 2 MSCRMClient{ORGGUID} Set to 0
ActiveCachesUpdatingPeriodMilliseconds Msec 1500000 (Decimal) MSCRMClient Increment to 3000000 (Decimal)
IncrementalDataCachesInclusionUpdatingPeriodMilliseconds Msec 300000 (Decimal) MSCRMClient Increment to 6000000 (Decimal)
IncrementalDataCachesExclusionUpdatingPeriodMilliseconds Msec 300000 (Decimal) MSCRMClient Increment to 6000000 (Decimal)
  • Optimize Address Book performance by configuring the Address Book to match only against the contacts that are synchronized to Microsoft Dynamics CRM and to retrieve updates as infrequently as possible without compromising business requirements
  • With Microsoft Dynamics CRM for Outlook, users can “pin” views so they always display when a user logs in to Outlook. Pinned views, which are stored in cache, respond more quickly than do standard views, so be sure that suggest that users “pin” the views with which they most commonly interact. Note: Each pinned view consumes system resources (memory), so balance the use of pinned views against the need for system resources.
  • Optimize the offline synchronization process
    • Assign all users roles with the minimum access levels
    • Whenever possible, avoid using “Parent downloaded=true” and sliding time windows.
    • Implement local data filtering for each offline client to ensure that users have offline access only to the data required to perform their job functions
    • Configure offline synchronization to run in the background periodically, for example every 15 minutes, to improve performance

4. About CRM Customzation:

  • Use Javascript, columns, grids, iFrames, subgrids judiciously
  • Use role-based forms to limit the fields that display on a form
  • Adjust security roles to limit the functionality presented to users
  • Consider the complexity and number of visualizations used in the dashboards
  • Limit the number of rows that are returned per page
  • Hide the Get Started pane