Books regarding Dynamics CRM 4.0

Today an article of mine has been posted to the Dynamics CRM Team blog as a guest post. This article discusses all the books which are currently available for Dynamics CRM 4.0. Next to these books you can of course get a lot of information in trainings, MOC's, the SDK and from the internet. Drop by at the team blog to look at which books are available and which matches your needs.

Dynamics CRM Report Modification Walkthrough

There are quite some reports in the out of the box installation of Dynamics CRM 4.0, but these sometimes do not match the exact business requirements. Also the reports which can be created by using the Dynamics CRM Report Builder Wizard cannot contain complex calculations or information of more than two entities. When you do export one of these reports and try to edit this in Visual Studio, then you will end up with errors. This post will guide you through these errors and modify a default report. For this example we will change the default “User Summary” report. This of course works for reports generated with the Report Wizard as well.

Exporting a report
The first step is to download a report from Dynamics CRM. You can do this by browsing to the Workplace and open the reports are. In the grid select the report which you want to modify and press “Edit Report”.

Clicking on “Edit Report” will open the Report Detail page. On this page click “Actions” and select “Download Report”. This will let you download the *.rdl file which is the definition of the report. Save this file to some location on your hard drive.

Opening the report in Visual Studio 2005
Keep in mind that the report must be opened in an editor which supports the rdl for SQL Server 2005. For Visual Studio this is version 2005. With 2008 you cannot change report files for CRM. When you directly open the report in Visual Studio you will see that the xml viewer will be opened.

Although you can modify a report in XML, there is an easier way to modify reports in Visual Studio. You will first need to set up a project for Reports. In Visual Studio select the “Report Server Project” from the “Business Intelligence Projects” group. If this is not available, install the “Business Intelligence Development Studio Add-In for Visual Studio 2005” from the SQL Server installation CD.

From the “Solution Explorer” right click on “Reports” and add an existing Report. From the report selection screen select the report which you have saved in the previous step.

The report will now be added to the solution under the reports tree view item. When you open this report now, you will get into a mode in which you can modify the report.

Connecting to Dynamics CRM
The report does have three tabs for defining the dataset, modifying the layout and previewing the report output. The first step in changing a report is to change the dataset. Every report which is exported from Dynamics CRM does have a hardcoded data source set. This will need to be changed to your current environment before you can modify the report. To do this click on the “Data” tab. You will get the following error message.
A connection cannot be made to the database. Set and test the connection string:

This is the message specifying the situation as I have just described. Just click “OK” and let’s change the data source. To do this click on the “…” next to the dataset pick list.

This will give you the “Dataset” detail form. On this form click on “…” next to the data source picklist.

This will give you the “Data Source” detail form. On this screen click on Edit next to the connection string.

This will give you the “Connection Properties” detail form. On this page verify that the server name is correct. Also select the correct database name. This should be in the format of “organizationname_MSCRM”.

After clicking on “OK” several times you will get back to the main screen. This will be refreshed and more information will be visible now.

Changing the Query
Now that a connection is created you can change the query. Unfortunately there is not just a single query. There are multiple Datasets with each a separate query. You’ll first need to find the correct Dataset before you start changing the query. By looking at the queries you will probably be able to determine which dataset you should use. Most likely the query starts with the declaration of a dynamic query like “Declare @SQL Varchar(4000)”.
Once you have found the query you can modify the query. I do expect that the people reading this article do have knowledge of how to change these queries, if not than you might want to find somebody else to change the query for you.
Once the query is modified and does return the attributes you want to use in your report, then there is an important step you should execute. If you miss the following steps, then you’ll get this error messsage “An error occurred during the local report processing. The definition of the report '/User Summary' is invalid.”. For some reason Visual Studio removes the “Fields” from the dataset. This basically is the mapping between the attributes returned by the query and the variables used in the report. You can verify that the list of Fields is empty by opening the Dataset detail form (click on the “…” next to the dataset pick list). On the Dataset detail form click “Fields”.

You can manually enter each of the fields and values, but you can also let Visual Studio regenerate this list. To generate this list you can click the “Refresh Fields” in the Dataset toolbar.

Clicking this toolbar button will ask you to define query parameters.

This screen doesn’t automatically fill the default values, but the values are available in the report though. You can find the values which you should fill in here on the “Report Parameters”. You can access these from the “Layout“ tab. Somewhere on the layout screen right click outside of the report somewhere on the yellow piece. This will give you a context menu where you can select the “Report Parameters”.

On the “Report Parameters” form you can select the property on the left side on the screen and at the right bottom you can find the default value for the selected property.

Copy the default value and past this into the “Parameter Value” for the “Parameter Name”.

Now click “OK” and the query is changed AND you can use the selected attributes in the report layout editor.

Changing the Layout
The layout can be changed on the “Layout” tab of the report. There are many possibilities to change the layout, but I won’t dive into the Reporting Services possibilities. I will just show how to add the field which is added to the query, but for more information you should look into Reporting Services trainings.
To add a field to the result table select the table and right click on the header. You’ll now get a context menu which will allow you to add a row group. This is the value you need to select to add a column. In the “Expression” field you should select your newly added attribute in this format “=Fields!address1_fax.Value”. For the label you could add a Textbox from the toolbox and change its properties to match the existing labels, but you could also just copy an existing label and change the text value.

Previewing the Report
To review the report, just click the “Preview” tab. If necessary you can go back to the Layout or Data tab to change the report. When you are ready, then save the report to an *.rdl file.

Updating the report in CRM
In Dynamics CRM, go back to the Reports area in the Workplace module. In the grid select the report which you have just modified. In the toolbar click on “Edit Report”.

On the Report detail form select the saved report definition file by using the browse button for the file location. Now press “Save” or “Save and Close” and your report is updated with your new definition file. From CRM you can now run the updated report.

More Convergence!

The Convergence EMEA is just one week away. I do now have more information available about my planning for that week. You'll find me at the following times at the following locations:

Tuesday 18: 17:30-19:00 MS Pavillion CRM Booth Kiosks 33-36
Wednesday 19: 17:00-18:30 MS Pavillion CRM Booth Kiosks 33-36
Thursday 20: 9:30-11:30 MS Pavillion CRM Booth Kiosks 33-36
Thursday 20: 12:00-13:00 Hall B5.2 - Ask the Community Experts session

