Search This Blog

Wednesday, March 31, 2010

MSCRMTools repository


I created a dedicated site for my tools. This site is quite basic but provide links to download the tools and a small tutorial for each one of them.

I thought it is a better way to distribute the tools to my (or your) customers, partners and colleagues since it avoid to go through the blog (even if the tools are quite easily accessible).

The link:

I hope you will like it...

Saturday, March 27, 2010

Empty AsyncOperationBase table when it is too big

With one of my client, I came across a particularly disturbing issue. The symptoms were:
  • 2 minutes to delete a single record  
  • Timeout on restarting the Microsoft CRM asynchronous processing service  
  • Unable to display a view on workflows or system tasks.  
  • Incredibly long time wait for any SQL statement on AsyncOperationBase table

Passing a script on the organization database to identify the sizes of tables, I realized that two tables seem particularly large: 

  • AsyncOperationBase (800 000 lines)
  • DuplicateRecordBase (15 000 000 lines)

The total size of the database was 12GB.

After passing through the Microsoft support for a procedure to purge these tables, the answer was procedures that would require whole days of SQL processing, which was clearly not an option for a production server.

In agreement with my client, we decided to delete and recreate these tables instead of trying to empty them.

WARNING! The following procedure is of course unsupported and provided as is without any warranty.

It has the following constraints:

  • No job systems, workflow and detection of duplicates job will be retained.

  • All running workflows will also be deleted

The table that we want to delete the table is AsyncOperationBase. First thing to do, identify all the dependencies for that table. To do this, start deleing the table. The following screen appears:  


Click the dependencies in the bottom right. Here is the list of dependent components:  


Before deleting the table AsyncOperationBase, so we'll have to delete all dependent items.

Before that, he'll have to create the SQL scripts that will allow us to recreate the elements that will be deleted.
Right click on the database of the CRM organization, Tasks, Generate Scripts.


In the options for generating scripts, make sure you turn on all options for tables and views as to the screenshot below.


Then select the items that will recreate. We need tables, views and user defined functions.


Follow the wizard to generate scripts for the complete script to recreate the elements that we remove. When selecting items, you have therefore chosen only those items that were listed in the dependencies of AsyncOperationBase table.

You can now delete items that were listed in the dependencies table AsyncOperationBase. Delete the elements with no dependencies first to go back to the table AsyncOperationBase.

Once all the deleted items, use the script generated previously to recreate the elements that have been deleted.

Normally, you should have a "brand new CRM" (at least for system tasks, workflow logs, bulk deletion jobs, etc..).

For information after this procedure:  

  • The size of the database is 2GB
  • The asynchronous processing service restarts in no time
  • Record deletion is very fast 
  • Fast display of system tasks, workflow logs, etc.

After two days of intensive use of the CRM application in terms of workflow, bulk deletion, data import, there is no problem found.

Some tips to avoid swell these tables:  

  • Planning tasks to delete bulk to clean the table of system tasks regularly.
  • Disable the detection rules that are duplicates or not involving fields ever used. By default, if you create many prospect without email address, default duplicate detection rule applies and therefore generates many rows in the table DuplicationRecordBase.  

Wednesday, March 24, 2010

Tools update: Improving the speed and lightness


I just updated three of my tools to make them faster and lighter:
  • BulkDeleteLauncher
  • ViewLayoutReplicator
  • SearchablePropertyAttributeUpdater
To do that, I just cleaned the content of the web reference to keep only classes used by the tools.

The average weight of the tools was 1,2MB. It is now 350KB
Also, the first call to the crm web service is faster as there is so much less data to load

Monday, March 22, 2010

How to create a relative URL in site map to static content under the ISV folder in CRM 4

Very interesting post about the sitemap and ISV folder on the EMEA support blog:
How to create a relative URL in site map to static content under the ISV folder in CRM 4

Remove unwanted activities from web interface