For the session on thursday we're still looking for more questions. See my previous post about the convergence for more details: Convergence - Ask the expert.

See you in Copenhagen!

Convergence - Ask the expert

In just a couple of weeks there is the Convergence EMEA in Denmark. I'll attend this convergence again and I am looking forward to meeting many of the readers of my blog. On this convergence you can find me at the CRM Booth many times, but there is one place for sure where you can find me. That will be the session IDCRM05: "Microsoft Dynamics CRM: Ask the Community Experts".

That session is going to be one of the most interactive sessions of the Convergence. On stage will be my fellow MVP's as well as myself answering questions from the audience. Feel free to drop by and ask any question. Also, you can let us know your questions upfront on this forum discussion:

Let me know if you'll be in Copenhagen as well. I look forward drinking a beer with my fellow CRM people!

CRM 5.0 Features

Now that CRM 4.0 is available for almost a year, it is good to start thinking about what investmenst you will make in the coming period and which functionality can wait until the has been released. In this topic I'll list some of the most interesting features that Microsoft has said to be working on:
- Adding auditing capabilities out of the box
- Deeply integrate SharePoint with CRM for instance for document management
- Improve crm platform for use in a call center. Less mouse-clicks, less keystrokes
- Reduce the amount of popup screens to improve the usability
- Extend the activities with Voice and IM channels as well as allowing recurring activities
- Improve e-mail marketing, including attachments to emails
- Improve application maintenance including cascading/hierarchical pick-lists, streamlined management for hosted environments and integration with Visual Studio
There are some nice look and feel changes of course like the inclusion of the Microsoft Office Ribbon bar, but I don't expect that many organizations are looking to do this themselves.
For more information regarding the direction of Microsoft Dynamics CRM, look at the paper Statement of Direction on Customersource or Partnersource.
More information on CRM 5.0 you can find at the presentations which were given at the PDC:
A summary of these presentations including screenshots can be found at Simon Hutson's blog.

Social Media and CRM

Although we're in the middle of web 2.0, most companies do not integrate social media in their organizations, including CRM. Avanade has concluded this based on a research which has been conducted under more than 500 global executives.

There are a lot of interesting facts published in the press release which can be downloaded from the CRM Social Media website of Avanade.

Get rid of "Do you want to close this window?"

You might get a question when opening CRM in Internet Explorer. The question is:

The webpage you are viewing is trying to close the window.
Do you want to close this window?
yes no

This message does appear in CRM 4.0 only when you are using Internet Explorer 7.0 and you have enabled the application mode setting. Nevertheless, it is an anoying message which you can get away!

To get rid of this message open the default.aspx file which resides in the root of the CRM website. In this file there are these three lines of code:

var oMe = window.self;
oMe.opener = window.self;

Modify the second line of this snippet and end up with these three lines:

var oMe = window.self;'','_self','');

You now will not have the message anymore. Keep in mind that any update or migration might remove this change, but you should be able to reapply the change easily again.

Overview of CRM 4.0 Training & development collateral

Microsoft employee Jon Butler is sending me updates on CRM regularly. This time he has sent an overview of the available training material. Since this is such a usefull list, I thought it would be worth sharing this with you guys!

Official Courseware available now
These training courses are the Microsoft Dynamics Official Curriculum currently available for CRM 4.0 now, either as soft-copy downloads, ordered hard copy – or you can schedule classroom training.

Download them directly via or for customer source access.

Extending Microsoft Dynamics CRM 4.0 - Course Number 8969
This three-day training material provides individuals with the knowledge and skills to develop extensions for Microsoft Dynamics CRM. The training material focuses on extension methods documented in the Microsoft Dynamics CRM SDK.It also includes content on Microsoft Dynamics CRM Web Service programming, creating and configuring Custom Workflow Activities and Plug-ins, advanced client-side scripting, application integration capabilities and how to create a customer portal solution that connects Microsoft Dynamics CRM to the Internet.

Administration in Microsoft Dynamics CRM 4.0 - Course Number 80002
This training material, Administration in Microsoft Dynamics CRM 4.0, provides individuals with the necessary techniques to plan, develop, apply, and examine administrative tasks within Microsoft Dynamics CRM 4.0.

Workflow in Microsoft Dynamics CRM 4.0 - Course Number 80003
This training material describes how to create, run, and monitor workflows to automate business processes. The training material emphasizes out-of-box workflow functionality. The training material includes the following topics:Basic concepts Creating a basic workflow Design process Update triggers Conditional branching Advanced workflows Multi-stage workflows Monitoring workflows Workflow securityThe training material also focuses on using workflows in Microsoft Dynamics CRM 4.0 to automate the following business processes:Sales process Lead promotion Probable revenueThe following topics are not covered in detail in this training material, but are introduced to provide individuals with insight into potential advanced workflow topics:Extending workflows with custom assemblies Upgrading workflows Data migration and workflows

Customization and Configuration in Microsoft Dynamics CRM 4.0 - Course Number 8912
This three-day training material provides individuals with the tools to configure and customize Microsoft Dynamics CRM 4.0. Configuration topics include setting up business management functions such as:Business units Users Teams Security privileges and roles System Settings Multilingual User Interface Language Packs Currency Exchange Rates Multiple OrganizationsThe training material also focuses on using the Microsoft Dynamics CRM 4.0 Customization tools to customize the following system components:Forms Views Entities Attributes Relationships Entity MappingsThe following customization topics are outside the scope of this training material, but are introduced here to provide individuals with insight into potential advanced customization features:Application Event Programming Client Extensions Workflow SiteMap URL Addressable Forms IFrames SDK

Applications in Microsoft Dynamics CRM 4.0 - Course Number 8913
This three-day training material explores the Microsoft Dynamics CRM application from a user's perspective. Application functionality covered in the training material includes: Sales Management Marketing Automation Service Management Service Scheduling

What’s New in Microsoft Dynamics CRM 4.0 - Course Number 8910
This one-day training material provides individuals with the knowledge and skills to begin planning for Microsoft Dynamics CRM 4.0.

Installation and Deployment in Microsoft Dynamics CRM 4.0 - Course Number 8911
This three-day training material provides individuals with the tools to install and configure Microsoft Dynamics CRM 4.0. The training material focuses on the components used within a Microsoft Dynamics CRM deployment, the hardware and software requirements needed to successfully deploy Microsoft Dynamics CRM, and the installation instructions for the primary Microsoft Dynamics CRM components: the Microsoft Dynamics CRM Server, the E-Mail Router, and Microsoft Dynamics CRM for Office Outlook.

E-Learning available now
Note that for an individual to view the E-Learning online, they’ll have to be set up as a user in PartnerSource/CustomerSource. Some partners or customers prefer to download the E-Learning courses for their trainees instead, and have the trainees view them offline

This query will bring up all E-Learning courses (57 is the current count) – but note that they map pretty consistently to individual chapters of the Official Courseware, so the content of the Official Courseware and E-Learning are similar:

You can filter this further to essentially get E-Learning versions of the Official Courseware training courses listed above. The right column lists appropriate audiences, such as Desktop and End-User Support Professionals, Developers, IT Professional

Dynamics CRM 4.0 collateral from the Microsoft Download Center
All available via
A minor subset of the 155 items available via the Download Center URL provided above

Microsoft Dynamics CRM 4.0 Implementation Guide
This guide contains comprehensive information about how to plan, install, and maintain Microsoft Dynamics CRM 4.0.

Microsoft Dynamics CRM 4.0 SDK
This package contains the complete software development kit for Microsoft Dynamics CRM 4.0.

Microsoft Dynamics CRM 4.0 Logical Database Diagrams
A series of diagrams showing the logical database structure for Microsoft CRM 4.0.

Microsoft Dynamics CRM 4.0 Internet Facing Deployment Scenarios
This document covers how to set up the Microsoft Dynamics CRM 4.0 Web site to make it available from the Internet.

Microsoft Dynamics CRM 4.0 ISV White Paper
How to create business applications for Microsoft Dynamics CRM 4.0.

Microsoft Dynamics CRM 4.0 Data Migration Manager
Using the Microsoft Dynamics CRM 4.0 Data Migration Manager, you can convert and upload data from another CRM system to Microsoft Dynamics CRM 4.0.

Optimizing and Maintaining Microsoft Dynamics CRM 4.0
This white paper details techniques, considerations, and best practices for optimizing and maintaining the performance of Microsoft Dynamics CRM 4.0 implementations.

Offline and Online Synchronization in Microsoft Dynamics CRM
This "nuts and bolts" white paper details the Offline and Online synchronization processes in Microsoft Dynamics CRM 4.0.

How to configure the Microsoft Dynamics CRM 4.0 On-premise and Online E-mail Router in different deployment scenarios
This document lists steps to configure Microsoft Dynamics CRM 4.0 e-mail in different deployment scenarios.

Microsoft Dynamics CRM 4.0 Performance and Scalability
Microsoft, together with Unisys Corporation, completed benchmark testing of Microsoft Dynamics CRM 4.0 running on Microsoft® Windows Server® 2008 operating system and Microsoft SQL Server® 2008 database software. Benchmark results demonstrate that Microsoft Dynamics CRM can scale to meet the needs of an enterprise.

Microsoft Dynamics CRM 4.0 Deployment SDK
SDK for customizing deployments for Microsoft Dynamics CRM 4.0.

Microsoft Dynamics CRM 4.0 Suggested Hardware for Deployments of up to 500 Concurrent Users
Describes general hardware sizing information that will support Microsoft Dynamics CRM version 4.0 with up to 500 concurrent users in a single deployment on-premise model.

Microsoft Dynamics CRM Developer Center
Access to SDK-related information, including access to CRM developers, etc.

Microsoft CRM Blog
Very useful, target, in-depth knowledge shared by program managers, developers, and testers from the CRM Product Group as well as other sources

Hope this is useful.

Get the latest hotfixes for the CRM 4.0 outlook client

The product team has posted a blog article about the known issues with their hotfixes on the team blog. I'd strongly recommend everybody to look at this list and to install all applicable hotfixes for your system.

The following issues are discussed:
1. Outlook hangs during initialization (progress toolbar displays “Loading…” and never finishes)
2. With E-mail Auto Promotion Enabled, Outlook may not close cleanly/properly.
3. Contacts with birthdays earlier than 1/1/1970 causes Outlook to crash
4. Items in Shared Calendars will report Sync Issues
5. Cannot Promote an E-mail where the name of the attached file contains a ‘&’ symbol.
6. Selecting Dismiss on Outlook Calendar reminder for Service Activity causes record to change Status Reason back to default value for that record.
7. OWA Sent Emails Get Stuck in Outlook Draft Folder When Outlook Is Open And CRMADDIN is Enabled
8. Microsoft Outlook stops responding when you open, close, reply to, or forward e-mail messages in the Microsoft Dynamics CRM 4.0 client for Outlook
9. CRM Outlook client and/or Desktop Client hangs in presence of other Outlook add-ins
10. Phone call activity due time is changed after the activity is snoozed or dismissed.

There is a cumulative hotfix which does fix each of these as well: Download

Custom entities and attributes in a plug-in

You cannot create a webservice in Visual Studio when you're writing a plugin. Instead you need to use the method context.CreateCrmService(true);. There is only one single issue when using this approach. You cannot leverage the power of IntelliSense in Visual Studio. Visual Studio will not recognize your custom entities and attributes. How to work with this? The only correct answer is "Dynamic Entities".

To retrieve records based on some attribute values you could use a piece of code like this:

// Create the QueryByAttribute object.
QueryByAttribute query = new QueryByAttribute();
query.ColumnSet = new AllColumns();
query.EntityName = "new_customentity";
query.Attributes = new string[] { "new_customentityid" };
query.Values = new string[] { customEntityId };

// Create the request.
RetrieveMultipleRequest request = new RetrieveMultipleRequest();

// Set the request properties.
request.Query = query;
request.ReturnDynamicEntities = true;

// Execute the request.
RetrieveMultipleResponse response = (RetrieveMultipleResponse)service.Execute(request);

One of the most important details in this piece of code is this line:

request.ReturnDynamicEntities = true;

If you forget this line, you'll end up with this error message:

System.InvalidOperationException was unhandled by user code Message="There is an error in XML document (1, 509)." Source="System.Xml" StackTrace: at System.Xml.Serialization.XmlSerializer.Deserialize(XmlReader xmlReader, String encodingStyle, XmlDeserializationEvents events) at System.Xml.Serialization.XmlSerializer.Deserialize(XmlReader xmlReader, String encodingStyle) at System.Web.Services.Protocols.SoapHttpClientProtocol.ReadResponse(SoapClientMessage message, WebResponse response, Stream responseStream, Boolean asyncCall) at System.Web.Services.Protocols.SoapHttpClientProtocol.Invoke(String methodName, Object[] parameters) at Microsoft.Crm.SdkTypeProxy.CrmService.Execute(Request Request) at Microsoft.Crm.Asynchronous.SdkTypeProxyCrmServiceWrapper.Execute(Object request) at ...your assembly information...

So, don't forget the ReturnDynamicEntities attribute and you should be fine to go!

Unauthorized error after deploying your custom application

I've been working on deploying an application today. I received the error "Unauthorized" all the time and did not know why. The website was deployed as a new virtual directory within the ISV folder, authentication was set to integrated windows authentication and the password which was supplied was correct. Still I was able to get this error message:

Server Error in '/ISV/CustomApplication' Application.
The request failed with HTTP status 401: Unauthorized. Description: An unhandled exception occurred during the execution of the current web request. Please review the stack trace for more information about the error and where it originated in the code. Exception Details: System.Net.WebException: The request failed with HTTP status 401: Unauthorized.Source Error:
An unhandled exception was generated during the execution of the current web request. Information regarding the origin and location of the exception can be identified using the exception stack trace below. Stack Trace:
[WebException: The request failed with HTTP status 401: Unauthorized.]
System.Web.Services.Protocols.SoapHttpClientProtocol.ReadResponse(SoapClientMessage message, WebResponse response, Stream responseStream, Boolean asyncCall) +551137
System.Web.Services.Protocols.SoapHttpClientProtocol.Invoke(String methodName, Object[] parameters) +204
Microsoft.Crm.Metadata.MetadataWebService.GetDataSet() +31
Microsoft.Crm.Metadata.DynamicMetadataCacheLoader.LoadDataSetFromWebService(Guid orgId) +301
Microsoft.Crm.Metadata.DynamicMetadataCacheLoader.LoadCacheFromWebService(LoadMasks masks, Guid organizationId) +40
Microsoft.Crm.Metadata.DynamicMetadataCacheFactory.LoadMetadataCache(LoadMethod method, CacheType type, IOrganizationContext context) +418
Microsoft.Crm.Metadata.MetadataCache.LoadCache(IOrganizationContext context) +324
Microsoft.Crm.Metadata.MetadataCache.GetInstance(IOrganizationContext context) +386
Microsoft.Crm.BusinessEntities.BusinessEntityMoniker..ctor(Guid id, String entityName, Guid organizationId) +115
Microsoft.Crm.Caching.UserDataCacheLoader.LoadCacheData(Guid key, ExecutionContext context) +323
Microsoft.Crm.Caching.ObjectModelCacheLoader`2.LoadCacheData(TKey key, IOrganizationContext context) +389
Microsoft.Crm.Caching.BasicCrmCache`2.CreateEntry(TKey key, IOrganizationContext context) +82
Microsoft.Crm.Caching.BasicCrmCache`2.LookupEntry(TKey key, IOrganizationContext context) +108
Microsoft.Crm.BusinessEntities.SecurityLibrary.GetUserInfoInternal(WindowsIdentity identity, IOrganizationContext context, UserAuth& userInfo) +344
Microsoft.Crm.BusinessEntities.SecurityLibrary.GetCallerAndBusinessGuidsFromThread(WindowsIdentity identity, Guid organizationId) +194
Microsoft.Crm.Authentication.CrmWindowsIdentity..ctor(WindowsIdentity innerIdentity, Boolean publishCrmUser, Guid organizationId) +279
Microsoft.Crm.Authentication.WindowsAuthenticationProvider.Authenticate(HttpApplication application) +605
Microsoft.Crm.Authentication.AuthenticationStep.Authenticate(HttpApplication application) +125
Microsoft.Crm.Authentication.AuthenticationPipeline.Authenticate(HttpApplication application) +66
Microsoft.Crm.Authentication.AuthenticationEngine.Execute(Object sender, EventArgs e) +513
System.Web.SyncEventExecutionStep.System.Web.HttpApplication.IExecutionStep.Execute() +92
System.Web.HttpApplication.ExecuteStep(IExecutionStep step, Boolean& completedSynchronously) +64
Version Information: Microsoft .NET Framework Version:2.0.50727.1433; ASP.NET Version:2.0.50727.1433

After quite a search I managed to find this blog. There I learned that CRM is using an HttpModule for multitenancy. The http module will be called with an anonymous user account and will fail when it's requesting the metadata webservice. To make your own app working, you'll need to remove the HttpModule from being loaded. A copy paste piece from Cesar de la Torre's blog:

This is what you have to add to your own web.con file:


Also, if you are not using any CRM 4.0 Titan assembly within your app, you can also get rid of all the references, adding also the following:

<add assembly="*"/>

Personally I prefer the removal of only the exact names instead of a generic "clear". What I ended up using is:

<remove name ="CrmAuthentication"/>
<remove name ="MapOrg"/>

If any of you finds a better approach I'm glad to hear that. Until then I'll be using this approach.

Convert lead to contact, account and/or opportunity programmatically

Update: The codeproject missed a line of code. After you have executed the InitializeFromRequest, then you'll get a InitializeFromResponse. This response has got a entity in it. This entity you will need to create. The entity does not yet get created by executing the InitializeFromRequest! The line to add is:

Guid entityId = service.Create(rps.Entity);

Today I needed some code which does convert a lead to a contact programmatically. Instead of just building, I first asked my mate Google if he knew how to do that. Kind as Google is, he told me that he didn't know, but he knew that Cem Onvar knows that. Cem has published the code on the codeproject website.

Basically it comes down to two steps. The first step is to disable the lead. This can be done by using the SetStateLeadRequest. The second step is to use an request class which is quite rare. It's the InitializeFromRequest class. On this class you can set the EntityMoniker attribute to the lead which you just disabled. On the same request you'll need to set the target entityname to the name of the entity you wish to convert the lead into (contact, account or opportunity) and you'll need to set the TargetFieldType. This would most likely be TargetFieldType.All. Now execute that request and you're done.

For the direct code look at the codeproject site.

Keep in mind that you can use this approach for all kind of conversions.

Plug-in not working

One of the most read pages on my blog is the list of reasons why a callout won't work. Since the release of CRM 4.0 we do not have callouts anymore, but we're using plug-ins for extending CRM. This article will contain all the reasons that I find on why a plug-in is not working.


"Unable to load the plug-in assembly"

There are multiple reasons why this error can occur. These reasons include:

- The plug-in is registered on disk, but the file is not located in the correct location (drive:\crm server folder\server\bin\assembly\). Keep in mind that if you use the registration tool that the plug-in will be registered, but the file will not be placed in the right location. This is a manual step.

- The plug-in is registered on disk and the file is located in the correct location, but the security settings are not correctly set on the assembly file. Once you have copied the file to the \server\bin\assembly folder, make sure that you check the permissions of the file. The user which is used to run the application pool in which CRM is running, should have read & execute rights. You can set this by going to the folder and right click on your plugin its dll file. Then press "Properties". Go to the tab "Security" and add the user which is used for the application pool. This user you can figure out in the IISManager. There look at the properties of the CRM website to find out which application pool is used. Then look in the application pool's properties to find out the identity. Most likely this is "Network Service" but it could be changed in your situation.

After setting the security settings, make sure to perform an IISreset.

- Your environment exists out of multiple servers and the plugin is registered on disk. In this situation make sure that the file is placed in the \server\bin\assembly folder on all servers. Also the security should be set correctly (see other possible reason).


"The request failed with HTTP status 401 unauthorized"

Possible reasons for this error include
- The code does use a reference to the webservices, but uses credentials which do not have enough privileges in CRM

- The plug-in does is created for the non default instance. In this case, look at the following kb article: From there you can request a hotfix for this issue.


"Not have enough privilege to complete Create operation for an Sdk entity"

This error shows up even though the user is a System Administrator. The cause is that the user is not a member of the Deployment Administrators group in CRM Deployment Manager. Once you have added yourself to that group it will work. Keep in mind that you will need to login as an administrator to be able to open the Deployment Manager.


"The request failed with http status 400: Bad Request"

This error seems to come from a piece of code in the synchronous plug-in framework which forces the CrmService to use the localhost. George has written a post on the logic behind this.
The solution is to either run the plug-in asynchronous or otherwise make the webservice available from the localhost.
Update: There is a hotfix available for this issue now:

As soon as I run into other issues with plug-ins, I'll definitely add them to this list.

Javascript Files and Caching

You will notice that the performance of Dynamics CRM can be negatively affected when you have loads of Javascript codes embedded into the form of an entity. It is recommended that you take out the Javascript codes from the form and place them in a separate script file which can then be loaded in the form. This will cause the script to be downloaded only once and therefore improve performance when opening the page again. For some info on how to load javascript files in CRM, look at one of my previous posts.

There is one issue though when doing so. When the file has been changed on the server, it will still be cached on the client's machines. You can force Internet Explorer to check the Javascript file to see if it has been changed. One of my German colleagues (Christian Niss) has learned me that it is possible to modify the iis-cache settings for just the javascript file.

If you switch off "enable content expiration" and add a custom http header for the javascript file only:

Cache-Control: max-age=259200, must-revalidate

It should set client side caching of the file to three days (259200 sec), but each time the script is being used the browser must check if a more recent file is available on the server.

Good luck with caching!

Not all emails are sent from MailMerge

Yesterday I looked at an issue with a colleague of mine (Nico Verhagen). The problem was that a mailmerge quick campaign has been created which should send out approximately 1500 emails. When the quickcampaign had finished, there were only 43 emails sent and nothing failed. How could that be true?

Apparently only 800 contacts had an email address specified, so that already is causing half of the issue. The second half was harder to find, especially because there was no error message anywhere.

The root cause of this issue appeared to be that the bit field for 'donotsendmm' has been set to NULL. Although the default is 'yes', the field had no value because the records were created in an import program instead of the UI. In this import program the default values were not set for the 'allow marketing' attribute. After setting the allow marketing to true, the emails were sent.

Hint: To update all the records in bulk on a supported way, Nico created a workflow rule which updates that field to set it to true. Then perform an advanced find to select the records for which the field has not been set to false and run the workflow on all the records on the page. You will then update 250 records in each run. You can set the record amount visible in your personal options in CRM.

Creating an activity report which includes the related people

In an activity CRM grid, it is not possible to add attributes from the activity type (letter, phonecall etc) itself. The fields to and from on the entities phonecall, letter, fax are therefore not eligable for addition on the CRM grid. It would be very useful to see those though. The same is valid for the to, cc and bcc in email and required and optional attendees in appointments. In this post I won't be giving a solution to show the attributes in the grid, instead I will give a workaround by using reports.

The only attributes which you can select in the grid are the attributes which are belonging to the entity activitypointer. These include the activityid, startdate, statecode, but also the regardingobjectid. So the question is, how to get the to, from, cc etc. For this you can use the function which I have posted in my previous post. This function accepts an ActivityID and an ActivityPartyType. So what is this type? Look at this page: ActivityPartyType. You will find a list of values mapped to what kind of field you want to add to your report.

By using that function you can create your query for the report. An example would be:

activityid, activitytypecode, scheduledstart, subject, owneridname, statecodename,
(SELECT DBO.fn_PGGM_GetActivityPartyList(activityid, 1)) [to],
(SELECT DBO.fn_PGGM_GetActivityPartyList(activityid, 2)) [from],
(SELECT DBO.fn_PGGM_GetActivityPartyList(activityid, 5)) [required]

This query does select some default attributes and it adds the regarding, to, from and required fields. Add this query to the generation of a report and you'll be set to go.

Note: make sure that the function gets added to your database and assign the correct rights. See the post around the function for details.

Happy reporting!

Transform a table column into a CSV field in SQL Server

Imagine that you want to use a related table in your SQL query. You then must return only a single column or otherwise you'll get this SQL error:

Msg 512, Level 16, State 1, Line 2
Subquery returned more than 1 value. This is not permitted when the subquery follows =, !=, <, <= , >, >= or when the subquery is used as an expression.

What I like to do, is to transform the result table column into a single field separated by a ; sign. Earlier on I used to create a huge function which used cursors etc. Then a colleague of mine told me how to use C# code in SQL server which seemed to be a neater solution.

Today I have found a new approach. This uses a function again, but it is very simple. Here's the function:

-- =============================================
-- Author: Ronald Lemmen
-- Create date: 4 July 2008
-- Description: Function to return the people in CSV format belonging to a activity based on the activity party type code
-- =============================================
CREATE FUNCTION fn_RL_GetActivityPartyList
@ActivityId uniqueidentifier,
@ActivityPartyType int
RETURNS nvarchar(3000)
DECLARE @result nvarchar(3000)

SET @result = ''

SELECT @result = Coalesce(@result + ';', '') + partyidname from filteredactivityparty party where party.activityid = @ActivityId and party.participationtypemask = @ActivityPartyType

RETURN SUBSTRING(@result ,2, LEN(@result))

The @result will get filled by the SELECT query with the values from the filteredactivityparty table separated by a ;. The first character is a ; as well and therefore I do remove this one in the RETURN statement.
After the + in the SELECT query you can place your own query. This example is just extremely useful in my next post :)

Make sure that you do grant access to the correct people in order to use this function. In the case of a CRM report, add the reporting group. See the below example, but make sure that you do change the guid to the guid which is valid for your system.

GRANT EXECUTE ON [dbo].[fn_PGGM_GetActivityPartyList] TO [PGGM-INTRA\ReportingGroup {05e0584a-1d94-424c-8014-c2f3b1b92ccc}]

Happy reporting!

Determine the logged in user

Some time ago I wrote a post around how to show and hide fields based on the logged in user. Apparently this doesn't work for Dynamics CRM 4.0 anymore for two reasons. This post will help you to get it working again.

The first one is that you are not allowed to use the <%= approach anymore. You do now have to use the function:

Page.Response.Write(string strText);

The second reason is that the variable "Microsoft.Crm.Security.User.Current.UserAuth.UserId" does not exist anymore. Microsoft has changed the internal structure of how they work with the current user. You now should use this "Microsoft.Crm.Security.User.Current.SystemUserId.ToString()". These two changes lead to the following code

<script language="javascript">
var loggedInUser = '<%Page.Response.Write(Microsoft.Crm.Security.User.Current.SystemUserId.ToString())%>';

If you do have a single mistake in the aspx page you are changing, then you'll get the following error:

The VirtualPathProvider returned a VirtualFile object with VirtualPath set to '/MicrosoftCRM/sfa/accts/edit.aspx' instead of the expected '//MicrosoftCRM/sfa/accts/edit.aspx'

This has nothing to do with the VirtualPathProvider, it's just that you have a mistake in your aspx page.

Good luck!

MVP for the 3rd consecutive year

Hi Guys,

As a reward for community work last year, Microsoft has again reawarded me the Microsoft CRM MVP! I am very much pleased with this award because as one of my colleagues said: Getting to the top is hard, but staying there is even harder!

Last year I have spend a lot of time on doing community work again. I have spend a lot of time preparing for presentations like deepdive sessions and CRM 4.0 presentations. Furthermore this blog has been extended with quite some posts. And although there were not as much posts from me as in the year before, I did do spend a lot of time on the newsgroups en forums to help out people.

Once again I would like to encourage all of you to share your knowledge. Answer questions in newsgroups and forums. Or prepare a presentation about something you have been working on and share this with your colleagues. My girlfriend has a t-shirt which says: "Knowledge is power". I agree with that, but I am confident that sharing knowledge is even more powerfull!

See you around in the communities!

UPDATE: Have a drink with your fellow CRM consultants

For quite some time I've been thinking about organizing a drink for all the Microsoft Dynamics CRM consultants in the Netherlands. Mostly I've been thinking about the format. Who should be invited, should Microsoft be a sponsor etc. From one day to another, these questions were answered by Johan van Dijk. He started the "Dynamics Netwerk Borrel". He organizes drinks for consultants who are working with Dynamics CRM, AX or NAV. These drinks are sponsored by Microsoft Partners. The first drink is on the 21st of August and is sponsored by Centric. The location is in Gouda, Netherlands. Feel free to subscribe on:

See you there!

If you're not from the Netherlands, then use this as an example and set up such a similar event. It's always nice to have some drinks with CRM consultants right?

The date has been changed to the 21st of August.

Windows Home Server

Who of you guys is working with Windows Home Server (WHS)? Last weeks I've been working with this in my spare time. I've grabbed an old pc, added some harddisk space and memory and installed this product. Now I'm figuring out all of the possibilities.

Of course there's the most important feature: Backup. Every night the WHS server wakes up all of my pc's and laptops and makes a backup. Once my work laptop was stolen and I did lose data... I had a hard time back then, but that won't happen again. My laptop might still get stolen, that's a risk of living near Amsterdam, but I won't ever my data again.

The second feature I really like, is the ability to have a share to place your files on. By default it creates different folders like Photos, Music, Movies etc. And there's an even greater feature related to that. Some of you probably have a server at home as well. You have to admit that you have been struggling with harddrives and free spaces right? Well, I've added several harddisks to this machine and it just combines them all to one virtual harddrive. There's never the problem that one harddrive is full. Just add a harddrive and you can add files to the shares again.

Then there's the feature of accessing your server from the internet. You can easily set up the server to be accessible from the internet. Microsoft even offers a friendly url like: From this site you can access your shares and even remote desktop to your home computers, if they support RDP.

Now it would be great to have CRM on this installed as well right? It would be wonderful to have your own home CRM system which contains all the addresses of your friends, birthdays etc. Integrate this with Facebook and Linked-in to always be up to date. Also use a mobile solution to have the data integrate with your phone and then we're living in a utopia right? I think it would be great that if I end up with my car somewhere in Spain and I do know somebody in Barcelona, that I can search for my friend in my crm system, click the button "use address in TomTom" and drive there to say "HI!". That would be awesome.

But thats not possible, yet. WHS isn't designed to be an Domain Controller or even part of a domain. Doing so appears to be possible but it is very much unsupported. I'll dig a bit into this after the Power Pack 1 has been released. For the users who wan't to have AD and install CRM at home now, they should go and get Windows SBS and get it running in your home. Not only is this product a lot more expensive, it also doesn't have some of the neat featurs of WHS.

In short, Windows Home Server is a great product for what it's designed for: Allowing the home users to have a centralized place for their files and backups.

Resizing windows

If you have a lot of data on an entity form, then you sometimes do want to force the page to open in full screen mode. There's a small javascript which will allow you to do this. Just add these two lines of code to the form onload of your entity form:

window.resizeTo(screen.availWidth, screen.availHeight);

Also, when you open a custom page you can also set the window size by using the same javascript function. In your code you can use the following function in the Page.OnLoad() to set the window size to match your requirements:

private void SetWindowSize(int iWidth, int iHeight)
StringBuilder sbResizeScript = new StringBuilder();
ClientScript.RegisterClientScriptBlock(this.GetType(), "ResizeScript", sbResizeScript.ToString());

Happy resizing!

Stopping and continuing a save event

For some customizations you do need to stop the form onsave event, perform some business logic and continue the save event. An example would be that in specific conditions are met when a record is saved, then a popup will need to be shown. After filling in data in the popup and pressing a continue button on the popup, then the save operation would need to continue. The SDK helps in this situation. Look at the following page for more information. MSDN SDK: OnSave Event

On that page you will see that you can stop the onsave event by setting the 'event.returnValue = false'. Don't forget to follow that line with a 'return false'. This will cause the save procedure to stop right at that point. Otherwise statements after that will still be executed.

To call the save event from your javascript code, you can use the javascript functions crmForm.Save(); and crmForm.SaveAndClose(). By looking at the 'event.Mode' you can determine which event was executed before. If the code is 1, then it is a crmForm.Save(); or it is 2 for a crmForm.SaveAndClose(). There's only one small issue. There can be other save events as well. There's the 'save and new', 'save as completed', and also the 'send' for emails. Below is a list of save events with the corresponding javascript functions to call. Once again, this is not documented in the SDK, so this might change with a hotfix or new version.

Code: 1
Function: crmForm.Save();

Code: 2
Function: crmForm.SaveAndClose();

Code: 7
Function: send();

Code: 58
Function: SaveAsCompleted();

Code: 59
Function: crmForm.SubmitCrmForm(59, true, true, false);

Good luck!

Import CSV file to DataTable

I'm preparing a demo right now and for this I'm importing a CSV file to CRM. Especially the piece around the import of data from a CSV file to a DataTable is very generic. I'm sharing it with you guys for if it does make sense for you to use this as well.

class CSVReader
public System.Data.DataTable GetDataTable(string strFileName)
System.Data.OleDb.OleDbConnection conn = new System.Data.OleDb.OleDbConnection("Provider=Microsoft.Jet.OleDb.4.0; Data Source = " + System.IO.Path.GetDirectoryName(strFileName) + "; Extended Properties = \"Text;HDR=YES;FMT=Delimited\"");
string strQuery = "SELECT * FROM [" + System.IO.Path.GetFileName(strFileName) + "]";
System.Data.OleDb.OleDbDataAdapter adapter = new System.Data.OleDb.OleDbDataAdapter(strQuery, conn);
System.Data.DataSet ds = new System.Data.DataSet("CSV File");
return ds.Tables[0];

You can then use this class together with a code like this:

private void YourFunction()
CrmService service = new CrmService();
service.Credentials = System.Net.CredentialCache.DefaultCredentials;

CSVReader reader = new CSVReader();
DataTable dt = reader.GetDataTable("C:\\CoffeeContacts.csv");
for (int i = 0; i < dt.Rows.Count; i++)
DataRow dr = dt.Rows[i];

account acc = new account(); = dr["Company"].ToString();

ForceSubmit in ASP.Net

Today I've been working on a simple IFrame. This IFrame shows 3 dynamic picklists and the data in these picklists is coming from crm. Since some clients are a bit slow, I would like the picklists to be disabled while the postback is being performed. This is easily done with this script:

function disableFields(field1, field2){
field1.disabled = true;
field2.disabled = true;

<asp:DropDownList ID="ddl1" runat="server" AutoPostBack="true" onchange="disableField(form1.ddl2, form1.ddl3);">
<asp:DropDownList ID="ddl2" runat="server" AutoPostBack="true" onchange="disableField(form1.ddl1, form1.ddl3);">
<asp:DropDownList ID="ddl3" runat="server" AutoPostBack="true" onchange="disableField(form1.ddl1, form1.ddl2);">

This works perfectly, but... After a postback, the values of the selected picklists are gone! This seems like the same behavior as the disabled fields in CRM. In CRM you can solve this by setting the attribute ForceSubmit to true on the attribute, but I did not know of such an attribute.

Apparently there is such behaviour built into ASP.NET 2.0. In order to enable the submission of disabled form elements, you need to put this line in the Page_Load:

Page.Form.SubmitDisabledControls = true;

For more information on this attribute, check MSDN

Happy disabling!

Javascript and IFrames

I'm struggling with IFrames and JavaScript quite often. When you're working with this as well, the first thing to keep in mind is:

Deselecte the option "restrict cross site scripting" (in dutch "Het uitvoeren van scripts tussen frames beperken")

That usually saves a lot of troubles.

Furthermore, the next step is to create JavaScripts. One which I use quite often, is one which allows me to access a value in the IFrame. This is useful in onSave routines to copy data from the iframe to any of the CRM attributes. This is the code which I use: =;

In this example you do need to change the name of the attribute to which you want to save the data to ( -> crmForm.all.yourSchemaName). The next modification is to change the name of the IFrame. When setting up an IFrame, you do supply a name. Change the IFRAME_CustomIFrame to IFRAME_YourIFrameName. Then on your custom html or aspx page, you do need to access the variable. That you can do by specifying the name of the form followed by the name of the attribute.

For other examples, look at the page of Jonas Deibe Playing around with iframes or Michael Höhne More JavaScript Code.


Just like Microsoft has developed a VPC for CRM 3.0, they have created one for CRM 4.0 as well. Here's the link to the VPC:

CrmDateTime conversion to DateTime

When working with CrmDateTime, you'll notice that this type does have a .value attribute, but the type of this attribute is string. There is no attribute to get the .net class DateTime out of your CrmDateTime. If you do want to use a DateTime anyway, you'd easily need to convert it. You could use any of these:


For more information on the CrmDateTime, look in the SDK:

Logo Dynamics

For a presentation I needed a logo of Microsoft Dynamics. At that point I realized that I have never used an official logo for Microsoft Dynamics. Searching on the internet resulted in this page:

It includes logo's for most Microsoft products including Visual Studio, Office, Windows and of course Dynamics.

Dynamics CRM and NAV Integration

Many newsletters get into my mailbox and there are just a few which I read. One of them is the newsletter from my friends at Scribe. Especially in this newsletter, great news is made public. They will be releasing the NAV Adapter for Scribe Insight next month! This means that you will be able to integrate NAV with any other database or product where they do have an adapter for. Of course for Microsoft Dynamics CRM such an adapter is developed. So from next month on, you can easily integrate NAV with Microsoft CRM by using Scribe Insight!

For more info look at:

Or join any of the following webinars:

Announcing the Scribe Adapter for Microsoft Dynamics NAV
Tuesday, February 19, 2008 11:00a.m. US ET/4p.m. GBT

Announcing the Scribe Adapter for Microsoft Dynamics NAV
Tuesday, February 26, 2008 11:00a.m. US ET/4p.m. GBT

There are more companies who have created an integration between Microsoft Dynamics CRM and NAV. I haven't performed research on which exist, but I've seen some in the comments section already *smile*

Unable to browse for Active directory objects

While installing CRM (both CRM 3.0 as well as 4.0), you might run into the error message

Unable to browse for Active directory objects

This error message can appear when you press "Browse" after selecting the Organizational Unit in Active Directory. There are some possible solutions which could cause this issue. Think about the following:

- Are you logged in with an account to the domain instead of the local machine
- Is the server member of the domain
- Are you logged as a user with sufficient rights in CRM? If possible, try to use a domain admin.

There has been posted a possible solution to the public newsgroups as well by Merlin:
I was installing on a fresh domain within the same network, and got this error. I set up the new domain's DNS and still got the error. However, since I was on the same network subnet, my servers were getting their DNS from the primary domain's DNS server, which had no knowledge of my test domain's domain controller. So I turned on zone transfers between the 2 domains. Now my servers can find their domain controller via DNS and I can browse that domain's AD.

Hope this helps you further!


Everybody who's performing data imports knows the problem. When you create a record in CRM, the created on field always points at the date the record is created. Ofcourse you could go into the database and update the date by using a SQL script. But then again, there is this good white angel hanging above your shoulder whispering "Don't do it, it's not supported". No matter what this angel says, the evil red devil shouts "Do it, your customer wants the correct data" and you go into the database.

Well these kind of situations are now history. The CRM development team has silently introduced a new feature. While performing an insert, you can set the attribute overriddencreatedon field. The value of this field will be used to set the record's created on attribute. So now you can import records in the history! A small feature which will make many people happy.

AttributeInfo.TypeName(int) != AttributeMetadata.Type.Name(float)

You might bump into an error message while importing an entity from a customizations file. The error show could be:

Error: lead: AttributeInfo.TypeName(int) != AttributeMetadata.Type.Name(float)

The cause of this error is a mismatch in attribute type. Usually a field has been removed in the other environment and has been recreated with another attribute type. The type in your destination CRM system of an attribute is the type displayed in the right side of the != statement. In the example above float. The type in the import file is the type displayed on the left side of the != statement. This is int in the example above. In order to get rid of this error message and to import the entity, you will need to remove the attribute from the destination system.

In the list of attributes, search for a custom attribute which has the same type as displayed on the right side of the equation. Determine if there is any of these which has been changed. Delete this attribute and import the entity again. Keep in mind that the attribute must be removed from the form first (also the published form) before it can be removed from the attribute list. Another thing to keep in mind, is that when you perform this action on a production system, that the data in the attribute will be removed. Since this is not recoverable, you should first perform the removal of the attribute by following the next steps:
- create a new custom temporary attribute
- copy the data from the old attribute to the temporary attribute for each record
- remove the attribute
- import the entity (and with that the new attribute)
- copy the data from the temporary attribute to the new attribute for each record
- remove the temporary attribute

If there are many custom attributes, it might be hard to locate which of these is causing the error to appear. Unfortunately the name is not in the error description and also the event viewer and tracing does not mention the exact attribute name. To find out which of the attributes is causing the error, you should start the database profiler. Start a new trace and run the import. As soon as the error shows up, stop the tracing. In the trace search for the last occurence of:

exec sp_executesql N'SELECT T1.AttributeId AS attributeid

When you have found this record, copy the whe query. When you run this query in the SQL Server Management Studio, then only a single record should be returned. One of the attributes in the result is the name attribute. This is the attribute which is changed and will need to be removed.

Disclaimer: Only perform actions on the database if you are comfortable with the technologies. Incorrect SQL statements can corrupt your database and cause mayor dataloss. Always make a backup before performing database queries against your CRM database.

Dynamics CRM 4.0 Test Data

The test data to be used in demo's etcetera is available on the Microsoft download site. Here you can find the exe and details:

Failure at Microsoft.crm.setup.common.registerasyncserviceAction

Some people are experiencing troubles while installing CRM 4.0. Right now I’m having the same problems as some others. In the end of the installation, the setup throws the error message "Failure at Microsoft.crm.setup.common.registerasyncserviceAction".

The reason why I got this error message was because I had just uninstalled CRM and tried to install it again. I did not think about a wise lesson I had once learned from a German guy. He said "Ein reboot macht immer gut". So after a restart of the server I have tried to install again and now it works like a charm.

Another thing to try, is to manually start the Async service for CRM and then retry the action.

If this doesn't work for you, make sure to check the log file regarding this service. You can find it on this location:
C:\Documents and Settings\{username}\Application Data\Microsoft\MSCRM\Logs\CrmAsyncService.log

Good luck installing CRM!

Happy new year!

Happy new year to everybody!

After a nice holiday of more than a month, I'm back in the office. Whole december I've been free and doing as least work related stuff as possible. And I have succeeded in that quite good. Except for answering some questions, helping some colleagues out, writing an article for the CRM Team Blog, giving a presentation on CRM 4.0 for my Dutch colleagues, I have not done much work related stuff.

Okay, maybe I did do a bit much CRM related stuff in my holidays, but I have spend time the correct way as well. I've visited Hannover (Germany) for Christmas shopping, went to Austria on Holidays and moved houses. Unfortunatly the month is of free time is over and I need to get back to work.

In fact, I'm in the Munich office for the coming 3 weeks. Here I'll be working on a nice data migration from Salesforce to MS CRM 4.0 by using Scribe Insight. If you happen to be in Munich, please let me know and we can have a beer!

I hope that everybody has enjoyed the christmas time as much as I have done so and I wish everybody a great new year!