I love the CRM forums because lot of people are asking very interesting question...

The last I liked was: how to remove some activities when I click on "New" button in the activities grid or when I click to the top menu "New activity".
Indeed, if you don't want to use the campaign response activity, or any other of them, you can't hide them in a native and supported way.

So, I give you some hints to hide these activities.

Please be aware that these methods are unsupported! Make a backup of each mentionned file before follwoing this procedure.

Removing an activity in the "New" activity dialog in activities grid
To remove the activity you want, open the file \Activities\dlg_create.aspx.

Search for the block in blue in the screenshot below. You can comment or delete the lines that correspond to the activities you need to hide. Then save the file.

Removing an activity from the "New activity" top menu
For this one, open the file \_root\bar_top.aspx.

Search for the function "CheckAddin()". This method is called during page loading. Add the line (see screenshot below) corresponding to the activity you need to hide.

The all list of activities id is:
  • btn_new_task
  • btn_new_fax
  • btn_new_phonecall
  • btn_new_email
  • btn_new_letter
  • btn_new_appointment
  • btn_new_serviceappointment
  • btn_new_campaignresponse
The result, if I hide the camaping response activity is below:

Saturday, March 20, 2010

New tool: AssemblyRecovery


Someone, on Microsoft CRM forums, asked how he would be able to compare plugins or workflow activities between two environments...
The obvious answer was to use Reflector to analyze the content of these assemblies.

What? You don't have the assemblies? You are not sure which version of the assembly is stored in CRM database?

No problem! Just use this new tool that allows you to display the list of custom assemblies and recover them on your disk.

As usual, the tool can be downloaded with the following link:

Tuesday, March 16, 2010

CrmDiagTool: Download location changed


As Benjamin Lecoq is leaving Microsoft, the CrmDiagTool could have been orphaned...

But no! The EMEA support team is the new hoster for this MUST HAVE tool. You can find the tool here: EMEA Support team

David Berry JavaScript Grid Editor

David Berry developed an awesome javascript to allow the grids to be editable...

See his blog:

Thursday, March 11, 2010

Tool Update: Form Javascript Manager


Thanks to Andrew Zimmer, a bug has been corrected in the tool.

This bug made the tool decoding the HTML characters that were encoded when exporting the customizations. So when you were importing them back, the HTML characters were no more encoded...

You can download this latest version from the usual location (right pane of the blog) 

Tuesday, March 9, 2010

Survey available


Just to inform you that I put a survey on the top right part of this blog...

Thank you for your participation!

Update: Access Checker

Thanks to Andrew request (see previous post comments), I uploaded a new version of the tool.

New features:
  • Tooltip on each privilege to see the privilege ID
  • A "name" resolution is made against the object ID specified (I use the primary attribute of the entity)

I will focus next on the peformance of the tool (I need to do some clean up on the CrmService reference to speed the tool)...


Friday, March 5, 2010

New tool: Access Checker

Hello everyone,

It's been a while that I'm back but I have a lot of work and so little time for this blog.

However, things promise is a promise, here is a small tool that could make your life easier.

Have you ever encountered this error message:

SecLib::AccessCheckEx failed. Returned hr = -2147187962, ObjectID: 1ef9f412-6601-dd11-8655-0019b9dfe618, OwningUser: 98bbc999-96a2-de11-aeaf-0019b9dfe227 and CallingUser: 037c1c90-96a2-de11-aeaf-0019b9dfe227

You do not really know what object and what user it is and especially what rights might fail him. With this tool, you can put all these IDs and know what are the privileges of the user regarding this record.

With this tool, you can:

  • Indicate which entity you want to inspect
  • Enter the identifier of the object in question
  • Searching for a user with its name or its unique identifier
Click the “Retrieve rights” button and the program will tell you what rights the user with respect to the record.

As usual, if you need improvment or detect a bug, do not hesitate to contact me

The tool can be downloaded just below (and in the archive with all tools)