<?xml version='1.0' encoding='UTF-8'?><?xml-stylesheet href="http://www.blogger.com/styles/atom.css" type="text/css"?><feed xmlns='http://www.w3.org/2005/Atom' xmlns:openSearch='http://a9.com/-/spec/opensearchrss/1.0/' xmlns:georss='http://www.georss.org/georss' xmlns:gd='http://schemas.google.com/g/2005' xmlns:thr='http://purl.org/syndication/thread/1.0'><id>tag:blogger.com,1999:blog-199106851038957806</id><updated>2012-01-31T15:14:15.506Z</updated><category term='CRM 2011'/><category term='Virtual PC'/><category term='Plugin'/><category term='Reports'/><category term='Email Templates'/><category term='SQL Server 2008'/><category term='Error Codes'/><category term='Callouts'/><category term='Troubleshooting'/><category term='SQL Server'/><category term='Deployment'/><category term='Auditing'/><category term='MVP'/><category term='Workflow'/><category term='Client Code'/><category term='Security'/><category term='IIS'/><category term='Registry'/><category term='Customisation'/><category term='Announcement'/><category term='SDK'/><category term='Configuration'/><category term='CRM 4.0'/><category term='WSDL'/><category term='Upgrade'/><category term='Data Integration'/><category term='Crm Online'/><category term='Advanced Find'/><category term='64 Bit'/><category term='Server code'/><category term='Code Gallery'/><category term='How it Works'/><category term='Documentation'/><category term='Team Blog'/><category term='Asychronous Service'/><category term='SSIS'/><category term='Quick Tips'/><category term='Design Patterns'/><category term='News'/><category term='Installation'/><category term='CRM 3.0'/><category term='ASP .Net'/><category term='Excel'/><title type='text'>David Jennaway - Microsoft Dynamics CRM</title><subtitle type='html'>Postings about Microsoft CRM customisation and development, with digressions into SQL Server, Reporting, SharePoint and .Net</subtitle><link rel='http://schemas.google.com/g/2005#feed' type='application/atom+xml' href='http://mscrmuk.blogspot.com/feeds/posts/default'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/199106851038957806/posts/default?max-results=100'/><link rel='alternate' type='text/html' href='http://mscrmuk.blogspot.com/'/><link rel='hub' href='http://pubsubhubbub.appspot.com/'/><author><name>David Jennaway</name><uri>http://www.blogger.com/profile/09695858105618938443</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><generator version='7.00' uri='http://www.blogger.com'>Blogger</generator><openSearch:totalResults>100</openSearch:totalResults><openSearch:startIndex>1</openSearch:startIndex><openSearch:itemsPerPage>100</openSearch:itemsPerPage><entry><id>tag:blogger.com,1999:blog-199106851038957806.post-5638374908685789474</id><published>2012-01-31T13:30:00.005Z</published><updated>2012-01-31T15:14:15.513Z</updated><category scheme='http://www.blogger.com/atom/ns#' term='CRM 2011'/><category scheme='http://www.blogger.com/atom/ns#' term='Crm Online'/><category scheme='http://www.blogger.com/atom/ns#' term='WSDL'/><title type='text'>Using WSDL Proxies with CRM Online. It's outside of North America</title><content type='html'>I've been spending more time than I'd like using WSDL Proxies with CRM Online (i.e. when I can't use the .Net 4.0 OrganizationServiceProxy class). I'll write up some more about this soon, but this is a quick post about a specific issue with connecting to CRM Online for an organisation in EMEA, rather than North America, which I've not found documented anywhere.&lt;br /&gt;&lt;br /&gt;I was basing my code on the wsdlbasedproxies example in the CRM 2011 SDK. Once you find it, this code is reasonably well documented.&lt;br /&gt;&lt;br /&gt;However, when testing it, I could connect to the IDiscoveryService without problems, but continually got the error 'An unsecured or incorrectly secured fault was received from the other party. See the inner FaultException for the fault code and detail' when connecting to the IOrganizationService.&lt;br /&gt;&lt;br /&gt;Ultimately the issue was with the AppliesTo constant. The setup.txt instructions tell you to set this based on data in the &lt;ms-xrm:livetrust&gt;element from the Discovery.svc wsdl. This gave me "urn:crmemea:dynamics.com" when connecting to an Online organisation in EMEA, which worked for the IDiscoveryService, but not IOrganizationService.&lt;br /&gt;&lt;br /&gt;After more time than I'd like, I found out that the IOrganizationService in EMEA works when AppliesTo = "urn:crm4:dynamics.com". My guess is that "urn:crm5:dynamics.com" would be correct in Asia (if anybody has a sample login to try, let me know and I'll confirm it one way or another).&lt;br /&gt;&lt;br /&gt;So, this needed a few minor code changes to the code in Online\program.cs, as you need different tokens for each service. For EMEA, I used the following:&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family:courier new;font-size:85%;"&gt;private const string AppliesToDiscovery = "urn:crmemea:dynamics.com";&lt;br /&gt;private const string AppliesTo = "urn:crm4:dynamics.com";&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family:courier new;font-size:85%;"&gt;static void Main(string[] args)&lt;br /&gt;{&lt;br /&gt;//Authenticate the user&lt;br /&gt;SecurityToken tokenDiscovery = Authenticate(UserName, UserPassword, AppliesToDiscovery, Policy, IssuerUri);&lt;br /&gt;SecurityToken token = Authenticate(UserName, UserPassword, AppliesTo, Policy, IssuerUri);&lt;br /&gt;//Execute the sample&lt;br /&gt;string serviceUrl = DiscoverOrganizationUrl(tokenDiscovery, OrganizationUniqueName, DiscoveryServiceUrl);&lt;br /&gt;ExecuteWhoAmI(token, serviceUrl);&lt;br /&gt;}&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;/ms-xrm:LiveTrust&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/199106851038957806-5638374908685789474?l=mscrmuk.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://mscrmuk.blogspot.com/feeds/5638374908685789474/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=199106851038957806&amp;postID=5638374908685789474' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/199106851038957806/posts/default/5638374908685789474'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/199106851038957806/posts/default/5638374908685789474'/><link rel='alternate' type='text/html' href='http://mscrmuk.blogspot.com/2012/01/using-wsdl-proxies-with-crm-online-its.html' title='Using WSDL Proxies with CRM Online. It&apos;s outside of North America'/><author><name>David Jennaway</name><uri>http://www.blogger.com/profile/09695858105618938443</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-199106851038957806.post-5610756032480635513</id><published>2011-11-04T18:09:00.001Z</published><updated>2011-11-04T18:09:00.127Z</updated><category scheme='http://www.blogger.com/atom/ns#' term='Workflow'/><title type='text'>Selecting the correct workflowid</title><content type='html'>A very quick one, which is mostly an aide-memoire for myself, but others may find useful.&lt;br /&gt;&lt;br /&gt;I occasionally need to run CRM workflows programmatically using an ExecuteWorkflow request. This takes a workflowid as a parameter, but the question is, which one ? If you look at the workflow entity, you'll find several records for a workflow with a given name. The logic I use to determine which is the correct on is:&lt;br /&gt;&lt;br /&gt;&lt;ul&gt;&lt;br /&gt;&lt;li&gt;statecode = 1 (Activated)&lt;/li&gt;&lt;br /&gt;&lt;li&gt;activeworkflowid is not null&lt;/li&gt;&lt;/ul&gt;&lt;br /&gt;&lt;p&gt;But use the workflowid value of the record for which activeworkflowid is not null. This seems a but counter-intuitive to me, hence this post&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/199106851038957806-5610756032480635513?l=mscrmuk.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://mscrmuk.blogspot.com/feeds/5610756032480635513/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=199106851038957806&amp;postID=5610756032480635513' title='5 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/199106851038957806/posts/default/5610756032480635513'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/199106851038957806/posts/default/5610756032480635513'/><link rel='alternate' type='text/html' href='http://mscrmuk.blogspot.com/2011/11/selecting-correct-workflowid.html' title='Selecting the correct workflowid'/><author><name>David Jennaway</name><uri>http://www.blogger.com/profile/09695858105618938443</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>5</thr:total></entry><entry><id>tag:blogger.com,1999:blog-199106851038957806.post-2804709636928367303</id><published>2011-07-13T09:55:00.002+01:00</published><updated>2011-07-13T10:04:59.726+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Server code'/><category scheme='http://www.blogger.com/atom/ns#' term='CRM 2011'/><category scheme='http://www.blogger.com/atom/ns#' term='Plugin'/><title type='text'>PartyList attributes and the plugin event pipeline</title><content type='html'>This should be a quick post about a subtlety with the plugin event pipeline. I recently wrote a plugin that could modify the data that's submitted when updating an activity record. This should have been a straightforward plugin on the Pre event that modified the Target InputParameter, and it all worked fine, except for partylist fields (such as the resources field on the serviceappointment entity, or optionalattendees on the appointment entity). Essentially, any changes I made to these fields in the plugin were ignored.&lt;br /&gt;&lt;br /&gt;Fortunately, there is a solution, and it depends on the stage that you register the plugin on. If you register on stage=20 (i.e. within the transaction), your changes are ignored. However, change the registration to stage=10 (before the transaction), then it does work. There's no documentation on this, but I expect it is due to how the partylist data is saved. This data is written to the activityparty table in the database, and I expect that the SQL for this is already fixed at the start of the transaction, and hence is unaffected by changes in the plugin code.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/199106851038957806-2804709636928367303?l=mscrmuk.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://mscrmuk.blogspot.com/feeds/2804709636928367303/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=199106851038957806&amp;postID=2804709636928367303' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/199106851038957806/posts/default/2804709636928367303'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/199106851038957806/posts/default/2804709636928367303'/><link rel='alternate' type='text/html' href='http://mscrmuk.blogspot.com/2011/07/partylist-attributes-and-plugin-event.html' title='PartyList attributes and the plugin event pipeline'/><author><name>David Jennaway</name><uri>http://www.blogger.com/profile/09695858105618938443</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-199106851038957806.post-3189469145195592261</id><published>2011-05-25T18:00:00.004+01:00</published><updated>2011-05-25T18:34:10.887+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Server code'/><category scheme='http://www.blogger.com/atom/ns#' term='CRM 2011'/><title type='text'>Unexpected error with ConditionOperator.In and typed arrays</title><content type='html'>I just met a bizarre error when using the Crm xrm assembly when using the ConditionOperator.In in a query. In this case the query was to find all notes related to a list of CRM entities, and the error was "Condition for attribute 'annotation.objectid': expected argument(s) of type 'System.Guid' but received 'System.Guid[]'". I was using almost identical code to some code that did work, but there was a subtle difference in the overloads of some of the xrm methods.&lt;br /&gt;&lt;br /&gt;Consider the following code, which works:&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family:courier new;font-size:85%;"&gt;QueryExpression q = new QueryExpression("annotation");&lt;br /&gt;Guid g1 = Guid.NewGuid();&lt;br /&gt;Guid g2 = Guid.NewGuid();&lt;br /&gt;q.Criteria.AddCondition(new ConditionExpression("objectid", ConditionOperator.In, new Guid[] { g1, g2 }));&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;However, change the last line to the following, and it fails with the error above:&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family:courier new;font-size:85%;"&gt;q.Criteria.AddCondition("objectid", ConditionOperator.In, new Guid[] { g1, g2 }); &lt;/span&gt;&lt;br /&gt;&lt;br /&gt;On the face of it, you'd expect identical behaviour, but it looks like the problem is due to the parameter overloads on the different methods. The constructor for ConditionExpression takes 5 overloads, and the compiler will use System.Collections.ICollection for the array of Guids. However, the AddCondition method only offers one type for the third parameter (params object[]). The result of this is that the code fails because the parameter is interpreted as object[] {new Guid[] { g1, g2 }}.&lt;br /&gt;&lt;br /&gt;Interestingly, other code can also work, e.g.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family:courier new;font-size:85%;"&gt;q.Criteria.AddCondition("objectid", ConditionOperator.In, new object[] { g1, g2 });&lt;br /&gt;q.Criteria.AddCondition("objectid", ConditionOperator.In, g1, g2); &lt;/span&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/199106851038957806-3189469145195592261?l=mscrmuk.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://mscrmuk.blogspot.com/feeds/3189469145195592261/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=199106851038957806&amp;postID=3189469145195592261' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/199106851038957806/posts/default/3189469145195592261'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/199106851038957806/posts/default/3189469145195592261'/><link rel='alternate' type='text/html' href='http://mscrmuk.blogspot.com/2011/05/unexpected-error-with.html' title='Unexpected error with ConditionOperator.In and typed arrays'/><author><name>David Jennaway</name><uri>http://www.blogger.com/profile/09695858105618938443</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-199106851038957806.post-6311562931982312558</id><published>2011-04-09T10:30:00.001+01:00</published><updated>2011-04-09T10:30:01.641+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Server code'/><category scheme='http://www.blogger.com/atom/ns#' term='CRM 2011'/><category scheme='http://www.blogger.com/atom/ns#' term='CRM 4.0'/><category scheme='http://www.blogger.com/atom/ns#' term='ASP .Net'/><title type='text'>Options for upgrading ASP .Net extensions for CRM 2011</title><content type='html'>I like April. One reason is that it's the start of my MVP renewal cycle. After April 1st April I will either have been renewed, or not, and I feel less circumspect about making critical comments about decisions Microsoft have made. So, ASP .Net extensions with CRM 2011. Since the first release of CRM (CRM 1.0 or CRM 1.2 depending on your country), a major extension point for On-Premise CRM implementations was to develop ASP .Net extensions and deploy them within the CRM web site. Having a supported way to place these extensions &lt;em&gt;within the CRM web site&lt;/em&gt; was important for several reasons: &lt;br /&gt;&lt;ol&gt;&lt;li&gt;To allow relative Urls in IFrames, ISV.Config and SiteMap. Main reasons for that are to cope with IFD environments where different domain names are provided for internal and external access, and to avoid configuration issues exporting/importing between environments&lt;/li&gt;&lt;li&gt;To allow single-sign on and impersonation, so the code could act on behalf of the CRM user, without needing to re-enter their credentials&lt;/li&gt;&lt;li&gt;To maintain the Site Origin (aka same site of origin). This is an important consideration as Internet Explorer security will only permit code interaction between pages if it considers that they are part of the same site. For example, the ability to pass data to a dialog using window.dialogArguments, or the ability to access objects on a calling window via window.opener both depend on the pages being in the same site&lt;/li&gt;&lt;/ol&gt;However, CRM 2011 puts significant &lt;a href="http://msdn.microsoft.com/en-us/library/gg309571.aspx"&gt;restrictions &lt;/a&gt;on putting your ASP .Net extensions within the CRM web site. Essentially, the only supported option is to retain existing extensions that use the CRM 4 endpoint. So, what happens to the points above if you can't put your ASP .Net extensions in the CRM web site: &lt;br /&gt;&lt;ol&gt;&lt;li&gt;You'll have to use absolute Urls. This makes deployment between environments (e.g. from development to live) harder, as the Urls would have to changed. In small-scale environments this would be just a manual task, but in larger environments you may decide to build a process to automate this. Overall, I see this as a major annoyance, but not a major problem&lt;/li&gt;&lt;li&gt;Microsoft have put &lt;a href="http://msdn.microsoft.com/en-us/library/gg509061.aspx"&gt;work &lt;/a&gt;into making single sign-on work across web sites. This depends on setting up Secure Token Services, which incurs some administrative and deployment overhead. There's an additional deployment overhead of setting up a new web site for the extensions, and configuring access to it. I've not tested this fully, but assuming it works as promised, this should resolve the single sign-on and impersonation issue&lt;/li&gt;&lt;li&gt;This is the big problem area. I don't think same site of origin can be maintained with the ASP .Net pages outside of the CRM web site, which effectively removes support for a common type of extension that was possible in all previous versions (Note, IE 8 has some settings that affect how Site Origin is applied, and this might help, but IE 7 is a supported browser for CRM 2011, so this cannot be a universal solution)&lt;/li&gt;&lt;/ol&gt;&lt;p&gt;So, what can/should you do with your ASP .Net extensions that you wrote for CRM 4.0, or were intending to write. I see 3 main options:&lt;/p&gt;&lt;ol&gt;&lt;li&gt;Don't upgrade your code. ASP .Net code that uses the CRM 4 web service endpoint will still work in the ISV folder, and Microsoft have not said it is unsupported. This is the simplest option, but it means you need to maintain CRM 4 code, and you'll still have to address the issue when CRM 6 comes out. You could cross your fingers and hope that, in CRM 6, Microsoft reintroduce support for ASP .Net extensions within the CRM web site&lt;/li&gt;&lt;li&gt;Upgrade the code to use the CRM 2011 endpoint, and deploy it in a separate web-site from CRM. As stated above, this causes extra deployment overhead (which I consider is a significant overhead, which is often under-estimated), and you won't be able to use same site of origin, so you have to expect some limitations&lt;/li&gt;&lt;li&gt;Rewrite the code as web resources (Silverlight, or HTML with javascript). Microsoft have introduced quite a lot of integration points in CRM 2011 that makes this a powerful option. This has a major advantage that the resources are necessarily hosted within the CRM web site, and can be deployed as part of a CRM solution. However, these are client-side technologies and some extensions would need extra work to build (e.g. extensions that access a database on another server). My biggest problem though is the development effort required to rewrite code in substantially different technologies, and these are technologies that are not as mature as ASP .Net&lt;/li&gt;&lt;/ol&gt;&lt;p&gt;Of these, I don't like any of the options. Numbers 2 and 3 would be necessary if you need to support CRM Online, but for On-Premise implementations there are some difficult decisions to make. Don't get me wrong, I appreciate that there are a lot of good things for developers in CRM 2011; web resources and the single sign-on across web-sites are very powerful and very welcome, and the only options for CRM Online, it's just a shame to lose some On-Premise options.&lt;/p&gt;&lt;p&gt;But to finish on a more positive note, another reason I like April is that this is a great month for ski touring.&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/199106851038957806-6311562931982312558?l=mscrmuk.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://mscrmuk.blogspot.com/feeds/6311562931982312558/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=199106851038957806&amp;postID=6311562931982312558' title='3 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/199106851038957806/posts/default/6311562931982312558'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/199106851038957806/posts/default/6311562931982312558'/><link rel='alternate' type='text/html' href='http://mscrmuk.blogspot.com/2011/04/options-for-upgrading-asp-net.html' title='Options for upgrading ASP .Net extensions for CRM 2011'/><author><name>David Jennaway</name><uri>http://www.blogger.com/profile/09695858105618938443</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>3</thr:total></entry><entry><id>tag:blogger.com,1999:blog-199106851038957806.post-8797091020864871995</id><published>2011-04-08T15:50:00.005+01:00</published><updated>2011-04-08T16:13:38.421+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Security'/><category scheme='http://www.blogger.com/atom/ns#' term='Troubleshooting'/><title type='text'>Removing prompt for credentials when browsing with Internet Explorer</title><content type='html'>&lt;p&gt;This post isn't intended to be a complete list of solutions to issue when you are unexpectedly prompted for AD credentials when browsing with Internet Explorer, but it gives some rules of thumb regarding where to start looking. The scenario: You try accessing a page using IE, and are prompted by a 'Windows Security' dialog for AD credentials when you don't expect it. &lt;/p&gt;&lt;a href="http://3.bp.blogspot.com/--oXfOvNi_fc/TZ8lHrpnDyI/AAAAAAAAADA/hh5fZB_dwwk/s1600/IEPrompt.jpg"&gt;&lt;img style="TEXT-ALIGN: center; MARGIN: 0px auto 10px; WIDTH: 320px; DISPLAY: block; HEIGHT: 317px; CURSOR: hand" id="BLOGGER_PHOTO_ID_5593230076124008226" border="0" alt="" src="http://3.bp.blogspot.com/--oXfOvNi_fc/TZ8lHrpnDyI/AAAAAAAAADA/hh5fZB_dwwk/s320/IEPrompt.jpg" /&gt;&lt;/a&gt;&lt;p&gt;Possible causes: There are many, but the first thing to do is work out if it's a server-side issue, or a client-side issue. A simple test is what happens if you provide valid credentials in the Windows Security dialog: &lt;br /&gt;&lt;ul&gt;&lt;li&gt;If you can then connect, then this is a client-side issue&lt;/li&gt;&lt;li&gt;If you are prompted again, either 2 or 3 times, then get a permission error (normally HTTP 401), then it is a server-side issue&lt;/li&gt;&lt;/ul&gt;&lt;/p&gt;&lt;p&gt;&lt;strong&gt;Client-side issues &lt;/strong&gt;If it's a client-side issue, then look at the client IE settings, and the URL of the web page: If IE considers that you have already logged into the DNS domain (the part of the url prior to the first single / - e.g. &lt;a href="http://crm:5555/"&gt;http://crm:5555/&lt;/a&gt;), then it should reuse these credentials and you won't be prompted to login. However, IE is picky about matching the DNS domain, so if you've already logged into http://crm, then it won't trust other aliases (e.g. http://localhost, http://crm.mydom.com, http://192.168.0.1) and will prompt for credentials. &lt;/p&gt;&lt;p&gt;If you're using CRM 4 and have extension pages in the ISV directory of the CRM web site, then it is best to provide the URL as a relative path (e.g. /ISV/MyCompany/MyPage.aspx) rather than an absolute path, to avoid this issue.&lt;/p&gt;&lt;p&gt;The IE security settings will determine whether IE will try submitting your logged-on credentials. By default, it will only do this if you connect to a site in the Local Intranet Zone, so check the IE security settings, and the zone of the web site you're connecting to &lt;/p&gt;&lt;p&gt;&lt;strong&gt;Server-side issues&lt;/strong&gt; If it's a server-side issue, then there are many possible causes, but most of them come to Kerberos in one way or another &lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/199106851038957806-8797091020864871995?l=mscrmuk.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://mscrmuk.blogspot.com/feeds/8797091020864871995/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=199106851038957806&amp;postID=8797091020864871995' title='3 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/199106851038957806/posts/default/8797091020864871995'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/199106851038957806/posts/default/8797091020864871995'/><link rel='alternate' type='text/html' href='http://mscrmuk.blogspot.com/2011/04/removing-prompt-for-credentials-when.html' title='Removing prompt for credentials when browsing with Internet Explorer'/><author><name>David Jennaway</name><uri>http://www.blogger.com/profile/09695858105618938443</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://3.bp.blogspot.com/--oXfOvNi_fc/TZ8lHrpnDyI/AAAAAAAAADA/hh5fZB_dwwk/s72-c/IEPrompt.jpg' height='72' width='72'/><thr:total>3</thr:total></entry><entry><id>tag:blogger.com,1999:blog-199106851038957806.post-5903480579090666397</id><published>2011-02-28T19:26:00.004Z</published><updated>2011-02-28T19:53:08.584Z</updated><category scheme='http://www.blogger.com/atom/ns#' term='SQL Server'/><title type='text'>Possible SQL Gotcha - use of 'Not In' with NULLs and the customer attribute</title><content type='html'>I was recently putting together a bit of SQL to illustrate the use of a NOT IN clause for a forum answer, and got some unexpected results. The query was a relatively simple example; find all accounts with no associated opportunities. So, I tried this:&lt;br /&gt;&lt;br /&gt;SELECT name FROM FilteredAccount&lt;br /&gt;WHERE accountid NOT IN (SELECT accountid FROM FilteredOpportunity)&lt;br /&gt;&lt;br /&gt;Nice, simple query, but it returned no data (and it should have done). However, the following works fine:&lt;br /&gt;&lt;br /&gt;SELECT name FROM FilteredAccount&lt;br /&gt;WHERE accountid NOT IN (SELECT customerid FROM FilteredOpportunity)&lt;br /&gt;&lt;br /&gt;The only difference is the use of customerid instead of accountid in the subquery. If I'd have expected the first query to work instead of the second query, as customerid is a generated field (it's generated within the Opportunity via by the SQL function COALESCE(accountid, contactid)).&lt;br /&gt;&lt;br /&gt;This all seems weird, but it comes down to what happens with nulls. An opportunity will be associated with one of an account, or a contact. So, the subquery 'SELECT accountid FROM FilteredOpportunity' could return a null (if you have an opportunity against a contact), but 'SELECT customerid FROM FilteredOpportunity' will always return non-null values. Don't ask me why, but the presence of nulls in the subquery cause the NOT IN query to misbehave.&lt;br /&gt;&lt;br /&gt;One way to confirm this is with another variation on the query above, which also works:&lt;br /&gt;&lt;br /&gt;SELECT name FROM FilteredAccount&lt;br /&gt;WHERE accountid NOT IN (SELECT accountid FROM FilteredOpportunity WHERE accountid is NOT NULL)&lt;br /&gt;&lt;br /&gt;This query explicitly excludes nulls from the results on the subquery, and so it works fine.&lt;br /&gt;&lt;br /&gt;The main lesson I took from this is to always test for nulls in the subquery when using NOT IN; another lesson is to pay close attention when using attributes that represent the composite Customer data type in CRM&lt;br /&gt;&lt;br /&gt;For reference, the reason why I was doing this is because this is a classic example of a query that cannot be done through FetchXML, and hence cannot be written with an Advanced Find in CRM. If the primary entity is an account, contact or lead then you have a manual workaround in CRM, for example:&lt;br /&gt;&lt;ul&gt;&lt;li&gt;Create a marketing list, and populate it with all accounts&lt;/li&gt;&lt;li&gt;Use Advanced Find to remove from the list all accounts that have an opportunity&lt;/li&gt;&lt;li&gt;This will then leave you with a marketing list that contains all accounts without an opportunity&lt;/li&gt;&lt;/ul&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/199106851038957806-5903480579090666397?l=mscrmuk.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://mscrmuk.blogspot.com/feeds/5903480579090666397/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=199106851038957806&amp;postID=5903480579090666397' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/199106851038957806/posts/default/5903480579090666397'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/199106851038957806/posts/default/5903480579090666397'/><link rel='alternate' type='text/html' href='http://mscrmuk.blogspot.com/2011/02/possible-sql-gotcha-use-of-not-in-with.html' title='Possible SQL Gotcha - use of &apos;Not In&apos; with NULLs and the customer attribute'/><author><name>David Jennaway</name><uri>http://www.blogger.com/profile/09695858105618938443</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-199106851038957806.post-8047671192176613549</id><published>2011-02-16T16:00:00.003Z</published><updated>2011-02-16T16:07:53.729Z</updated><category scheme='http://www.blogger.com/atom/ns#' term='CRM 2011'/><category scheme='http://www.blogger.com/atom/ns#' term='Announcement'/><title type='text'>CRM 2011 RTM Release</title><content type='html'>Seems like the day for announcements: the CRM 2011 RTM code has been &lt;a href="http://www.microsoft.com/Presspass/press/2011/feb11/02-16OnPremisesPR.mspx"&gt;released&lt;/a&gt; for On-Premise and Partner-Hosted environments. This is nearly 2 weeks earlier than I expected, so congratulations to the CRM product team.&lt;br /&gt;&lt;br /&gt;The server software can be downloaded &lt;a href="http://www.microsoft.com/downloads/en/details.aspx?FamilyID=c3f82c6f-c123-4e80-b9b2-ee422a16b91d"&gt;here&lt;/a&gt;, and that page has links to download the other components. The build number is 05.00.9688.583, which is consistent with the build number of the binaries in the release &lt;a href="http://go.microsoft.com/fwlink/?LinkID=207027"&gt;SDK&lt;/a&gt;.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/199106851038957806-8047671192176613549?l=mscrmuk.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://mscrmuk.blogspot.com/feeds/8047671192176613549/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=199106851038957806&amp;postID=8047671192176613549' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/199106851038957806/posts/default/8047671192176613549'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/199106851038957806/posts/default/8047671192176613549'/><link rel='alternate' type='text/html' href='http://mscrmuk.blogspot.com/2011/02/crm-2011-rtm-release.html' title='CRM 2011 RTM Release'/><author><name>David Jennaway</name><uri>http://www.blogger.com/profile/09695858105618938443</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-199106851038957806.post-7017946511576673231</id><published>2011-02-16T11:35:00.004Z</published><updated>2011-02-17T17:28:49.236Z</updated><category scheme='http://www.blogger.com/atom/ns#' term='Server code'/><category scheme='http://www.blogger.com/atom/ns#' term='CRM 2011'/><category scheme='http://www.blogger.com/atom/ns#' term='Troubleshooting'/><category scheme='http://www.blogger.com/atom/ns#' term='SDK'/><category scheme='http://www.blogger.com/atom/ns#' term='CRM 4.0'/><title type='text'>Using CRM 4.0 assemblies on a CRM 2011 Server</title><content type='html'>CRM 2011 Server includes a &lt;a href="http://msdn.microsoft.com/en-us/library/06d2bae3.aspx"&gt;publisher policy&lt;/a&gt; that causes any assembly built against the CRM 4 sdk assemblies to load the CRM 5 sdk assemblies instead. There are certain circumstances where this can cause errors loading the assembly; see the end of this post for possible error messages.&lt;br /&gt;&lt;br /&gt;One workaround is to not run the application on a Crm 2011 Server, but there is an alternative, which is to explictly tell your application not to use this publisher policy file. This is done through adding the following to the app.config file:&lt;br /&gt;&lt;br /&gt;&amp;lt;configuration&amp;gt;&lt;br /&gt;&amp;lt;runtime&amp;gt;&lt;br /&gt;&amp;lt;assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1"&amp;gt;&lt;br /&gt;&amp;lt;dependentAssembly&amp;gt;&lt;br /&gt;&amp;lt;assemblyIdentity name="Microsoft.Crm.Sdk" publicKeyToken="31bf3856ad364e35" culture="neutral" /&amp;gt;&lt;br /&gt;&amp;lt;publisherPolicy apply="no" /&amp;gt;&lt;br /&gt;&amp;lt;/dependentAssembly&amp;gt;&lt;br /&gt;&amp;lt;/assemblyBinding&amp;gt;&lt;br /&gt;&amp;lt;/runtime&amp;gt;&lt;br /&gt;&amp;lt;/configuration&amp;gt;&lt;br /&gt;&lt;br /&gt;This raises one more issue: in some circumstances your assembly may not be the main .exe, but a .dll loaded by another process, in which case you'll have to modify/create the .config file for that .exe. This is done by creating a file named &lt;executablename&gt;.exe.config in the same directory as the &lt;executablename&gt;.exe (here's an &lt;a href="http://mscrmuk.blogspot.com/2007/11/workflow-problems-on-crm-30-with-net.html"&gt;example&lt;/a&gt;). I have a nagging concern that I may have to do this with SSIS packages that use a custom component that use the SDK assemblies, which could get interesting, as different executables are used for in design, debug and runtime. If I do have this issue with SSIS, then I'll post a more detailed workaround (if I find it).&lt;br /&gt;&lt;br /&gt;My hope is that this is a temporary problem that will be fixed, as the readme in the 5.0.1 version of the &lt;a href="http://www.microsoft.com/downloads/en/details.aspx?FamilyID=420f0f05-c226-4194-b7e1-f23ceaa83b69"&gt;SDK&lt;/a&gt; refers to an 'incorrect Publisher Policy'. This readme also gives an explanation of this issue&lt;br /&gt;&lt;br /&gt;&lt;strong&gt;One possible error&lt;/strong&gt;&lt;br /&gt;System.IO.FileLoadException: Could not load file or assembly 'Microsoft.Crm.Sdk, Version=5.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35' or one of its dependencies. The located assembly's manifest definition does not match the assembly reference. (Exception from HRESULT: 0x80131040)&lt;br /&gt;File name: 'Microsoft.Crm.Sdk, Version=5.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35' ---&gt; System.IO.FileLoadException: Could not load file or assembly 'Microsoft.Crm.Sdk, Version=4.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35' or one of its dependencies. The located assembly's manifest definition does not match the assembly reference. (Exception from HRESULT: 0x80131040)&lt;br /&gt;File name: 'Microsoft.Crm.Sdk, Version=4.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35'&lt;br /&gt;&lt;br /&gt;&lt;strong&gt;Another possible error&lt;/strong&gt;&lt;br /&gt;System.IO.FileNotFoundException: Could not load file or assembly 'Microsoft.Crm.Sdk, Version=5.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35' or one of its dependencies. The system cannot find the file specified.&lt;br /&gt;System.IO.FileNotFoundException: Could not load file or assembly 'Microsoft.Crm.Sdk, Version=4.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35' or one of its dependencies. The system cannot find the file specified.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/199106851038957806-7017946511576673231?l=mscrmuk.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://mscrmuk.blogspot.com/feeds/7017946511576673231/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=199106851038957806&amp;postID=7017946511576673231' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/199106851038957806/posts/default/7017946511576673231'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/199106851038957806/posts/default/7017946511576673231'/><link rel='alternate' type='text/html' href='http://mscrmuk.blogspot.com/2011/02/using-crm-40-assemblies-on-crm-2011.html' title='Using CRM 4.0 assemblies on a CRM 2011 Server'/><author><name>David Jennaway</name><uri>http://www.blogger.com/profile/09695858105618938443</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-199106851038957806.post-8334323268378209585</id><published>2011-02-16T09:01:00.003Z</published><updated>2011-02-16T11:35:03.813Z</updated><category scheme='http://www.blogger.com/atom/ns#' term='CRM 2011'/><category scheme='http://www.blogger.com/atom/ns#' term='Announcement'/><category scheme='http://www.blogger.com/atom/ns#' term='SDK'/><category scheme='http://www.blogger.com/atom/ns#' term='Documentation'/><title type='text'>CRM 2011 Documentation Released</title><content type='html'>The &lt;a href="http://www.microsoft.com/downloads/en/details.aspx?FamilyID=9886AB96-3571-420F-83AD-246899482FB4"&gt;CRM 2011 Implementation Guide&lt;/a&gt; was released last week, and it looks like the &lt;a href="http://www.microsoft.com/downloads/en/details.aspx?FamilyID=420f0f05-c226-4194-b7e1-f23ceaa83b69"&gt;CRM 2011 SDK&lt;/a&gt; has also been released. As far as I can tell, the SDK is a live (as opposed to beta) release, though the hands-on labs were built on beta code. The SDK documentation has version 5.0.1, and it includes binaries with version 5.0.9688.583 which are claimed to match those for CRM 2011 Online. We'll see what version number we get with the RTM code.&lt;br /&gt;&lt;br /&gt;And the &lt;a href="http://blogs.msdn.com/b/crm/archive/2011/02/14/announcement-microsoft-dynamics-crm-2011-developer-training-kit.aspx"&gt;CRM 2011 Developer Training Kit&lt;/a&gt; has also been released recently.&lt;br /&gt;&lt;br /&gt;I'm deliberately using the term released to indicate that they are publicly available (as opposed to 'launch', which I consider a marketing event).&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/199106851038957806-8334323268378209585?l=mscrmuk.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://mscrmuk.blogspot.com/feeds/8334323268378209585/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=199106851038957806&amp;postID=8334323268378209585' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/199106851038957806/posts/default/8334323268378209585'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/199106851038957806/posts/default/8334323268378209585'/><link rel='alternate' type='text/html' href='http://mscrmuk.blogspot.com/2011/02/crm-2011-documentation-released.html' title='CRM 2011 Documentation Released'/><author><name>David Jennaway</name><uri>http://www.blogger.com/profile/09695858105618938443</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-199106851038957806.post-5246087973233053092</id><published>2011-02-11T10:01:00.002Z</published><updated>2011-02-11T10:07:17.997Z</updated><category scheme='http://www.blogger.com/atom/ns#' term='Server code'/><category scheme='http://www.blogger.com/atom/ns#' term='Plugin'/><title type='text'>Plugin Deployment Options</title><content type='html'>&lt;p&gt;The CRM 4 SDK gives some information about the storage options when &lt;a href="http://msdn.microsoft.com/en-us/library/cc151098.aspx"&gt;registering plugins&lt;/a&gt; but there are a few more considerations. I got prompted to elaborate on this in a forum &lt;a href="http://social.microsoft.com/Forums/en-US/crmdeployment/thread/fdf17be4-b843-44da-af56-a4c2f0a6544f"&gt;post&lt;/a&gt;, and I think it's worth documenting this here as well:&lt;br /&gt;&lt;br /&gt;The 3 storage options are: Database, Disk and GAC. The main differences between these are: &lt;/p&gt;&lt;ul&gt;&lt;li&gt;Database: The assembly dll is stored in the database, rather than the file system. The major advantages are that the assembly need only be deployed once if you have multiple CRM servers, and that no additional action is required to restore / redeploy the assembly either during disaster recovery, or if redeploying to an alternate server. This is the preferred option in a production environment&lt;/li&gt;&lt;li&gt;Disk: The assembly dll is placed in the &lt;crm&gt;\server\bin\assembly directory on each server. You have to ensure the dll is placed in the correct place on all CRM servers, so the deployment overhead is a little greater. I normally use this option in development environments as you can redeploy newer versions solely by file transfer, rather than reregistering. Also, if debugging, the assembly .pdb file needs to be placed in the same location; with this option it's easy to ensure the dll and pdb are from the same build&lt;/li&gt;&lt;li&gt;GAC: The assembly is placed in the Global Assembly Cache on each CRM server, and again you will have to do this. The GAC does allow multiple versions of an assembly, but CRM doesn't, so you don't really gain anything by using the GAC. I don't think I've ever used this option &lt;/li&gt;&lt;/ul&gt;&lt;p&gt;There is one further consideration. If your plugin assembly has other dependent assemblies, then you can place this dependent assembly in the GAC whichever of the above options you take. However, if you use the Disk option, then the dependent assemblies can also be deployed into the \server\bin\assembly directory&lt;br /&gt;&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/199106851038957806-5246087973233053092?l=mscrmuk.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://mscrmuk.blogspot.com/feeds/5246087973233053092/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=199106851038957806&amp;postID=5246087973233053092' title='4 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/199106851038957806/posts/default/5246087973233053092'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/199106851038957806/posts/default/5246087973233053092'/><link rel='alternate' type='text/html' href='http://mscrmuk.blogspot.com/2011/02/plugin-deployment-options.html' title='Plugin Deployment Options'/><author><name>David Jennaway</name><uri>http://www.blogger.com/profile/09695858105618938443</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>4</thr:total></entry><entry><id>tag:blogger.com,1999:blog-199106851038957806.post-4525002414782928805</id><published>2011-02-04T16:17:00.002Z</published><updated>2011-02-04T16:35:40.332Z</updated><category scheme='http://www.blogger.com/atom/ns#' term='SQL Server 2008'/><category scheme='http://www.blogger.com/atom/ns#' term='SSIS'/><title type='text'>.Net Framework versions of custom components with SQL 2008 R2 BIDS</title><content type='html'>&lt;p&gt;Rather a long title, but I couldn't think of anything shorter. Anyway, it's a topic that I would have preferred was better publicised.&lt;br /&gt;&lt;br /&gt;SQL 2008 R2 Business Intelligence Development Studio (BIDS) will only recognise extension components (such as SSIS Data Flow Components) that are built against .Net Framework 3.5. Neither earlier nor later versions will work, and I've yet to find any useful messages to tell you why.&lt;br /&gt;&lt;br /&gt;So far I've only done enough testing to find combinations that definitely work, as summarised in the following table. &lt;/p&gt;&lt;table&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td&gt;&lt;b&gt;BIDS Version&lt;/b&gt;&lt;/td&gt;&lt;td&gt;&lt;b&gt;.Net Framework version of component&lt;/b&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;SQL 2005&lt;/td&gt;&lt;td&gt;2.0&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;SQL 2008&lt;/td&gt;&lt;td&gt;2.0&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;SQL 2008 R2&lt;/td&gt;&lt;td&gt;3.5&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/199106851038957806-4525002414782928805?l=mscrmuk.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://mscrmuk.blogspot.com/feeds/4525002414782928805/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=199106851038957806&amp;postID=4525002414782928805' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/199106851038957806/posts/default/4525002414782928805'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/199106851038957806/posts/default/4525002414782928805'/><link rel='alternate' type='text/html' href='http://mscrmuk.blogspot.com/2011/02/net-framework-versions-of-custom.html' title='.Net Framework versions of custom components with SQL 2008 R2 BIDS'/><author><name>David Jennaway</name><uri>http://www.blogger.com/profile/09695858105618938443</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-199106851038957806.post-6352512226330165419</id><published>2010-12-09T11:11:00.006Z</published><updated>2010-12-09T11:36:54.347Z</updated><category scheme='http://www.blogger.com/atom/ns#' term='Workflow'/><category scheme='http://www.blogger.com/atom/ns#' term='Troubleshooting'/><category scheme='http://www.blogger.com/atom/ns#' term='Asychronous Service'/><title type='text'>Stability issues with AsyncRemoveCompletedJobs</title><content type='html'>CRM 4.0 UR 3 brought in a useful feature, the ability to configure the CRM Asynchronous Service to automatically delete records from completed asynchronous operations, and hence keep the size of the asyncoperationbase SQL table down to a reasonable size. This behaviour is configured by the registry values &lt;a href="http://support.microsoft.com/kb/957871"&gt;AsyncRemoveCompletedJobs &lt;/a&gt;and &lt;a href="http://support.microsoft.com/kb/968755"&gt;AsyncRemoveCompletedWorkflows &lt;/a&gt;&lt;br /&gt;&lt;br /&gt;However, I recently met an issue with this behaviour, where the CRM Asynchronous Service appears to get in a state where all it is doing is deleting completed jobs, to the exclusion of all other activity. This can leave the CRM Asynchronous Service to have effectively hung (not responding to service control requests, nor polling for new jobs to process) and not to process any new jobs for a considerable period of time (in one environment, this could be several hours).&lt;br /&gt;&lt;br /&gt;The main symptoms are:&lt;br /&gt;&lt;br /&gt;&lt;ul&gt;&lt;li&gt;No jobs being processed for a considerable period of time&lt;/li&gt;&lt;li&gt;The Crm Asynchronous Service not responding to service control requests (i.e. you cannot stop it through the Services console, so you have to kill the process)&lt;/li&gt;&lt;li&gt;No values reported for most performance counters (e.g. 'Total Operations Outstanding', 'Threads in use')&lt;/li&gt;&lt;li&gt;If you do restart the service, you see a burst of activity (including performance counters) whilst outstanding jobs are processed, then it reverts to the same behaviour as above&lt;/li&gt;&lt;li&gt;If you look at the SQL requests submitted by the Crm Asynchronous Service (I use the SQL dynamic management views sys.dm_exec_requests and sys.dm_exec_sessions) you see just one DELETE request and no other SQL activity&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;At the moment, the only workaround I have is to remove the registry values, and to use a scheduled SQL job to periodically clear out the asyncoperationbase table. &lt;a href="http://support.microsoft.com/kb/968520"&gt;Here &lt;/a&gt;is an example of such a script.&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/199106851038957806-6352512226330165419?l=mscrmuk.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://mscrmuk.blogspot.com/feeds/6352512226330165419/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=199106851038957806&amp;postID=6352512226330165419' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/199106851038957806/posts/default/6352512226330165419'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/199106851038957806/posts/default/6352512226330165419'/><link rel='alternate' type='text/html' href='http://mscrmuk.blogspot.com/2010/12/stability-issues-with.html' title='Stability issues with AsyncRemoveCompletedJobs'/><author><name>David Jennaway</name><uri>http://www.blogger.com/profile/09695858105618938443</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-199106851038957806.post-3796489791387277455</id><published>2010-11-17T18:18:00.005Z</published><updated>2010-11-17T21:02:38.591Z</updated><category scheme='http://www.blogger.com/atom/ns#' term='Server code'/><category scheme='http://www.blogger.com/atom/ns#' term='Security'/><category scheme='http://www.blogger.com/atom/ns#' term='How it Works'/><category scheme='http://www.blogger.com/atom/ns#' term='CRM 4.0'/><category scheme='http://www.blogger.com/atom/ns#' term='ASP .Net'/><title type='text'>How to use impersonation in an ASP .Net page using IFD in CRM 4.0</title><content type='html'>This is is common requirement, and I've never found what I consider to be a suitable explanation of what needs to be done. This post is not intended to be exhaustive, but is intended to cover the essentials in one place.&lt;br /&gt;&lt;br /&gt;The fundamental requirement is to create a custom ASP .Net page that is accessible both internally (via AD authentication) and over the Internet (via IFD authentication), and where the code will access CRM data under the context of the user accessing the page. To do this, you need to deploy and configure your code as follows:&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;ol&gt;&lt;li&gt;Deploy the ASP .Net page within the CRM Web Site (the only supported place is within the ISV directory). If you don't do this, then IFD authentication will not apply to your page&lt;/li&gt;&lt;li&gt;Run the ASP .Net page within the CrmAppPool, and do not create an IIS application for it. If you don't do this, then you won't be able to identify the authenticated user&lt;/li&gt;&lt;li&gt;Ensure that the CRM HttpModules MapOrg and CrmAuthentication are enabled. This will happen by default by inheritance of the settings from the root web.config file in the CRM web site, but I'm mentioning it here as there are some circumstances (when you don't need IFD) in which it is appropriate to disable these HttpModules. Again, if the HttpModules aren't enabled, then you won't be able to identify the authenticated user&lt;/li&gt;&lt;li&gt;As your code is in a virtual directory (rather than a separate IIS application), ASP .Net will look for your assemblies in the [webroot]\bin folder, so that is where you should put them (or in the GAC). The initial release documentation for CRM 4.0 stated that it was unsupported to put files in [webroot]\bin folder of the CRM web site, but this restriction has been lifted&lt;/li&gt;&lt;/ol&gt;&lt;p&gt;You also need to follow certain coding patterns within your code. An example of these can be found &lt;a href="http://msdn.microsoft.com/en-us/library/cc151050.aspx"&gt;here&lt;/a&gt;. Note that, Crm web services refers to both the CrmService and the MetadataService:&lt;/p&gt;&lt;ol&gt;&lt;li&gt;Ensure you can identify the organisation name. The example code shows how to parse this from the Request.Url property, though I prefer to pass this on the querystring (which the example also supports)&lt;/li&gt;&lt;li&gt;Use the CrmImpersonator class. All access to the Crm web services needs to be wrapped within the &lt;span style="font-family:courier new;"&gt;using&lt;/span&gt; &lt;span style="font-family:courier new;"&gt;(new CrmImpersonator())&lt;/span&gt; block. If you don't do this you will probably get 401 errors, often when accessing the page internally via AD authentication (see later for a brief explanation)&lt;/li&gt;&lt;li&gt;Use the &lt;span style="font-family:courier new;"&gt;ExtractCrmAuthenticationToken&lt;/span&gt; static method. This is necessary to get the context of the calling user (which is stored in the CallerId property)&lt;/li&gt;&lt;li&gt;Use &lt;span style="font-family:courier new;"&gt;CredentialCache.DefaultCredentials&lt;/span&gt; to pass AD credentials to the Crm web services. If you don't do this, then you will probably get 401 errors as you'd be trying to access the web service anonymously (IIS would throw these 401 errors)&lt;/li&gt;&lt;/ol&gt;&lt;p&gt;That should be all that you need on the server side. The final piece of the puzzle is to ensure that you provide the correct Url when accessing the page, which again needs a little consideration:&lt;/p&gt;&lt;p&gt;When accessing the page from an internal address, the Url should be of the form:&lt;br /&gt;&lt;span style="font-family:courier new;font-size:85%;"&gt;http://[server]/[orgname]/ISV/MyFolder/MyPage.aspx&lt;/span&gt;&lt;/p&gt;&lt;p&gt;When accessing the page from an external address, the Url should be of the form:&lt;br /&gt;&lt;span style="font-family:courier new;font-size:85%;"&gt;http://[orgname].[serverFQDN]/ISV/MyFolder/MyPage.aspx&lt;/span&gt;&lt;/p&gt;&lt;p&gt;This is relatively easy to achieve when opening the page from within CRM (i.e. in an IFrame, via an ISV.config button or in client script). In each case you can use the &lt;a href="http://msdn.microsoft.com/en-us/library/cc905758.aspx"&gt;PrependOrgName&lt;/a&gt; global function in client script - e.g. &lt;/p&gt;&lt;p&gt;&lt;span style="font-family:courier new;font-size:85%;"&gt;var u = PrependOrgName('/ISV/MyFolder/MyPage.aspx');&lt;/span&gt;&lt;/p&gt;&lt;p&gt;This function will determine correctly whether to add the organisation name to the Url. Note also that I've provided a relative Url, which will ensure the first part of the Url is always correct. As this uses a JavaScript function, you will always need to use a small piece of code to access the page, and cannot rely on statically providing the Url in the source of an IFrame, or in the Url attribute of an ISV.Config button. Any relative Urls in SiteMap should automatically get the organisation name applied correctly. Remember to also pass the organisation name on the querystring if the server code expects this (you can get the organisation name from the &lt;a href="http://msdn.microsoft.com/en-us/library/cc150876.aspx"&gt;ORG_UNIQUE_NAME&lt;/a&gt; global variable)&lt;/p&gt;&lt;p&gt;Earlier I promised an explanation of what the server code does. This is not as complete an explanation as it could be, but the basics are:&lt;/p&gt;&lt;ol&gt;&lt;li&gt;The HttpModules identify the correct CRM organisation (MapOrg) from the Url provided, and place information about the authenticated calling user in the HttpContext (CrmAuthentication)&lt;/li&gt;&lt;li&gt;The ExtractCrmAuthenticationToken method reads the user context from the HttpContext, and puts the user's systemuserid in the CallerId property of the CrmAuthenticationToken&lt;/li&gt;&lt;li&gt;Because the CallerId is set, the call to CRM is necessarily using CRM impersonation. For this to be permitted, the execution account (see &lt;a href="http://crmentropy.blogspot.com/search/label/impersonation"&gt;Dave Berry's blog&lt;/a&gt; for a definition) must be a member of the AD group PrivUserGroup. The execution account is the AD account that is returned by CredentialCache.DefaultCredentials. This is where things get a little interesting&lt;/li&gt;&lt;li&gt;If the request comes via the external network and IFD authentication is used, CRM handles the authentication outside of IIS and no IIS / ASP .Net impersonation occurs. Therefore CredentialCache.DefaultCredentials will return the AD identity of the process, which is the identity of the CrmAppPool, which necessarily is a member of PrivUserGroup&lt;/li&gt;&lt;li&gt;However, if the request comes via the internal network, AD authentication is used and IIS / ASP .Net impersonation does occur (through the &lt;identity impersonate="true"&gt;setting in web.config). This impersonation will change the execution context of the thread, and CredentialCache.DefaultCredentials would then return the AD context of the caller. This is fine in a pure AD authentication scenario, but the use of the ExtractCrmAuthenticationToken method means that CRM impersonation is necessarily expected; this will only work if the execution account is a member of PrivUserGroup, and CRM users should not be members of PrivUserGroup. This is where the CrmImpersonator class comes in: its constructor reverts the thread's execution context to that of the process (i.e. it undoes the IIS / ASP .Net impersonation), so that CredentialCache.DefaultCredentials will now return the identity of the CrmAppPool, and the CRM platform will permit CRM impersonation &lt;/li&gt;&lt;/ol&gt;&lt;p&gt;To finish off, here are a few other points to note:&lt;/p&gt;&lt;ul&gt;&lt;li&gt;IFD impersonation only applies when accessing the CRM platform. If you use IFD authentication, there is no way of impersonating the caller when accessing non-CRM resources (e.g. SQL databases, SharePoint, the file system); it cannot be done, so save yourself the effort and don't even try (though, for completeness, SQL impersonation is possible using EXECUTE AS, but that's it)&lt;/li&gt;&lt;li&gt;If you want to use impersonation, do not use the CrmDiscoveryService. The CrmDiscoveryService can only be used with IFD if you know the user's username and password, and you won't know these unless you prompt the user, which kind of defeats the point of impersonation&lt;/li&gt;&lt;/ul&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/199106851038957806-3796489791387277455?l=mscrmuk.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://mscrmuk.blogspot.com/feeds/3796489791387277455/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=199106851038957806&amp;postID=3796489791387277455' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/199106851038957806/posts/default/3796489791387277455'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/199106851038957806/posts/default/3796489791387277455'/><link rel='alternate' type='text/html' href='http://mscrmuk.blogspot.com/2010/11/how-to-use-impersonation-in-asp-net.html' title='How to use impersonation in an ASP .Net page using IFD in CRM 4.0'/><author><name>David Jennaway</name><uri>http://www.blogger.com/profile/09695858105618938443</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-199106851038957806.post-5786036079799699575</id><published>2010-11-11T17:19:00.003Z</published><updated>2010-11-11T18:01:38.054Z</updated><category scheme='http://www.blogger.com/atom/ns#' term='How it Works'/><category scheme='http://www.blogger.com/atom/ns#' term='Troubleshooting'/><category scheme='http://www.blogger.com/atom/ns#' term='CRM 4.0'/><title type='text'>When is the Default Organisation not the Default Organisation</title><content type='html'>&lt;div align="left"&gt;In CRM 4.0, an organisation can be designated as the Default Organisation in the Deployment Manager tool:&lt;br /&gt;&lt;br /&gt;&lt;/div&gt;&lt;p&gt;&lt;a href="http://1.bp.blogspot.com/_q3OlQztdu1Y/TNwies74nPI/AAAAAAAAACY/q_HAwxLdt-8/s1600/DM_DefaultOrg.jpg"&gt;&lt;img style="TEXT-ALIGN: center; MARGIN: 0px auto 10px; WIDTH: 320px; DISPLAY: block; HEIGHT: 106px; CURSOR: hand" id="BLOGGER_PHOTO_ID_5538339552612621554" border="0" alt="" src="http://1.bp.blogspot.com/_q3OlQztdu1Y/TNwies74nPI/AAAAAAAAACY/q_HAwxLdt-8/s320/DM_DefaultOrg.jpg" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;However, this does not always do what some people expect. CRM has 2 distinct concepts of a 'Default Organisation', and only one of them can be set using Deployment Manager. The 'Default Organisation' that you set in Deployment is a system-wide setting whose primary use is to define which organisation database is used by code that accesses CRM 4.0 through the CRM 3.0 web services (CRM 3.0 did not support multiple organisations, so the web services had no way to specify the organisation to connect to).&lt;br /&gt;&lt;br /&gt;The other type of 'Default Organisation' applies to users. Each user has a Default Organisation, which is the organisation that they are connected to if browsing to a Url that does not contain the organisation name. For example, if a user browses to http://crm/Excitation/loader.aspx, then the user will necessarily be taken to the Excitation organisation, but if they browse to http://crm/loader.aspx, they will be taken to their default organisation, which has no relationship to the 'Default Organisation' that is set in Deployment Manager. Each user's default organisation will be the first organisation in which their CRM user record was created. &lt;/p&gt;&lt;p&gt;One issue that can arise is if a user connects using a Url that does not contain the organisation name, and either their default organisation has been disabled, or their user account in their default organisation has been disabled. In this scenario, the user would receive either the error 'The specified organization is disabled' or 'The specified user is either disabled or is not a member of any business unit'. The simplest solution would be to specify an appropriate organisation name in the Url; however if this is not possible, the rest of this post describes an unsupported alternative.&lt;br /&gt;&lt;br /&gt;Unfortunately, none of the MSCRM tools will display a user's default organisation, nor is there a supported way to change this (though there is an unsupported way - see below). All the information is stored in the MSCRM_Config database, in the SystemUser, Organization and SystemUserOrganizations tables. The following output shows some of the relevant data from these tables:&lt;br /&gt;&lt;br /&gt;&lt;a href="http://2.bp.blogspot.com/_q3OlQztdu1Y/TNwifJbPu1I/AAAAAAAAACg/fLeIdutVg_E/s1600/SQLData_SystemUser.jpg"&gt;&lt;img style="TEXT-ALIGN: center; MARGIN: 0px auto 10px; WIDTH: 320px; DISPLAY: block; HEIGHT: 37px; CURSOR: hand" id="BLOGGER_PHOTO_ID_5538339560260352850" border="0" alt="" src="http://2.bp.blogspot.com/_q3OlQztdu1Y/TNwifJbPu1I/AAAAAAAAACg/fLeIdutVg_E/s320/SQLData_SystemUser.jpg" /&gt;&lt;/p&gt;&lt;p align="center"&gt;&lt;/a&gt;&lt;br /&gt;SystemUser table&lt;br /&gt;&lt;br /&gt;&lt;/p&gt;&lt;a href="http://4.bp.blogspot.com/_q3OlQztdu1Y/TNwifeSsIpI/AAAAAAAAACo/aClWIHjfIIU/s1600/SQLData_Organization.jpg"&gt;&lt;img style="TEXT-ALIGN: center; MARGIN: 0px auto 10px; WIDTH: 320px; DISPLAY: block; HEIGHT: 85px; CURSOR: hand" id="BLOGGER_PHOTO_ID_5538339565861610130" border="0" alt="" src="http://4.bp.blogspot.com/_q3OlQztdu1Y/TNwifeSsIpI/AAAAAAAAACo/aClWIHjfIIU/s320/SQLData_Organization.jpg" /&gt;&lt;/a&gt; &lt;p align="center"&gt;&lt;br /&gt;Organization table&lt;br /&gt;&lt;br /&gt;&lt;/p&gt;&lt;img style="TEXT-ALIGN: center; MARGIN: 0px auto 10px; WIDTH: 320px; DISPLAY: block; HEIGHT: 39px; CURSOR: hand" id="BLOGGER_PHOTO_ID_5538339574581885314" border="0" alt="" src="http://2.bp.blogspot.com/_q3OlQztdu1Y/TNwif-xw-YI/AAAAAAAAACw/1vQshUAMROA/s320/SQLData_SystemUserOrgs.jpg" /&gt; &lt;p align="center"&gt;&lt;br /&gt;SystemUserOrganizations table &lt;/p&gt;&lt;p align="left"&gt;The DefaultOrganizationId field in SystemUser defines each user's default organisation, and this can be joined to the Id field in the Organization table.&lt;br /&gt;&lt;br /&gt;The fields that define the user are a little more complex: The Id field in SystemUser is unique to each CRM user. You can join the SystemUser table to the SystemUserOrganizations table using the SystemUser.Id and the SystemUserOrganizations.UserId fields. The CrmUserId field in SystemUserOrganizations can be joined to the systemuserid field in the systemuserbase table in each CRM organisation database. Note that the same user will have a different systemuserid in each organisation database. The following query illustrates these joins, taking the user's name from one of the organisation databases (it's not stored in MSCRM_Config):&lt;br /&gt;&lt;br /&gt;&lt;span style="font-size:85%;"&gt;&lt;span style="font-family:courier new;"&gt;select o.UniqueName, u.FullName&lt;br /&gt;from Organization o&lt;br /&gt;join SystemUser su on o.Id = su.DefaultOrganizationId&lt;br /&gt;join SystemUserOrganizations suo on su.Id = suo.UserId&lt;br /&gt;join Excitation_MSCRM..systemuser u on suo.CrmUserId = u.systemuserid&lt;/span&gt;&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;So, that's how it fits together. As this is all SQL data, it is not difficult to modify this, but be aware that to do so is completely unsupported, and could break your CRM implementation. If you were to make any changes, make sure you backup the relevant databases (especially MSCRM_Config) before you do so.&lt;br /&gt;&lt;br /&gt;If you did want to change a user's default organisation, please heed the warning in the preceding paragraph and backup the MSCRM_Config database. The following SQL update statement will change the default organisation of a given user, based on their systemuserid in one organisation database. The reason for writing the query this way is to ensure that a user's default organisation can only be set to an organisation that they exist in, and this query should only ever modify one record. If it modifies 0 records, then check the @systemuserid value, and if it modifies more than one record then your MSCRM_Config database is probably corrupt, and you should reinstall CRM and reimport your organisation databases (I was serious about my warnings).&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family:courier new;font-size:85%;"&gt;declare @systemuserid uniqueidentifier&lt;br /&gt;set @systemuserid = '25E1DC1D-BEC2-449B-AAD8-4A6309122AE1' -- replace this&lt;br /&gt;update SystemUser&lt;br /&gt;set DefaultOrganizationId = suo.OrganizationId&lt;br /&gt;from SystemUserOrganizations suo&lt;br /&gt;where suo.UserId = SystemUser.Id&lt;br /&gt;and suo.CrmUserId = @systemuserid&lt;/span&gt; &lt;/p&gt;&lt;p align="left"&gt;One final point; CRM caches some of the data in MSCRM_Config, so you'd need to recycle the CRM application pool to sure any changes have taken effect. &lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/199106851038957806-5786036079799699575?l=mscrmuk.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://mscrmuk.blogspot.com/feeds/5786036079799699575/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=199106851038957806&amp;postID=5786036079799699575' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/199106851038957806/posts/default/5786036079799699575'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/199106851038957806/posts/default/5786036079799699575'/><link rel='alternate' type='text/html' href='http://mscrmuk.blogspot.com/2010/11/when-is-default-organisation-not.html' title='When is the Default Organisation not the Default Organisation'/><author><name>David Jennaway</name><uri>http://www.blogger.com/profile/09695858105618938443</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://1.bp.blogspot.com/_q3OlQztdu1Y/TNwies74nPI/AAAAAAAAACY/q_HAwxLdt-8/s72-c/DM_DefaultOrg.jpg' height='72' width='72'/><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-199106851038957806.post-4995462222007875899</id><published>2010-11-09T16:27:00.001Z</published><updated>2010-11-11T17:18:07.668Z</updated><category scheme='http://www.blogger.com/atom/ns#' term='How it Works'/><category scheme='http://www.blogger.com/atom/ns#' term='Reports'/><category scheme='http://www.blogger.com/atom/ns#' term='SQL Server'/><category scheme='http://www.blogger.com/atom/ns#' term='CRM 4.0'/><title type='text'>The CRM 4.0 Reporting Services Connector - how it works</title><content type='html'>The Dynamic CRM Connector for Reporting Services is a very useful component that avoids the need to configure Active Directory delegation (&lt;a href="http://blogs.technet.com/b/askds/archive/2008/06/13/understanding-kerberos-double-hop.aspx"&gt;aka double-hop authentication&lt;/a&gt;) when multiple servers are used for the CRM, Reporting Services and SQL Server roles in a CRM implementation. In general, it is easy to install and use, but I'm always interested in how these things work.&lt;br /&gt;&lt;br /&gt;&lt;strong&gt;How the Connector is installed and invoked&lt;/strong&gt;&lt;br /&gt;The connector is installed as a &lt;a href="http://msdn.microsoft.com/en-us/library/ms154655.aspx"&gt;Data Processing Extension&lt;/a&gt; with SSRS. These extensions are registered within the rsreportserver.config file on the Reporting Server, as per the following snippet:&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family:courier new;font-size:85%;"&gt;&amp;lt;Data&amp;gt;&lt;br /&gt;&amp;lt;Extension Name="SQL" Type="Microsoft.ReportingServices.DataExtensions.SqlConnectionWrapper,Microsoft.ReportingServices.DataExtensions" /&amp;gt; &amp;lt;Extension Name="OLEDB" Type="Microsoft.ReportingServices.DataExtensions.OleDbConnectionWrapper,Microsoft.ReportingServices.DataExtensions" /&amp;gt;&lt;br /&gt;&lt;strong&gt;&amp;lt;Extension Name="MSCRM" Type="Microsoft.Crm.Reporting.DataConnector.SrsExtConnection,Microsoft.Crm.Reporting.DataConnector" /&amp;gt; &amp;lt;/Data&amp;gt;&lt;/strong&gt;&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;All CRM reports with SSRS are configured to use a specific SSRS Data Source. When the Connector is installed, the Data Source is changed to use the MSCRM Data Processing Extension, instead of the default SQL Server extension. See images below:&lt;br /&gt;&lt;br /&gt;&lt;p&gt;&lt;a href="http://4.bp.blogspot.com/_q3OlQztdu1Y/TMq672lMV8I/AAAAAAAAABw/CVoUSd0V5Cw/s1600/MSCRM_Report_DataSource.jpg"&gt;&lt;img style="TEXT-ALIGN: center; MARGIN: 0px auto 10px; WIDTH: 320px; DISPLAY: block; HEIGHT: 138px; CURSOR: hand" id="BLOGGER_PHOTO_ID_5533440629604636610" border="0" alt="" src="http://4.bp.blogspot.com/_q3OlQztdu1Y/TMq672lMV8I/AAAAAAAAABw/CVoUSd0V5Cw/s320/MSCRM_Report_DataSource.jpg" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;span style="font-size:85%;"&gt;Report properties showing the MSCRM Data Source&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;&lt;a href="http://3.bp.blogspot.com/_q3OlQztdu1Y/TMq68DLyvKI/AAAAAAAAAB4/kWAsVes3K5s/s1600/MSCRM_DataSource_SQLServer.jpg"&gt;&lt;img style="TEXT-ALIGN: center; MARGIN: 0px auto 10px; WIDTH: 320px; DISPLAY: block; HEIGHT: 274px; CURSOR: hand" id="BLOGGER_PHOTO_ID_5533440632987761826" border="0" alt="" src="http://3.bp.blogspot.com/_q3OlQztdu1Y/TMq68DLyvKI/AAAAAAAAAB4/kWAsVes3K5s/s320/MSCRM_DataSource_SQLServer.jpg" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;span style="font-size:85%;"&gt;MSCRM Data Source using the SQL Server extension before the connector is installed&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;a href="http://4.bp.blogspot.com/_q3OlQztdu1Y/TMq68D3bDtI/AAAAAAAAACA/8I3asBQSd8w/s1600/MSCRM_DataSource_CRM.jpg"&gt;&lt;img style="TEXT-ALIGN: center; MARGIN: 0px auto 10px; WIDTH: 320px; DISPLAY: block; HEIGHT: 277px; CURSOR: hand" id="BLOGGER_PHOTO_ID_5533440633170759378" border="0" alt="" src="http://4.bp.blogspot.com/_q3OlQztdu1Y/TMq68D3bDtI/AAAAAAAAACA/8I3asBQSd8w/s320/MSCRM_DataSource_CRM.jpg" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;span style="font-size:85%;"&gt;MSCRM Data Source using the CRM extension after the connector is installed.&lt;/span&gt;&lt;/p&gt;&lt;p&gt;There are 3 differences between these configurations: &lt;/p&gt;&lt;ol&gt;&lt;li&gt;The Connection Type, which specifies the extension&lt;/li&gt;&lt;li&gt;The Connection String is absent with the CRM connector. This is because the connector reads some of the database information from registry values that were created during its installation, and some from data passed to it when the report is run (see below)&lt;/li&gt;&lt;li&gt;The Credentials. With the SQL Server connector, standard Windows Integrated security is used - i.e. the user's AD credentials are used to connect to SQL Server. With the CRM connector, separate 'credentials' are passed to SSRS (again, see below)&lt;/li&gt;&lt;/ol&gt;&lt;p&gt;&lt;strong&gt;What happens when a report is run&lt;/strong&gt;&lt;br /&gt;If you try to run a CRM report with the CRM connector installed, the connector will require some 'credentials', as per point no.3 above. This image shows what happens if you try to run a report from Report Manager:&lt;br /&gt;&lt;br /&gt;&lt;a href="http://4.bp.blogspot.com/_q3OlQztdu1Y/TMq_YL43kPI/AAAAAAAAACQ/6q9NfsL86Og/s1600/MSCRM_Report_Credentials.jpg"&gt;&lt;img style="TEXT-ALIGN: center; MARGIN: 0px auto 10px; WIDTH: 320px; DISPLAY: block; HEIGHT: 101px; CURSOR: hand" id="BLOGGER_PHOTO_ID_5533445514407153906" border="0" alt="" src="http://4.bp.blogspot.com/_q3OlQztdu1Y/TMq_YL43kPI/AAAAAAAAACQ/6q9NfsL86Og/s320/MSCRM_Report_Credentials.jpg" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;span style="font-size:85%;"&gt;Running a CRM report from Report Manager when the CRM connector is installed&lt;/span&gt;&lt;/p&gt;These 'credentials' are not what they seem; rather they are a cunning way for the CRM platform to pass information about the current user to the CRM connector. The CRM connector expects the current user's systemuserid (a Guid) to be passed into the Log In Name box, and the organizationid (another Guid) to be passed into the Password box. These are not your login name and password.&lt;br /&gt;&lt;br /&gt;As the report uses a data source that uses the CRM connector, the RS Report Server code calls the CRM connector code (the SrsExtConnection class in the Microsoft.Crm.Reporting.DataConnector assembly, as per the rsreportserver.config data above). The code will then:&lt;br /&gt;&lt;ol&gt;&lt;li&gt;Check that it is permitted to impersonate a CRM user. This checks that the identity the code is running under (which the identity of the ReportServer application pool, or the Reporing Services service, depending on the version of Reporting Services) belongs to the AD group PrivReportingGroup&lt;/li&gt;&lt;li&gt;Connect to the MSCRM_Config database to determine the correct MSCRM organization database, based on the organizationid that was passed in the 'credentials'&lt;/li&gt;&lt;li&gt;Connect to the relevant MSCRM organization database. Note that this is done (as was the previous step) using integrated security under the AD identity as per step 1 above&lt;/li&gt;&lt;li&gt;Use the SQL statement SET Context_Info to pass the calling CRM user's systemuserid into the Context_Info&lt;/li&gt;&lt;li&gt;Execute the SQL statement(s) within the report definition. The definition of all filtered views use the fn_FindUserGuid function to read the systemuserid from the Context_Info &lt;/li&gt;&lt;/ol&gt;&lt;p&gt;&lt;strong&gt;What can you do with this information&lt;/strong&gt;&lt;br /&gt;One use is for troubleshooting. Checking the rsreportserver.config is a quick way to see if the connector is installed, and checking the configuration of the MSCRM Data Source will tell you if the connector is in use. Changing the MSCRM Data Source is a quick way to turn the connector on or off for test purposes.&lt;/p&gt;&lt;p&gt;You can also run the reports directly, rather than from CRM. Again, when troubleshooting I find it useful to run a report directly from Report Manager web interface. To do this with the connector, you need to enter the systemuserid and organizationid when prompted (see image above). These values can be read from the filteredsystemuser and filterorganization views respectively in the MSCRM database.&lt;/p&gt;&lt;p&gt;A further option is to run the reports via other means, such as Url Access, as described &lt;a href="http://blogs.msdn.com/b/crm/archive/2007/10/04/writing-reports-to-display-in-iframes-and-from-isv-config.aspx"&gt;here&lt;/a&gt; (that article was written for CRM 3, see &lt;a href="http://mscrmuk.blogspot.com/2008/06/reports-in-iframes-updated-for-crm-40.html"&gt;here&lt;/a&gt; for an update for CRM 4). To do this with the connector installed, you will also have to pass the systemuserid and organizationid on the query string. This is done using the following syntax:&lt;/p&gt;&lt;p&gt;&amp;amp;dsu:CRM=&amp;lt;systemuserid&amp;gt;&amp;amp;dsp:CRM=&amp;lt;organizationid&amp;gt;&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/199106851038957806-4995462222007875899?l=mscrmuk.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://mscrmuk.blogspot.com/feeds/4995462222007875899/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=199106851038957806&amp;postID=4995462222007875899' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/199106851038957806/posts/default/4995462222007875899'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/199106851038957806/posts/default/4995462222007875899'/><link rel='alternate' type='text/html' href='http://mscrmuk.blogspot.com/2010/08/crm-40-reporting-services-connector-how.html' title='The CRM 4.0 Reporting Services Connector - how it works'/><author><name>David Jennaway</name><uri>http://www.blogger.com/profile/09695858105618938443</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://4.bp.blogspot.com/_q3OlQztdu1Y/TMq672lMV8I/AAAAAAAAABw/CVoUSd0V5Cw/s72-c/MSCRM_Report_DataSource.jpg' height='72' width='72'/><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-199106851038957806.post-6340442621807915564</id><published>2010-10-29T09:55:00.000+01:00</published><updated>2010-10-29T09:55:00.125+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Server code'/><category scheme='http://www.blogger.com/atom/ns#' term='Configuration'/><title type='text'>Web.config settings - e.g. ViewState, Session</title><content type='html'>A common issue raised in the &lt;a href="http://social.microsoft.com/Forums/en-US/crmdevelopment/threads"&gt;CRM Development forum&lt;/a&gt; is of custom web pages that work correctly in a development environment, but then fail to work when deployed into the CRM web site. The most common reason for this is that the CRM web.config overrides some of the default ASP.Net configuration settings.&lt;br /&gt;&lt;br /&gt;The relevant entries in the CRM web.config (in the root of the CRM web site) are:&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family:courier new;font-size:85%;"&gt;&amp;lt;pages buffer="true" enableSessionState="false" enableViewState="false" validateRequest="false/"&amp;gt;&lt;br /&gt;&amp;lt;sessionState mode="Off"/&amp;gt;&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;These have 2 main consequences:&lt;br /&gt;&lt;ol&gt;&lt;li&gt;Session State is disabled. This issue is relatively easy to diagnose, as you tend to get a clear error message if trying to use session state when it is disabled&lt;/li&gt;&lt;li&gt;ViewState is disabled. This can be a more subtle effect, as developers often rely on viewState without necessarily being aware of it. ViewState is what allows ASP.Net web controls to maintain property values across web requests; if it is disabled then it leads to symptoms such as values not being retained, or list boxes losing their contents&lt;/li&gt;&lt;/ol&gt;&lt;p&gt;The solution for viewState is straightforward. You can reenable viewState for you application either in the web.config in your application directory, or at the page level within the &lt;@Page&gt; directive. These looks like the following:&lt;/p&gt;&lt;p&gt;web.config:&lt;br /&gt;&lt;span style="font-family:courier new;font-size:85%;"&gt;&amp;lt;pages enableViewState="true" /&amp;gt;&lt;/span&gt; &lt;/p&gt;&lt;p&gt;Page directive:&lt;br /&gt;&lt;span style="font-family:courier new;font-size:85%;"&gt;&amp;lt;@Page EnableViewState="true"  /&amp;gt;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;Session state is a bit more complex, as this is configured at the web application level. Personally, I've never seen any reason to use session state within custom code in the CRM web site; CRM doesn't use this, and I find it best to mimic CRM behaviour wherever possible.&lt;/p&gt;&lt;p&gt;And one final point about best practise; as this post demonstrates, it is best not to rely on the default ASP .Net configuration settings, rather I find it best to always explicitly enable or disable settings in the local web.config&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/199106851038957806-6340442621807915564?l=mscrmuk.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://mscrmuk.blogspot.com/feeds/6340442621807915564/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=199106851038957806&amp;postID=6340442621807915564' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/199106851038957806/posts/default/6340442621807915564'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/199106851038957806/posts/default/6340442621807915564'/><link rel='alternate' type='text/html' href='http://mscrmuk.blogspot.com/2010/10/webconfig-settings-eg-viewstate-session.html' title='Web.config settings - e.g. ViewState, Session'/><author><name>David Jennaway</name><uri>http://www.blogger.com/profile/09695858105618938443</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-199106851038957806.post-2117629811369939070</id><published>2010-10-28T12:45:00.000+01:00</published><updated>2010-10-28T12:45:00.411+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Server code'/><category scheme='http://www.blogger.com/atom/ns#' term='Deployment'/><title type='text'>SDK assemblies: Versions and Processor Architecture</title><content type='html'>The &lt;a href="http://www.microsoft.com/downloads/details.aspx?FamilyID=82e632a7-faf9-41e0-8ec1-a2662aae9dfb&amp;amp;displaylang=en"&gt;download&lt;/a&gt; of the Dynamics CRM &lt;a href="http://msdn.microsoft.com/en-us/library/bb928212.aspx"&gt;SDK&lt;/a&gt; includes the sdk assemblies (microsoft.crm.sdk.dll, microsoft.crm.sdktypeproxy.dll etc). There are 4 sets of these assemblies, one in the bin directory, another in bin\64bit, and two more in the respective online subdirectories.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;Given the directory naming, I'd always assumed that the assemblies in the bin directory were built for 32bit (x86) systems only, and those in bin\64bit were build for 64bit systems. I found this a little annoying, as I generally prefer to build assemblies as MSIL (AnyCPU) to avoid the need for different 32 and 64 bit deployment packages.&lt;br /&gt;&lt;br /&gt;However, it turns out that the assemblies in the bin\64bit directory are actually built as MSIL (AnyCPU), rather than specifically as 64 bit assemblies (apparently this was an earlier deployment mix-up which it's now too late to correct). This gives me what I want, so I now always use the assemblies that, bizarrely, come in the bin\64bit directory of the SDK.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/199106851038957806-2117629811369939070?l=mscrmuk.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://mscrmuk.blogspot.com/feeds/2117629811369939070/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=199106851038957806&amp;postID=2117629811369939070' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/199106851038957806/posts/default/2117629811369939070'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/199106851038957806/posts/default/2117629811369939070'/><link rel='alternate' type='text/html' href='http://mscrmuk.blogspot.com/2010/10/sdk-assemblies-versions-and-processor.html' title='SDK assemblies: Versions and Processor Architecture'/><author><name>David Jennaway</name><uri>http://www.blogger.com/profile/09695858105618938443</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-199106851038957806.post-5680335887565925798</id><published>2010-08-26T23:27:00.000+01:00</published><updated>2010-08-26T23:27:00.588+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Troubleshooting'/><category scheme='http://www.blogger.com/atom/ns#' term='SQL Server'/><title type='text'>What takes up most space in an MSCRM database</title><content type='html'>A frequent question is 'What is taking up most space in my MSCRM database'. My first step is to check which tables take up most space, for which I use the SQL script at the end of this post. The most common large tables, and reasons for them are:&lt;br /&gt;&lt;br /&gt;1. AsyncOperationBase: This stores all asynchronous operations, and can get very large if completed ones aren't cleared out. You have to explicitly set the registry values AsyncRemoveCompletedWorkflows and AsyncRemoveCompletedJobs. These 2 values are covered in separate KB articles (http://support.microsoft.com/kb/968755 and http://support.microsoft.com/kb/957871). To clear existing records, use the SQL script in http://support.microsoft.com/kb/968520/&lt;br /&gt;2. ActivityMimeAttachment: This stores email attachments&lt;br /&gt;3. AnnotationBase: This stores other files (those associated with Notes)&lt;br /&gt;4. ActivityPointerBase and/or ActivityPartyBase; These store activities and the associated parties respectively. Although individual record sizes aren't typically large, these tables typically have the largest number of records&lt;br /&gt;&lt;br /&gt;For no.s 2 to 4 I've not given a way of clearing out space, as this would involve deletion of business data.&lt;br /&gt;&lt;br /&gt;&lt;strong&gt;SQL Script&lt;/strong&gt;&lt;br /&gt;I normally use the following SQL Script to find what objects take up most space in a SQL database. It doesn't take account all possible storage in all SQL databases, but works fine for an MSCRM database&lt;br /&gt;&lt;br /&gt;select OBJECT_NAME(object_id), SUM(reserved_page_count) / 128 as ReservedMB,  sum(used_page_count) / 128 as UsedMB, MAX(row_count)&lt;br /&gt;from sys.dm_db_partition_stats&lt;br /&gt;group by object_id&lt;br /&gt;order by SUM(reserved_page_count) desc&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/199106851038957806-5680335887565925798?l=mscrmuk.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://mscrmuk.blogspot.com/feeds/5680335887565925798/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=199106851038957806&amp;postID=5680335887565925798' title='3 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/199106851038957806/posts/default/5680335887565925798'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/199106851038957806/posts/default/5680335887565925798'/><link rel='alternate' type='text/html' href='http://mscrmuk.blogspot.com/2010/08/what-takes-up-most-space-in-mscrm.html' title='What takes up most space in an MSCRM database'/><author><name>David Jennaway</name><uri>http://www.blogger.com/profile/09695858105618938443</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>3</thr:total></entry><entry><id>tag:blogger.com,1999:blog-199106851038957806.post-3526073393685973404</id><published>2010-08-06T07:27:00.003+01:00</published><updated>2010-08-26T16:31:04.056+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Customisation'/><category scheme='http://www.blogger.com/atom/ns#' term='Quick Tips'/><category scheme='http://www.blogger.com/atom/ns#' term='Advanced Find'/><title type='text'>A view of records owned by the user's business unit</title><content type='html'>Bubbling something up from an answer I gave on the &lt;a href="http://social.microsoft.com/Forums/en-US/category/dynamics"&gt;Dynamics CRM forums&lt;/a&gt;. Although it may not seem obvious within Advanced Find, it is possible to create a view that displays records owned by a user's business unit.&lt;br /&gt;&lt;br /&gt;The following gives the contacts owned by the current user's BU - strictly it's composed as 'contacts owned by a business unit that contains the current user'&lt;br /&gt;&lt;br /&gt;Contacts&lt;br /&gt;Owning Business Unit&lt;br /&gt;Users (Business Unit)&lt;br /&gt;User Equals Current User&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/199106851038957806-3526073393685973404?l=mscrmuk.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://mscrmuk.blogspot.com/feeds/3526073393685973404/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=199106851038957806&amp;postID=3526073393685973404' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/199106851038957806/posts/default/3526073393685973404'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/199106851038957806/posts/default/3526073393685973404'/><link rel='alternate' type='text/html' href='http://mscrmuk.blogspot.com/2010/08/view-of-records-owned-by-users-business.html' title='A view of records owned by the user&apos;s business unit'/><author><name>David Jennaway</name><uri>http://www.blogger.com/profile/09695858105618938443</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-199106851038957806.post-2379805644405172358</id><published>2010-05-12T12:12:00.003+01:00</published><updated>2010-05-12T12:18:51.577+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Server code'/><category scheme='http://www.blogger.com/atom/ns#' term='Announcement'/><title type='text'>Advanced Developer Extensions - an update</title><content type='html'>Just a quick note to say that I've updated my post on the &lt;a href="http://mscrmuk.blogspot.com/2010/05/crm-sdk-4012-and-advanced-developer.html"&gt;Advanced Developer Extensions&lt;/a&gt;. &lt;a href="http://www.shanmcarthur.net/"&gt;Shan McArthur&lt;/a&gt; of &lt;a href="http://www.adxstudio.com/"&gt;AdxStudio&lt;/a&gt; (who developed these extensions) was kind enough to provide extra information about these extensions, which I've now incorporated into the original post&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/199106851038957806-2379805644405172358?l=mscrmuk.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://mscrmuk.blogspot.com/feeds/2379805644405172358/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=199106851038957806&amp;postID=2379805644405172358' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/199106851038957806/posts/default/2379805644405172358'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/199106851038957806/posts/default/2379805644405172358'/><link rel='alternate' type='text/html' href='http://mscrmuk.blogspot.com/2010/05/advanced-developer-extensions-update.html' title='Advanced Developer Extensions - an update'/><author><name>David Jennaway</name><uri>http://www.blogger.com/profile/09695858105618938443</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-199106851038957806.post-8456104947929322353</id><published>2010-05-11T11:23:00.006+01:00</published><updated>2010-05-12T12:12:43.056+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Server code'/><category scheme='http://www.blogger.com/atom/ns#' term='Announcement'/><title type='text'>CRM SDK 4.0.12 and the Advanced Developer Extensions</title><content type='html'>The &lt;a href="http://blogs.msdn.com/crm/archive/2010/05/06/microsoft-dynamics-crm-sdk-4-0-12-available.aspx"&gt;CRM 4.0.12 SDK&lt;/a&gt; has recently been released. Normally an SDK update is not particularly significant, but in this case it includes some major enhancements, which come under the banner of 'Advanced Developer Extensions'. David Yack has already posted a quick how-to on the &lt;a href="http://blogs.msdn.com/crm/archive/2010/05/07/new-crm-sdk-new-developer-experience.aspx"&gt;CRM Team Blog&lt;/a&gt;; rather than duplicate that, this post is intended to cover the scope and limitations of the new extensions as I see them, and how they differ from the original CRM programming model.&lt;br /&gt;&lt;br /&gt;&lt;strong&gt;What are the new extensions ?&lt;/strong&gt;&lt;br /&gt;It seems to make sense to split the new features into 2; the 'Advanced Developer Extensions' (whcih has been helpfully shortened to Microsoft xRM), and the Portal Accelerator (aka Portal Developer). The Portal accelerator uses Microsoft xRM, but I think it is otherwise best treated separately. So, for this post I'll concentrate on Microsoft xRM.&lt;br /&gt;&lt;br /&gt;&lt;strong&gt;Architecture of Microsoft xRM&lt;/strong&gt;&lt;br /&gt;Although Microsoft xRM appears to provide a whole new programming model, it can be considered as essentially a (rather big) wrapper around the existing SDK assemblies (microsoft.crm.sdk and microsoft.crm.sdktypeproxy). So, although your code would not directly use the classes in the SDK assemblies, the communication with CRM is still ultimately done via the CRM web services, and is subject to the same limitations (e.g. limitations of the FetchXml query syntax). Another consequence of this is that you do not need to change any of your network configuration to use these extensions.&lt;br /&gt;&lt;br /&gt;&lt;strong&gt;Changes to the Programming Model&lt;/strong&gt;&lt;br /&gt;This is where it gets interesting; the new extensions provide a whole new programming model, which can affect pretty well all of the code you use to communicate with CRM. The major changes as I see it are:&lt;br /&gt;&lt;br /&gt;&lt;ol&gt;&lt;li&gt;You can use strongly-typed classes for the CRM entities. Although you can do this with the existing SOAP CRM web services, up till now you needed to use the DynamicEntity class with the SDK assemblies&lt;/li&gt;&lt;li&gt;Native .Net types are used for attributes - e.g. int? rather than CrmNumber. Note that nullable types (e.g. int?, rather than int) as used&lt;/li&gt;&lt;li&gt;The connection information is covered within a DataContext class, which effectively replaces the use of the CrmService instance&lt;/li&gt;&lt;li&gt;Data modifications can be cached locally, then submitted as a batch, using the DataContext.SaveChanges method&lt;/li&gt;&lt;li&gt;The extensions provide additional methods to update lookup values. These can work off either the lookup attribute name (e.g. customerid) or the relationship name (e.g. contact_customer_accounts). The extensions also provide methods to retrieve related records, which avoids the need to use QueryExpression or QueryByAttribute&lt;/li&gt;&lt;li&gt;You can use LINQ queries to retrieve data from CRM, rather than building QueryExpression instances&lt;/li&gt;&lt;li&gt;The DataContext and LINQ technologies allow direct data-binding with .Net user interface controls&lt;/li&gt;&lt;/ol&gt;&lt;p&gt;&lt;strong&gt;Use of Strongly-Typed classes&lt;/strong&gt;&lt;br /&gt;As with the SOAP web services, you can use strongly-types classes for system and custom entities. Superficially the process for setting this up differs from the SOAP web services, although the underlying idea is pretty similar. With these extensions, you use a supplied tool (CrmSvcUtil.exe) to connect to a CRM server. This tool will generate the class definitions for all CRM entities into one output code file which you'll add into your .Net project. Ultimately, this process is very similar to what happens behind the scenes when you create a Web Reference to the SOAP web services. The main internal difference is that the generated classes with these extensions maps down to the DynamicEntity class, but this is hidden from you.&lt;/p&gt;&lt;p&gt;You can still use a generic class with these extensions rather than strongly-typed classes. With the extensions it is ICrmEntity, rather than DynamicEntity. &lt;/p&gt;&lt;p&gt;&lt;strong&gt;Native .Net Types&lt;/strong&gt;&lt;br /&gt;Native .Net Types are used instead of Crm-specific types. The extensions use the nullable versions of the types (e.g. int?, rather than int) so that you can still identify null values (which was one of the main original reasons for the Crm-specific types). For picklist and status attributes the extensions provide an additional Label attribute (e.g. customertypecodeLabel) with the appropriate text, whereas for lookup attributes you can get the related entity via a property that has the relationship name (e.g. price_level_accounts).&lt;/p&gt;&lt;p&gt;&lt;strong&gt;DataContext class&lt;/strong&gt;&lt;br /&gt;This replaces the need for the CrmService instance, and handles the selection of authentication type, passing credentials and management of the CrmAuthentication token. All connection-related information (server URL and port, organisation name, authentication type and credentials) can be specified in one connection string. The extension code includes logic to read connection string information from the application config file. Overall, this should greatly simplify deployment across different environments and authentication types.&lt;/p&gt;&lt;p&gt;The DataContext exposes an IOrganizationService instance, which looks to combine the underlying ICrmService and IMetadataService instances. This allows use of any of the more specific CrmService messages (e.g. InstantiateTemplate), or MetadataService messages.&lt;/p&gt;&lt;p&gt;Interestingly the constructor for the DataContext can take an IContextService or IWorkflowContext instance, but not an IPluginExecutionContext instance. This implies that the extensions can work within a custom workflow activity, but are of limited use within plugins. See below for more on this.&lt;/p&gt;&lt;p&gt;&lt;strong&gt;Batch Updates&lt;/strong&gt;&lt;br /&gt;It looks to me as though any changes submitted via the DataContext will be submitted as a batch via the SaveChanges method. This won't provide any transactional support, as this is not possible within the Crm Web Services. Overall, I think this approach is due to the design patterns used in the Microsoft data-related classes, and I'm pretty neutral as to whether this offers more benefits or drawbacks. If you do develop with these extensions, I'd bear the following in mind: &lt;/p&gt;&lt;ul&gt;&lt;li&gt;I could imagine developers forgetting to include the SaveChanges method, and I can't see (though I've not tested this) a way that the extension code would throw an error is pending changes were discarded&lt;/li&gt;&lt;li&gt;There seems to be no means to control the behaviour if an individual data operation fails, and the documentation doesn't currently describe the default behaviour here. To get such control you need to call SaveChanges for each individual data modification&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;&lt;strong&gt;Handling lookups and relationships&lt;/strong&gt;&lt;br /&gt;I've not looked at this in great detail, but I see the greatest benefit is the simplicity of retrieving related records with methods such as GetRelatedEntities to get child and many-many entities, and GetRelatedEntity to get a parent entity.&lt;/p&gt;&lt;p&gt;&lt;strong&gt;Use of LINQ queries&lt;/strong&gt;&lt;br /&gt;Again, not an area I've spent much time with. In the first instance I see this as most useful for developers that are already familiar with the LINQ query syntax, but I generally encourage the use of standard technologies (such as LINQ) in preference to application-specific technologies (such as QueryExpression). My expectation is that you should expect developer productivity gains with use of LINQ instead of QueryExpression, but I've not spent enough time on this to get good metrics. It should be emphasised that the LINQ query ultimately maps down to a QueryExpression, and hence you are as limited in the scope of queries as you currently are.&lt;/p&gt;&lt;p&gt;&lt;strong&gt;Data Binding&lt;br /&gt;&lt;/strong&gt;This really comes as a direct benefit of the use of standard .Net data classes, and LINQ. You can directly bind UI components like the ASP.Net GridView control to the results of a LINQ query. Oddly, there doesn't seem to be an example of this in the main crmsdk4.chm help file, but the following code extract from the 'advanced_developer_extensions_-_walkthrough_webapp.docx' document in the SDK shows how easy and powerful this can be:&lt;/p&gt;&lt;p&gt;&lt;span style="font-family:courier new;font-size:85%;"&gt;var crm = new XrmDataContext("Crm");&lt;br /&gt;ContactsGrid.DataSource = crm.contacts.Where&lt;br /&gt; (c =&gt; c.emailaddress1.EndsWith("@example.com"));&lt;br /&gt;ContactsGrid.DataBind();&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;strong&gt;Limitations of the Advanced Developer Extensions&lt;/strong&gt;&lt;br /&gt;There's a lot of very good stuff in the areas mentioned above, which could have significant benefits on developer productivity. However, I don't think you can immediately replace all existing .Net code (even if you wanted to), as there are some areas that I don't think these extensions reach (yet?). Note that the following list is based on my investigations so far, and may include features that do exist, but which I've missed in my brief analysis so far. &lt;/p&gt;&lt;ol&gt;&lt;li&gt;Plugins. As mentioned above, the constructor for the XrmDataContext class has no overload that takes an IPluginExecutionContext. I also can't see a way to manipulate a DynamicEntity (e.g. from InputParameters) within these extensions, so I don't think they are viable for use in plugin code&lt;/li&gt;&lt;li&gt;IFD (aka SPLA) impersonation. AD impersonation is supported, but I can't see the equivalent of the CrmImpersonator class. I need to do some further tests on this to see if IFD impersonation can work with these extensions; if not it would restrict the deployment scenarios for web extensions&lt;/li&gt;&lt;/ol&gt;&lt;p&gt;It's also worth pointing out that the major benefits of the extension code relate to standard data operations (Create, Retrieve, Update, Delete). You can still use the additional messages (e.g. InstantiateTemplate, Merge) of the CrmService and MetadataService through these extensions, but you'll need to use the standard SDK types&lt;/p&gt;&lt;p&gt;My understanding is that these extensions originated as a basis for developing portal-style applications against CRM, so in that context it is not at all surprising that there are areas where the code can't reach. It'll be interesting to see how this changes, both with CRM 4 and CRM 5.&lt;/p&gt;&lt;p&gt;&lt;strong&gt;What Next ?&lt;/strong&gt;&lt;br /&gt;What next, indeed. The timing of this release is interesting, coming relatively late in the life of CRM 4 as the most recent version of CRM. It's still a little too early to know what will happen with CRM 5, but it would be logical to expect that these extensions will continue to work with future versions of CRM. The more interesting question is whether we will continue to have more that one programming model for CRM 5 (e.g. a native interface, and extensions such as these which form a wrapper around the native interface), or whether these 2 models will start to merge together. &lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/199106851038957806-8456104947929322353?l=mscrmuk.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://mscrmuk.blogspot.com/feeds/8456104947929322353/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=199106851038957806&amp;postID=8456104947929322353' title='3 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/199106851038957806/posts/default/8456104947929322353'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/199106851038957806/posts/default/8456104947929322353'/><link rel='alternate' type='text/html' href='http://mscrmuk.blogspot.com/2010/05/crm-sdk-4012-and-advanced-developer.html' title='CRM SDK 4.0.12 and the Advanced Developer Extensions'/><author><name>David Jennaway</name><uri>http://www.blogger.com/profile/09695858105618938443</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>3</thr:total></entry><entry><id>tag:blogger.com,1999:blog-199106851038957806.post-8684738851738855778</id><published>2010-04-13T17:38:00.001+01:00</published><updated>2010-04-13T17:38:00.132+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Announcement'/><title type='text'>CRM 4.0 UR 10</title><content type='html'>It's that time again; a new Update &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_0"&gt;Rollup&lt;/span&gt; is out. See&lt;br /&gt;&lt;a href="http://support.microsoft.com/?kbid=979347"&gt;http://support.microsoft.com/?kbid=979347&lt;/a&gt;&lt;br /&gt;&lt;a href="http://www.microsoft.com/downloads/details.aspx?displaylang=en&amp;amp;FamilyID=5da4d352-1d3f-4426-9c17-b256c30afdb9"&gt;http://www.microsoft.com/downloads/details.aspx?displaylang=en&amp;amp;&lt;span class="blsp-spelling-error" id="SPELLING_ERROR_1"&gt;FamilyID&lt;/span&gt;=5&lt;span class="blsp-spelling-error" id="SPELLING_ERROR_2"&gt;da&lt;/span&gt;4d352-1d3f-4426-9c17-b256c30&lt;span class="blsp-spelling-error" id="SPELLING_ERROR_3"&gt;afdb&lt;/span&gt;9&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;I think the most significant fix in this &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_4"&gt;rollup&lt;/span&gt; is the fix for &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_5"&gt;metadata&lt;/span&gt; in new Organisation databases, as described at &lt;a href="http://support.microsoft.com/kb/980627/"&gt;http://support.microsoft.com/kb/980627/&lt;/a&gt; . This fixes a bug that started in UR 7, in which a newly created organisation (i.e. created after &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_6"&gt;rollup&lt;/span&gt; 7 or higher had been installed) missed some &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_7"&gt;SQL&lt;/span&gt; objects and permissions. The 2 symptoms I'd met of this were:&lt;br /&gt;&lt;ol&gt;&lt;li&gt;Missing stored procedures for cascading relationships. This gives the error: &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_8"&gt;SqlException&lt;/span&gt;: Could not find stored procedure '&lt;span class="blsp-spelling-error" id="SPELLING_ERROR_9"&gt;dbo&lt;/span&gt;.p_&lt;span class="blsp-spelling-error" id="SPELLING_ERROR_10"&gt;CascadeCollectAssign&lt;/span&gt;'&lt;/li&gt;&lt;li&gt;Missing permissions on the &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_11"&gt;FilteredActivityPointer&lt;/span&gt; view. This gives the error: the SELECT permission was denied on the object '&lt;span class="blsp-spelling-error" id="SPELLING_ERROR_12"&gt;FilteredActivityPointer&lt;/span&gt;', and is described &lt;a href="http://icu-mscrm.blogspot.com/2010/03/select-permission-was-denied-on-object.html"&gt;here&lt;/a&gt;&lt;/li&gt;&lt;/ol&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/199106851038957806-8684738851738855778?l=mscrmuk.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://mscrmuk.blogspot.com/feeds/8684738851738855778/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=199106851038957806&amp;postID=8684738851738855778' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/199106851038957806/posts/default/8684738851738855778'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/199106851038957806/posts/default/8684738851738855778'/><link rel='alternate' type='text/html' href='http://mscrmuk.blogspot.com/2010/04/crm-40-ur-10.html' title='CRM 4.0 UR 10'/><author><name>David Jennaway</name><uri>http://www.blogger.com/profile/09695858105618938443</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-199106851038957806.post-8941121496045199431</id><published>2010-03-13T13:38:00.003Z</published><updated>2010-03-13T13:38:00.090Z</updated><category scheme='http://www.blogger.com/atom/ns#' term='SQL Server'/><title type='text'>A bit of SQL - finding CRM attributes with no data</title><content type='html'>Over time I've been asked to review various existing CRM implementations. One thing I often like to check is whether there are any attributes that are not in use. To this end I created the stored procedure at the end of this post.&lt;br /&gt;&lt;br /&gt;The stored procedure lists the attributes in an entity along with how many records contain data in that attribute. The parameters in the procedure allow you to limit the attributes to custom attributes, and to specify a maximum count of values (above which the attribute data won't be output).&lt;br /&gt;&lt;br /&gt;Notes:&lt;br /&gt;&lt;ol&gt;&lt;li&gt;The procedure as written would be created in the MSCRM organisation database. You could create it in a different database, and add the databasename.schemaname. prefixes if you want&lt;/li&gt;&lt;li&gt;The procedure uses the supported route of querying the filtered view for an entity. If you have SQL dbo permission, and don't mind deleted records being included in the counts, then you can run the query against the base view, which is considerably faster. To do this, remove the string 'Filtered' from the procedure definition&lt;/li&gt;&lt;/ol&gt;&lt;p&gt;Use the following SQL to create the stored procedure:&lt;/p&gt;&lt;span style="font-family:courier new;font-size:85%;"&gt;create proc pExcCheckColumnValues @entityName nvarchar(64), @customOnly bit = 0, @maxThreshold int = null&lt;br /&gt;as&lt;br /&gt;declare @attrName nvarchar(50), @sql nvarchar(1024)&lt;br /&gt;declare cur cursor fast_forward for&lt;br /&gt; select a.name from attribute a&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;font-size:85%;"&gt;  join entity e on a.entityid = e.entityid&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;font-size:85%;"&gt;  where e.name = @entityName and a.IsLogical = 0 &lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;font-size:85%;"&gt;   and ((@customOnly = 1 and a.IsCustomField = 1) or isnull(@customOnly, 0) = 0)&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;font-size:85%;"&gt;create table #tmp (EntityName nvarchar(64), AttributeName nvarchar(50), ValueCount int)&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;font-size:85%;"&gt;open cur&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;font-size:85%;"&gt;fetch next from cur into @attrName&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;font-size:85%;"&gt;while @@fetch_status = 0&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;font-size:85%;"&gt;begin&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;font-size:85%;"&gt; set @sql = 'insert #tmp select ''' + @entityName + ''', ''' + @attrName + ''', count(*) from Filtered' + @entityName + ' where ' + @attrName + ' is not null'  &lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;font-size:85%;"&gt;  + case when @maxThreshold is not null then ' having count(*) &lt;= ' + cast(@maxThreshold as nvarchar) else '' end &lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;font-size:85%;"&gt; exec (@sql)&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;font-size:85%;"&gt; fetch next from cur into @attrName&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;font-size:85%;"&gt;end&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;font-size:85%;"&gt;close cur&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;font-size:85%;"&gt;deallocate cur&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;font-size:85%;"&gt;select * from #tmp&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:Courier New;font-size:85%;"&gt;go&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:Courier New;font-size:85%;"&gt;&lt;/span&gt;&lt;br /&gt;To give an example of how to use the procedure, the following will return all custom attributes of the account, where no more than 10 account records have a value in this field:&lt;br /&gt;&lt;br /&gt;&lt;span style="font-size:85%;"&gt;&lt;span style="font-family:courier new;"&gt;exec pExcCheckColumnValues @entityName = 'account', @customOnly = 1, @maxThreshold = 10&lt;/span&gt; &lt;/span&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/199106851038957806-8941121496045199431?l=mscrmuk.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://mscrmuk.blogspot.com/feeds/8941121496045199431/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=199106851038957806&amp;postID=8941121496045199431' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/199106851038957806/posts/default/8941121496045199431'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/199106851038957806/posts/default/8941121496045199431'/><link rel='alternate' type='text/html' href='http://mscrmuk.blogspot.com/2010/03/bit-of-sql-finding-crm-attributes-with.html' title='A bit of SQL - finding CRM attributes with no data'/><author><name>David Jennaway</name><uri>http://www.blogger.com/profile/09695858105618938443</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-199106851038957806.post-5964318523548709892</id><published>2010-03-11T19:14:00.002Z</published><updated>2010-03-16T10:56:25.754Z</updated><category scheme='http://www.blogger.com/atom/ns#' term='Security'/><category scheme='http://www.blogger.com/atom/ns#' term='Troubleshooting'/><category scheme='http://www.blogger.com/atom/ns#' term='Installation'/><title type='text'>Service Principle Names and Security</title><content type='html'>I've recently been working with CRM and Reporting Services in environments where AD delegation has been required, and hence it's been important to configure Service Principle Names (SPN).&lt;br /&gt;&lt;br /&gt;A good overview of SPNs and how they are set can be found in this &lt;a href="http://www.microsoft.com/downloads/details.aspx?displaylang=en&amp;amp;FamilyID=51bf9f20-bd00-4759-8378-b38eefda7b99"&gt;document &lt;/a&gt;for CRM 3. Although some of the steps in that document have been superseded by the use of the CRM 4.0 Reporting Services connector, the document is still a good reference for the main aspects of setting up SPNs.&lt;br /&gt;&lt;br /&gt;There are two further considerations that are not covered in the above document though; ensuring Kerberos is used, and getting permission to modify SPNs.&lt;br /&gt;&lt;br /&gt;&lt;strong&gt;Ensure Kerberos is used&lt;/strong&gt;&lt;br /&gt;There are 2 Windows authentication mechanisms: NTLM (aka Challenge/Response) and Kerberos. Only Kerberos supports delegation. By default, Kerberos will be used if the client supports it (this setting is known as 'Negotiate'), but this behaviour can be changed.&lt;br /&gt;&lt;br /&gt;For web applications hosted in IIS (such as CRM and Reporting Servers 2005), this is controlled by the NTAuthenticationProvider setting in the IIS metabase. Note that this can be set at a few &lt;a href="http://mscrmuk.blogspot.com/2009/08/windows-nt-authentication-provider-it.html"&gt;different levels&lt;/a&gt;, and you'll need to check them all to determine the current configuration. When you install CRM, the Environment Diagnostics Wizard requires that Negotiate is the default setting, though it could have been changed after install.&lt;br /&gt;&lt;br /&gt;Reporting Services 2008 does not use IIS, and the authentication settings are configured in the rsreportserver.config file. Information about these settings can be found &lt;a href="http://msdn.microsoft.com/en-gb/library/bb283249.aspx"&gt;here&lt;/a&gt; in SQL Server 2008 Books Online.&lt;br /&gt;&lt;br /&gt;&lt;strong&gt;Permissions required to modify SPNs&lt;/strong&gt;&lt;br /&gt;It's all very well knowing what SPNs need to be created or modified, but you may not have permission to do this, especially in high security environments. SPN data is stored in Active Directory, hence you need appropriate permissions in Active Directory. There are two approaches that you can take to get the SPNs setup if you don't have permission:&lt;br /&gt;&lt;ol&gt;&lt;li&gt;Ask a Domain Administrator to grant you the permissions. The second half of this &lt;a href="http://technet.microsoft.com/en-us/library/cc731241(WS.10).aspx"&gt;technet article &lt;/a&gt;describes the permissions you need, and how they are assigned&lt;/li&gt;&lt;li&gt;The individual service accounts can be granted permission to create their own SPNs. This is more applicable to SQL Server SPNs, but can be used by any code that can register it's own SPN. This is well described &lt;a href="http://clintboessen.blogspot.com/2010/02/dynamically-set-spns-for-sql-service.html"&gt;here&lt;/a&gt;&lt;/li&gt;&lt;/ol&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/199106851038957806-5964318523548709892?l=mscrmuk.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://mscrmuk.blogspot.com/feeds/5964318523548709892/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=199106851038957806&amp;postID=5964318523548709892' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/199106851038957806/posts/default/5964318523548709892'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/199106851038957806/posts/default/5964318523548709892'/><link rel='alternate' type='text/html' href='http://mscrmuk.blogspot.com/2010/03/service-principle-names-and-security.html' title='Service Principle Names and Security'/><author><name>David Jennaway</name><uri>http://www.blogger.com/profile/09695858105618938443</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-199106851038957806.post-6823133433233017264</id><published>2010-02-12T21:01:00.002Z</published><updated>2010-02-12T21:06:59.376Z</updated><category scheme='http://www.blogger.com/atom/ns#' term='Announcement'/><title type='text'>Update Rollup 9</title><content type='html'>It's that time of every other month again. A new update &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_0"&gt;rollup&lt;/span&gt; is available; &lt;a href="http://support.microsoft.com/kb/977650/en-us/"&gt;number 9&lt;/a&gt; is available &lt;a href="http://www.microsoft.com/downloads/details.aspx?displaylang=en&amp;amp;FamilyID=5869f2b3-d1a0-4f71-8be3-fde6e8053a2e"&gt;here&lt;/a&gt;. There don't seem to be any particularly important fixes this time, unless you're in one of the time zones affect by this &lt;a href="http://support.microsoft.com/default.aspx/kb/948155/"&gt;bug&lt;/a&gt;, which is now fixed&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/199106851038957806-6823133433233017264?l=mscrmuk.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://mscrmuk.blogspot.com/feeds/6823133433233017264/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=199106851038957806&amp;postID=6823133433233017264' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/199106851038957806/posts/default/6823133433233017264'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/199106851038957806/posts/default/6823133433233017264'/><link rel='alternate' type='text/html' href='http://mscrmuk.blogspot.com/2010/02/update-rollup-9.html' title='Update Rollup 9'/><author><name>David Jennaway</name><uri>http://www.blogger.com/profile/09695858105618938443</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-199106851038957806.post-7047152229995504168</id><published>2009-12-18T09:39:00.002Z</published><updated>2009-12-18T09:44:50.191Z</updated><category scheme='http://www.blogger.com/atom/ns#' term='Deployment'/><category scheme='http://www.blogger.com/atom/ns#' term='Announcement'/><title type='text'>CRM 4 Update Rollup 8 is out</title><content type='html'>See &lt;a href="http://support.microsoft.com/default.aspx?kbid=975995"&gt;http://support.microsoft.com/default.aspx?kbid=975995&lt;/a&gt; and &lt;a href="http://www.microsoft.com/downloads/details.aspx?displaylang=en&amp;amp;FamilyID=c53b2916-6b93-4092-bdd3-a394c96ca000"&gt;http://www.microsoft.com/downloads/details.aspx?displaylang=en&amp;amp;FamilyID=c53b2916-6b93-4092-bdd3-a394c96ca000&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;I've not had a chance to test it yet. One welcome inclusion is an optimisation to the Import Organisation process (&lt;a href="http://support.microsoft.com/kb/977867/"&gt;http://support.microsoft.com/kb/977867/&lt;/a&gt; ), though interestingly you have to add a registry value to enable the optimisation.&lt;br /&gt;&lt;br /&gt;There's also appraently a fix to the 'dsMain' error with Report Wizard, as described &lt;a href="http://mscrmuk.blogspot.com/2008/10/report-wizard-query-execution-failed.html"&gt;here&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/199106851038957806-7047152229995504168?l=mscrmuk.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://mscrmuk.blogspot.com/feeds/7047152229995504168/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=199106851038957806&amp;postID=7047152229995504168' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/199106851038957806/posts/default/7047152229995504168'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/199106851038957806/posts/default/7047152229995504168'/><link rel='alternate' type='text/html' href='http://mscrmuk.blogspot.com/2009/12/crm-4-update-rollup-8-is-out.html' title='CRM 4 Update Rollup 8 is out'/><author><name>David Jennaway</name><uri>http://www.blogger.com/profile/09695858105618938443</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-199106851038957806.post-277263509608965284</id><published>2009-12-03T17:03:00.003Z</published><updated>2009-12-03T17:07:23.740Z</updated><category scheme='http://www.blogger.com/atom/ns#' term='Announcement'/><category scheme='http://www.blogger.com/atom/ns#' term='Team Blog'/><category scheme='http://www.blogger.com/atom/ns#' term='SQL Server'/><title type='text'>Analysing SQL Queries in CRM environments</title><content type='html'>I've another post &lt;a href="http://blogs.msdn.com/crm/archive/2009/12/03/capturing-and-analysing-sql-queries-in-crm-implementations.aspx"&gt;here&lt;/a&gt; on the &lt;a href="http://blogs.msdn.com/crm"&gt;Dynamics &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_0"&gt;CRM&lt;/span&gt; team blog&lt;/a&gt; describing some techniques I use to make effective use of &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_1"&gt;SQL&lt;/span&gt; &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_2"&gt;Profiler&lt;/span&gt; and &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_3"&gt;SQL&lt;/span&gt; Management Studio. This post also references a tool I published &lt;a href="http://code.msdn.microsoft.com/spExecuteSqlparser"&gt;here&lt;/a&gt; on the &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_4"&gt;MSDN&lt;/span&gt; Code Gallery&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/199106851038957806-277263509608965284?l=mscrmuk.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://mscrmuk.blogspot.com/feeds/277263509608965284/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=199106851038957806&amp;postID=277263509608965284' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/199106851038957806/posts/default/277263509608965284'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/199106851038957806/posts/default/277263509608965284'/><link rel='alternate' type='text/html' href='http://mscrmuk.blogspot.com/2009/12/analysing-sql-queries-in-crm.html' title='Analysing SQL Queries in CRM environments'/><author><name>David Jennaway</name><uri>http://www.blogger.com/profile/09695858105618938443</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-199106851038957806.post-1314087140824349807</id><published>2009-12-02T10:49:00.003Z</published><updated>2009-12-02T10:54:47.227Z</updated><category scheme='http://www.blogger.com/atom/ns#' term='Code Gallery'/><category scheme='http://www.blogger.com/atom/ns#' term='SQL Server'/><title type='text'>New Code Gallery resource - sp_executesql parser</title><content type='html'>I've added a new &lt;a href="http://code.msdn.microsoft.com/spExecuteSqlparser"&gt;code resource &lt;/a&gt;to the &lt;a href="http://code.msdn.microsoft.com/"&gt;MSDN code gallery&lt;/a&gt;. This is a simple tool to parse calls to sp_executesql. The reason for it is that the SQL tools cannot show the execution plan for calls to sp_executesql, which is a pain when doing performance analysis of these queries. So, I created a tool that replaces the manual editing process.&lt;br /&gt;&lt;br /&gt;Soon, I'll post a more detailed description of SQL performance analysis for CRM implementations, which will reference this tool.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/199106851038957806-1314087140824349807?l=mscrmuk.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://mscrmuk.blogspot.com/feeds/1314087140824349807/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=199106851038957806&amp;postID=1314087140824349807' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/199106851038957806/posts/default/1314087140824349807'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/199106851038957806/posts/default/1314087140824349807'/><link rel='alternate' type='text/html' href='http://mscrmuk.blogspot.com/2009/12/new-code-gallery-resource-spexecutesql.html' title='New Code Gallery resource - sp_executesql parser'/><author><name>David Jennaway</name><uri>http://www.blogger.com/profile/09695858105618938443</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-199106851038957806.post-6873462912698491776</id><published>2009-11-13T17:56:00.002Z</published><updated>2009-11-13T18:07:31.133Z</updated><category scheme='http://www.blogger.com/atom/ns#' term='Announcement'/><title type='text'>Attachment Download code in UR 7 - an update</title><content type='html'>I've updated my original post &lt;a href="http://mscrmuk.blogspot.com/2009/11/ur-7-breaks-attachment-download-code.html"&gt;here&lt;/a&gt; to reflect a suggested fix posted by Microsoft on the MSDN Forums &lt;a href="http://social.microsoft.com/Forums/en-US/crmdevelopment/thread/2f46a3c4-1123-49dd-804e-2787ef367986"&gt;here&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;Despite my major reservations with how the problem arose, credit is due to Microsoft for responding as quickly as I think they possibly could (even if it doesn't always seem that way).&lt;br /&gt;&lt;br /&gt;My reservations relate to disagreements on the need for the change made in UR7 (I don't think it increases security at all), and also to how MS allowed a change that broke supported extensions. It'll be interesting to see what happens with UR 8...&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/199106851038957806-6873462912698491776?l=mscrmuk.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://mscrmuk.blogspot.com/feeds/6873462912698491776/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=199106851038957806&amp;postID=6873462912698491776' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/199106851038957806/posts/default/6873462912698491776'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/199106851038957806/posts/default/6873462912698491776'/><link rel='alternate' type='text/html' href='http://mscrmuk.blogspot.com/2009/11/attachment-download-code-in-ur-7-update.html' title='Attachment Download code in UR 7 - an update'/><author><name>David Jennaway</name><uri>http://www.blogger.com/profile/09695858105618938443</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-199106851038957806.post-1065530094881423792</id><published>2009-11-13T11:40:00.002Z</published><updated>2009-11-13T14:23:25.724Z</updated><category scheme='http://www.blogger.com/atom/ns#' term='Server code'/><category scheme='http://www.blogger.com/atom/ns#' term='Troubleshooting'/><category scheme='http://www.blogger.com/atom/ns#' term='Registry'/><title type='text'>Socket Exhaustion when accessing CRM web services</title><content type='html'>When submitting a large number requests to the CrmService web service, you may occasionally get the error 'Only one usage of each socket address (protocol/network address/port) is normally permitted'. The reason for this is 'socket exhaustion', which is excellently described &lt;a href="http://blogs.msdn.com/dgorti/archive/2005/09/18/470766.aspx"&gt;here&lt;/a&gt;. You are at risk of this happening when over 4000 web requests are submitted within 4 minutes - I find this most commonly on data imports, but have recently met it during heavy user activity on a live CRM system.&lt;br /&gt;&lt;br /&gt;There are 2 solutions:&lt;br /&gt;&lt;ol&gt;&lt;li&gt;As suggested in the link above, add registry values to give a much wider range of socket addresses. Note that you need to restart the server for these registry changes to take effect&lt;/li&gt;&lt;li&gt;Set the UnsafeAuthenticatedConnectionSharing and PreAuthenticate properties of your CrmService (or MetadateService) proxy to true. This will allow your web request to reuse the same socket&lt;/li&gt;&lt;/ol&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/199106851038957806-1065530094881423792?l=mscrmuk.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://mscrmuk.blogspot.com/feeds/1065530094881423792/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=199106851038957806&amp;postID=1065530094881423792' title='4 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/199106851038957806/posts/default/1065530094881423792'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/199106851038957806/posts/default/1065530094881423792'/><link rel='alternate' type='text/html' href='http://mscrmuk.blogspot.com/2009/11/socket-exhaustion-when-accessing-crm.html' title='Socket Exhaustion when accessing CRM web services'/><author><name>David Jennaway</name><uri>http://www.blogger.com/profile/09695858105618938443</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>4</thr:total></entry><entry><id>tag:blogger.com,1999:blog-199106851038957806.post-5010163792197086419</id><published>2009-11-12T09:46:00.004Z</published><updated>2009-11-12T09:57:26.034Z</updated><category scheme='http://www.blogger.com/atom/ns#' term='Security'/><category scheme='http://www.blogger.com/atom/ns#' term='Announcement'/><category scheme='http://www.blogger.com/atom/ns#' term='CRM 4.0'/><title type='text'>Field Level Security in CRM 4.0 - MS White Paper</title><content type='html'>The Microsoft Dynamics CRM Engineering for Enterprise (MS CRM E2) team have released a detailed white paper describing the supported options for implementing field-level security in CRM 4.0. It is available for download at &lt;a href="http://www.microsoft.com/downloads/details.aspx?displaylang=en&amp;amp;FamilyID=471f8670-47b3-4525-b25d-c11a6774615c"&gt;http://www.microsoft.com/downloads/details.aspx?displaylang=en&amp;amp;FamilyID=471f8670-47b3-4525-b25d-c11a6774615c&lt;/a&gt; .&lt;br /&gt;&lt;br /&gt;As I was one of the document's technical reviewers, I may be a bit biased in my praise of the document, however one option is missing from it. As a Microsoft document, it concentrates on the supported approaches, but there are also unsupported approaches, such as that taken by c360, which uses an HttpModule to modify the html sent to the client. Personally I dislike this approach, as there is a potentially heavy performance overhead, and it is fragile with respect to future changes in hotfix rollup. However, it is another option that could be considered, and is unfortunately not mentioned in the white paper.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/199106851038957806-5010163792197086419?l=mscrmuk.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://mscrmuk.blogspot.com/feeds/5010163792197086419/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=199106851038957806&amp;postID=5010163792197086419' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/199106851038957806/posts/default/5010163792197086419'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/199106851038957806/posts/default/5010163792197086419'/><link rel='alternate' type='text/html' href='http://mscrmuk.blogspot.com/2009/11/field-level-security-in-crm-40-ms-white.html' title='Field Level Security in CRM 4.0 - MS White Paper'/><author><name>David Jennaway</name><uri>http://www.blogger.com/profile/09695858105618938443</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-199106851038957806.post-1044810735068033001</id><published>2009-11-06T09:52:00.004Z</published><updated>2009-11-13T17:56:21.752Z</updated><category scheme='http://www.blogger.com/atom/ns#' term='Troubleshooting'/><category scheme='http://www.blogger.com/atom/ns#' term='CRM 4.0'/><category scheme='http://www.blogger.com/atom/ns#' term='Registry'/><title type='text'>UR 7 breaks Attachment Download code, and how to fix it</title><content type='html'>* 2009-11-13. I've updated this post to reflect some proposed SDK changes published by Microsoft to the MSDN Forums &lt;a href="http://social.microsoft.com/Forums/en-US/crmdevelopment/thread/2f46a3c4-1123-49dd-804e-2787ef367986"&gt;here&lt;/a&gt;. I'll probably update this post again for reasons I'll come to later, but I think it's worth making an initial update now *&lt;br /&gt;&lt;br /&gt;It was going to happen at some point; a CRM hotfix rollup that broke existing supported customisation code. Update Rollup 7 adds some security changes that apply to the Attachment/download.aspx page. As a result the example code documented &lt;a href="http://msdn.microsoft.com/en-gb/library/cc151179.aspx"&gt;here&lt;/a&gt; in the SDK no longer works.&lt;br /&gt;&lt;br /&gt;If you try the code, the user gets the error message "Access Denied, Invalid Operation". If you enable tracing, you see a message like the following:&lt;br /&gt;"Message: INVALID_WRPC_TOKEN: Validate WRPC Token: WRPCTokenState=Invalid, TOKEN_EXPIRY=4320, IGNORE_TOKEN=False, TOKEN_KEY=b1Nd0byfEd6+gwAZuez7cauYiRnfHuMLAquFY1Ks22dHgxZiW5IrxSobkv9aVfbC, ErrorCode: -2140991221"&lt;br /&gt;&lt;br /&gt;The fundamental problem is that CRM now expects additional parameters on the query string that contain a Token, and there is no way for us to generate that token. There's a significant question about why this change was made, but I'll leave that for another time.&lt;br /&gt;&lt;br /&gt;The recommended workaround is the use the web services directly as described at &lt;a href="http://social.microsoft.com/Forums/en-US/crmdevelopment/thread/2f46a3c4-1123-49dd-804e-2787ef367986"&gt;http://social.microsoft.com/Forums/en-US/crmdevelopment/thread/2f46a3c4-1123-49dd-804e-2787ef367986&lt;/a&gt;, which I expect to make it into the SDK soon. This is close to a like-for-like replacement for the original SDK code in that it is the type of code you might write for a console application.&lt;br /&gt;&lt;br /&gt;However, a popular use of download.aspx was to provide any easy client-side link to download an attachment, rather than doing it programmatically with .Net code. To get equivalent behaviour you'll need a custom .aspx page that gets the uses similar code to that above, but writes it the response stream using Response.BinaryWrite. I'm going to have to write this code soon, and when I do I'll post it on the MSDN Code Gallery, and link to it here; in the meantime if anyone has to write it themselves the other thing you should do is pass information on the Response-Header to specify the filename. From memory this involves something like:&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family:courier new;font-size:85%;"&gt;Response.AddHeader("content-disposition","attachment; filename=" + outputFile);&lt;/span&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/199106851038957806-1044810735068033001?l=mscrmuk.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://mscrmuk.blogspot.com/feeds/1044810735068033001/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=199106851038957806&amp;postID=1044810735068033001' title='9 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/199106851038957806/posts/default/1044810735068033001'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/199106851038957806/posts/default/1044810735068033001'/><link rel='alternate' type='text/html' href='http://mscrmuk.blogspot.com/2009/11/ur-7-breaks-attachment-download-code.html' title='UR 7 breaks Attachment Download code, and how to fix it'/><author><name>David Jennaway</name><uri>http://www.blogger.com/profile/09695858105618938443</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>9</thr:total></entry><entry><id>tag:blogger.com,1999:blog-199106851038957806.post-4778060386491652081</id><published>2009-11-05T19:56:00.001Z</published><updated>2009-11-05T19:56:00.216Z</updated><category scheme='http://www.blogger.com/atom/ns#' term='64 Bit'/><category scheme='http://www.blogger.com/atom/ns#' term='SSIS'/><category scheme='http://www.blogger.com/atom/ns#' term='Excel'/><title type='text'>SSIS Packages and Excel Data on 64 bit machines</title><content type='html'>We do a fair amount of integration work between CRM and Excel using SSIS, and it's all got a bit harder with 64 bit machines. The main issues are:&lt;br /&gt;&lt;p&gt;&lt;strong&gt;There is no 64 bit OLEDB provider for Excel&lt;/strong&gt;&lt;br /&gt;So the packages cannot be executed by 64 bit code. This meant that the programmatic route for running packages with the classes in the Microsoft.SqlServer.Dts.Runtime namespace no longer works. The error you get is typically unhelpful - 'AcquireConnection method call to the connection manager "EXCEL: Source" failed with error code 0xC00F9304'. You can also get error code 0xC020801C.&lt;/p&gt;&lt;p&gt;The workaround is to run a package using the 32 bit version of dtexec.exe, which should be installed in Program Files (x86)\Microsoft SQL Server\100\DTS\Binn. This is also the fix if scheduling packages with the SQL Agent; your job steps need to be of type CmdExec instead of SSIS Package, and you have to learn the command line syntax of dtexec.&lt;/p&gt;&lt;p&gt;Overall, something of a pain, but I've not yet found anything I can't do with dtexec.exe and its command line parameters.&lt;/p&gt;&lt;p&gt;&lt;strong&gt;The Registry settings for the 32 bit OLEDB provider for Excel have moved&lt;/strong&gt;&lt;br /&gt;There are a several registry settings that you may need to make the OLEDB provider for Excel work, as described &lt;a href="http://mscrmuk.blogspot.com/2008/10/excel-data-type-issues-with-oledb-and.html"&gt;here&lt;/a&gt; and &lt;a href="http://blog.lab49.com/archives/196"&gt;here&lt;/a&gt;. When running a package in 32 bit mode on a 64 bit server, you find that it uses registry keys in a different location. &lt;/p&gt;&lt;p&gt;Values that were in HKLM\SOFTWARE\Microsoft\Jet\4.0\Engines\Excel are now in HKLM\SOFTWARE\Wow6432Node\Microsoft\Jet\4.0\Engines\Excel. &lt;/p&gt;&lt;p&gt;Note also that the paths to the providers have changed, so for example "Win32"="C:\Windows\system32\msexcl40.dll" becomes "Win32"="C:\Windows\syswow64\msexcl40.dll"&lt;/p&gt;&lt;p&gt;Although my emphasis here has been on Excel providers, and SSIS, the issues and resolutions can apply to other OLEDB providers and environments, as there are several OLEDB providers that are not expected to have 64 bit releases (the Exchange OLEDB provider, and the FoxPro one are 2 that I'm aware of)&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/199106851038957806-4778060386491652081?l=mscrmuk.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://mscrmuk.blogspot.com/feeds/4778060386491652081/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=199106851038957806&amp;postID=4778060386491652081' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/199106851038957806/posts/default/4778060386491652081'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/199106851038957806/posts/default/4778060386491652081'/><link rel='alternate' type='text/html' href='http://mscrmuk.blogspot.com/2009/11/ssis-packages-and-excel-data-on-64-bit.html' title='SSIS Packages and Excel Data on 64 bit machines'/><author><name>David Jennaway</name><uri>http://www.blogger.com/profile/09695858105618938443</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-199106851038957806.post-1304455863215229956</id><published>2009-09-22T17:06:00.003+01:00</published><updated>2009-09-22T17:13:58.190+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Design Patterns'/><category scheme='http://www.blogger.com/atom/ns#' term='Reports'/><category scheme='http://www.blogger.com/atom/ns#' term='Team Blog'/><category scheme='http://www.blogger.com/atom/ns#' term='Data Integration'/><title type='text'>Data Integration using Reports</title><content type='html'>I've another post on the &lt;a href="http://blogs.msdn.com/crm"&gt;CRM Team Blog &lt;/a&gt;site at &lt;a href="http://blogs.msdn.com/crm/archive/2009/09/22/data-integration-a-reporting-approach.aspx"&gt;http://blogs.msdn.com/crm/archive/2009/09/22/data-integration-a-reporting-approach.aspx&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;This is another post on design patterns (like this &lt;a href="http://mscrmuk.blogspot.com/2009/05/crm-design-patterns-and-back-on-mscrm.html"&gt;one&lt;/a&gt;), looking initially at potential data integration approaches and key issues, then covering some specifics on the reporting approach.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/199106851038957806-1304455863215229956?l=mscrmuk.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://mscrmuk.blogspot.com/feeds/1304455863215229956/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=199106851038957806&amp;postID=1304455863215229956' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/199106851038957806/posts/default/1304455863215229956'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/199106851038957806/posts/default/1304455863215229956'/><link rel='alternate' type='text/html' href='http://mscrmuk.blogspot.com/2009/09/data-integration-using-reports.html' title='Data Integration using Reports'/><author><name>David Jennaway</name><uri>http://www.blogger.com/profile/09695858105618938443</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-199106851038957806.post-3055128456796988994</id><published>2009-09-03T10:18:00.002+01:00</published><updated>2009-09-03T10:23:58.010+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='MVP'/><category scheme='http://www.blogger.com/atom/ns#' term='Announcement'/><title type='text'>Announcements: Update Rollup 6 and DynamicsWorld</title><content type='html'>As announced elsewhere, CRM 4.0 &lt;a href="http://support.microsoft.com/default.aspx?kbid=970148"&gt;Update Rollup 6&lt;/a&gt; has been released. Our initial assessment is that there is one significant fix – to resolve the &lt;a href="http://support.microsoft.com/kb/974037/"&gt;Invalid Email Address &lt;/a&gt;error introduced in rollup 4. For those customers where the decision whether or not to apply a rollup is decided on a per rollup basis, this fix will typically be significant enough to apply the rollup.&lt;br /&gt;&lt;br /&gt;I was interviewed for the &lt;a href="http://www.dynamicsworld.co.uk/index.php"&gt;Dynamics World&lt;/a&gt; web site recently, so I figured I should add a link to the interview &lt;a href="http://www.dynamicsworld.co.uk/MVP-Profiles.php"&gt;here&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/199106851038957806-3055128456796988994?l=mscrmuk.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://mscrmuk.blogspot.com/feeds/3055128456796988994/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=199106851038957806&amp;postID=3055128456796988994' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/199106851038957806/posts/default/3055128456796988994'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/199106851038957806/posts/default/3055128456796988994'/><link rel='alternate' type='text/html' href='http://mscrmuk.blogspot.com/2009/09/announcements-update-rollup-6-and.html' title='Announcements: Update Rollup 6 and DynamicsWorld'/><author><name>David Jennaway</name><uri>http://www.blogger.com/profile/09695858105618938443</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-199106851038957806.post-4370770477861763857</id><published>2009-08-18T10:58:00.003+01:00</published><updated>2009-08-18T11:14:37.603+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Security'/><category scheme='http://www.blogger.com/atom/ns#' term='IIS'/><category scheme='http://www.blogger.com/atom/ns#' term='Installation'/><title type='text'>Windows NT Authentication Provider - it can work at several levels</title><content type='html'>One of the diagnostics checks performed by the CRM Environmental Diagnostics Wizard prior to installation is to confirm that the CRM web site has the NTAuthenticationProvider set to 'Negotiate,NTLM'. I've never entirely worked out why this is necessary, especially as I've subsequently changed the Authentication provider after installation with no adverse effects (* though see below), but that's not the point of this post.&lt;br /&gt;&lt;br /&gt;The main point is that the NTAuthenticationProvider attribute can be viewed or set at several levels via the adsutil.vbs script. This is reasonably well documented in the &lt;a href="http://support.microsoft.com/kb/215383"&gt;Technet article &lt;/a&gt;referenced from the EDW help file. However, what is not made clear is that the attribute can be set at one of 3 levels. Each of the following commands does something slightly different:&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family:courier new;font-size:85%;"&gt;cscript adsutil.vbs set w3svc/&lt;em&gt;WebSite&lt;/em&gt;/root/NTAuthenticationProviders "Negotiate,NTLM"&lt;br /&gt;cscript adsutil.vbs set w3svc/&lt;em&gt;WebSite&lt;/em&gt;/NTAuthenticationProviders "Negotiate,NTLM"&lt;br /&gt;cscript adsutil.vbs set w3svc/NTAuthenticationProviders "Negotiate,NTLM"&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;The third command is noticeably different, in that it sets the attribute at the server level, rather than the web site level. I can't see any particular reason for different behaviour between the first 2 commands, but it does affect the CRM EDW. As far as I can tell, you need to use the syntax in the second command to satisfy the EDW, whereas unfortunately the Technet article uses the syntax in the first command.&lt;br /&gt;&lt;br /&gt;* Re what Authentication Provider to use. I've happily run a single server implementation of CRM using NTLM authentication, but I expect Kerberos may be necessary in a multi-server implementation&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/199106851038957806-4370770477861763857?l=mscrmuk.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://mscrmuk.blogspot.com/feeds/4370770477861763857/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=199106851038957806&amp;postID=4370770477861763857' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/199106851038957806/posts/default/4370770477861763857'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/199106851038957806/posts/default/4370770477861763857'/><link rel='alternate' type='text/html' href='http://mscrmuk.blogspot.com/2009/08/windows-nt-authentication-provider-it.html' title='Windows NT Authentication Provider - it can work at several levels'/><author><name>David Jennaway</name><uri>http://www.blogger.com/profile/09695858105618938443</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-199106851038957806.post-3755308517227045004</id><published>2009-08-07T16:51:00.002+01:00</published><updated>2009-08-07T16:54:16.572+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Security'/><category scheme='http://www.blogger.com/atom/ns#' term='Reports'/><category scheme='http://www.blogger.com/atom/ns#' term='SQL Server'/><title type='text'>Reports on CRM Privileges - Update to view by User</title><content type='html'>I've added 2 reports to the resource on the &lt;a href="http://code.msdn.microsoft.com/CrmSecurityReports"&gt;MSDN Code Gallery&lt;/a&gt;. These show cumulative privileges by user across their roles&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/199106851038957806-3755308517227045004?l=mscrmuk.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://mscrmuk.blogspot.com/feeds/3755308517227045004/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=199106851038957806&amp;postID=3755308517227045004' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/199106851038957806/posts/default/3755308517227045004'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/199106851038957806/posts/default/3755308517227045004'/><link rel='alternate' type='text/html' href='http://mscrmuk.blogspot.com/2009/08/reports-on-crm-privileges-update-to.html' title='Reports on CRM Privileges - Update to view by User'/><author><name>David Jennaway</name><uri>http://www.blogger.com/profile/09695858105618938443</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-199106851038957806.post-5521487520709747181</id><published>2009-08-04T16:39:00.002+01:00</published><updated>2009-08-04T16:44:28.783+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Security'/><category scheme='http://www.blogger.com/atom/ns#' term='Reports'/><category scheme='http://www.blogger.com/atom/ns#' term='CRM 4.0'/><title type='text'>Hidden CRM Privileges</title><content type='html'>Not all CRM privileges are visible within the CRM User Interface. I recently spent some time investigating what privileges exist in CRM, and how the privilege information is stored in the MSCRM database.&lt;br /&gt;&lt;br /&gt;The results of these investigations have been posted on the &lt;a href="http://blogs.msdn.com/crm/archive/2009/08/04/viewing-all-crm-privileges-including-hidden-privileges.aspx"&gt;Microsoft Dynamics CRM Team Blog&lt;/a&gt;. I also created a couple of reporting services reports to display the privilege data by role. These are available on the &lt;a href="http://code.msdn.microsoft.com/CrmSecurityReports"&gt;MSDN Code Gallery&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/199106851038957806-5521487520709747181?l=mscrmuk.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://mscrmuk.blogspot.com/feeds/5521487520709747181/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=199106851038957806&amp;postID=5521487520709747181' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/199106851038957806/posts/default/5521487520709747181'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/199106851038957806/posts/default/5521487520709747181'/><link rel='alternate' type='text/html' href='http://mscrmuk.blogspot.com/2009/08/hidden-crm-privileges.html' title='Hidden CRM Privileges'/><author><name>David Jennaway</name><uri>http://www.blogger.com/profile/09695858105618938443</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-199106851038957806.post-9096546860332346957</id><published>2009-07-30T09:48:00.015+01:00</published><updated>2009-07-30T10:11:38.373+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Error Codes'/><category scheme='http://www.blogger.com/atom/ns#' term='Server code'/><category scheme='http://www.blogger.com/atom/ns#' term='CRM 4.0'/><title type='text'>Some undocumented CRM attribute types</title><content type='html'>I was working on some custom plugin registration tools recently, and came across some undocumented attribute types. Several customisation entities (e.g. PluginAssembly, PluginType, SavedQuery) have an attribute called CustomizationLevel which has a value of 0 for system data, and 1 if it is custom or customised (according to the &lt;a href="http://msdn.microsoft.com/en-gb/library/cc906187.aspx"&gt;SDK&lt;/a&gt;).&lt;br /&gt;&lt;br /&gt;The SDK documentation states this attribute is of type CrmNumber, so when writing a QueryExpression that selects only records with a CustomizationLevel = 1, it would seem reasonable to use something like:&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family:courier new;font-size:85%;"&gt;qe.Criteria.AddCondition(new ConditionExpression("customizationlevel", ConditionOperator.Equal, 1));&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;However, this gives the error “Condition for attribute 'customizationlevel': expected argument(s) of type 'System.Byte' but received 'System.Int32' " (code 0x80040203 - Invalid Argument). Digging deeper I found that the field for the CustomizationLevel is stored in SQL as a tinyint (i.e. a single-byte integer), and that the AttributeTypes table in CRM has a corresponding AttributeType of tinyint.&lt;br /&gt;&lt;br /&gt;So, despite the attribute being identified as a CrmNumber, any condition expressions need to pass values as a single-byte integer, not the documented four-byte integer. This is easily done by using the following:&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family:courier new;font-size:85%;"&gt;qe.Criteria.AddCondition(new ConditionExpression("customizationlevel", ConditionOperator.Equal, (Byte) 1));&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;Being somewhat nosey, I thought to see what other attribute types there were. These can be easily found with the following SQL query:&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family:courier new;font-size:85%;"&gt;Select * from AttributeTypes&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;In addition to tinyint, 2 similar types caught my attention – smallint and bigint (SQL Server data type names are not that imaginative). Following on from this, the following SQL query lists attributes of these types, which may cause similar problems to those above:&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family:courier new;font-size:85%;"&gt;select e.name as Entity, a.name as Attribute, at.description as [Type]&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;font-size:85%;"&gt;from attribute a join entity e on a.entityid = e.entityid&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;font-size:85%;"&gt;join attributetypes at on a.attributetypeid = at.attributetypeid&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;font-size:85%;"&gt;where at.description in ('tinyint', 'smallint', 'bigint')&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;font-size:85%;"&gt;order by at.description, e.name, a.name&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;This yields the following results. The bigint attributes aren’t a concern, as these 2 attributes aren’t available via the CRM platform, but you could encounter some of the smallint types on UserSettings, in which case I expect you’d have to cast values to Int16.&lt;br /&gt;&lt;br /&gt;&lt;table border="1"&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td&gt;&lt;b&gt;Entity&lt;/b&gt;&lt;/td&gt;&lt;td&gt;&lt;b&gt;Attribute&lt;/b&gt;&lt;/td&gt;&lt;td&gt;&lt;b&gt;Type&lt;/b&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;AsyncOperation&lt;/td&gt;&lt;td&gt;sequence&lt;/td&gt;&lt;td&gt;bigint&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;Subscription&lt;/td&gt;&lt;td&gt;completedsyncversionnumber&lt;/td&gt;&lt;td&gt;bigint&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;Organization&lt;/td&gt;&lt;td&gt;tokenexpiry&lt;/td&gt;&lt;td&gt;smallint&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;UserSettings&lt;/td&gt;&lt;td&gt;advancedfindstartupmode&lt;/td&gt;&lt;td&gt;smallint&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;UserSettings&lt;/td&gt;&lt;td&gt;timezonecode&lt;/td&gt;&lt;td&gt;smallint&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;UserSettings&lt;/td&gt;&lt;td&gt;timezonedaylightday&lt;/td&gt;&lt;td&gt;smallint&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;UserSettings&lt;/td&gt;&lt;td&gt;timezonedaylightdayofweek&lt;/td&gt;&lt;td&gt;smallint&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;UserSettings&lt;/td&gt;&lt;td&gt;timezonedaylighthour&lt;/td&gt;&lt;td&gt;smallint&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;UserSettings&lt;/td&gt;&lt;td&gt;timezonedaylightminute&lt;/td&gt;&lt;td&gt;smallint&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;UserSettings&lt;/td&gt;&lt;td&gt;timezonedaylightmonth&lt;/td&gt;&lt;td&gt;smallint&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;UserSettings&lt;/td&gt;&lt;td&gt;timezonedaylightsecond&lt;/td&gt;&lt;td&gt;smallint&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;UserSettings&lt;/td&gt;&lt;td&gt;timezonedaylightyear&lt;/td&gt;&lt;td&gt;smallint&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;UserSettings&lt;/td&gt;&lt;td&gt;timezonestandardday&lt;/td&gt;&lt;td&gt;smallint&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;UserSettings&lt;/td&gt;&lt;td&gt;timezonestandarddayofweek&lt;/td&gt;&lt;td&gt;smallint&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;UserSettings&lt;/td&gt;&lt;td&gt;timezonestandardhour&lt;/td&gt;&lt;td&gt;smallint&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;UserSettings&lt;/td&gt;&lt;td&gt;timezonestandardminute&lt;/td&gt;&lt;td&gt;smallint&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;UserSettings&lt;/td&gt;&lt;td&gt;timezonestandardmonth&lt;/td&gt;&lt;td&gt;smallint&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;UserSettings&lt;/td&gt;&lt;td&gt;timezonestandardsecond&lt;/td&gt;&lt;td&gt;smallint&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;UserSettings&lt;/td&gt;&lt;td&gt;timezonestandardyear&lt;/td&gt;&lt;td&gt;smallint&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;Organization&lt;/td&gt;&lt;td&gt;fiscalyeardisplaycode&lt;/td&gt;&lt;td&gt;tinyint&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;Organization&lt;/td&gt;&lt;td&gt;tagmaxaggressivecycles&lt;/td&gt;&lt;td&gt;tinyint&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;Organization&lt;/td&gt;&lt;td&gt;trackingtokeniddigits&lt;/td&gt;&lt;td&gt;tinyint&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;OrganizationUI&lt;/td&gt;&lt;td&gt;customizationlevel&lt;/td&gt;&lt;td&gt;tinyint&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;PluginAssembly&lt;/td&gt;&lt;td&gt;customizationlevel&lt;/td&gt;&lt;td&gt;tinyint&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;PluginType&lt;/td&gt;&lt;td&gt;customizationlevel&lt;/td&gt;&lt;td&gt;tinyint&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;SavedQuery&lt;/td&gt;&lt;td&gt;customizationlevel&lt;/td&gt;&lt;td&gt;tinyint&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;SdkMessage&lt;/td&gt;&lt;td&gt;customizationlevel&lt;/td&gt;&lt;td&gt;tinyint&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;SdkMessageFilter&lt;/td&gt;&lt;td&gt;customizationlevel&lt;/td&gt;&lt;td&gt;tinyint&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;SdkMessagePair&lt;/td&gt;&lt;td&gt;customizationlevel&lt;/td&gt;&lt;td&gt;tinyint&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;SdkMessageProcessingStep&lt;/td&gt;&lt;td&gt;customizationlevel&lt;/td&gt;&lt;td&gt;tinyint&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;SdkMessageProcessingStepImage&lt;/td&gt;&lt;td&gt;customizationlevel&lt;/td&gt;&lt;td&gt;tinyint&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;SdkMessageProcessingStepSecureConfig&lt;/td&gt;&lt;td&gt;customizationlevel&lt;/td&gt;&lt;td&gt;tinyint&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;SdkMessageRequest&lt;/td&gt;&lt;td&gt;customizationlevel&lt;/td&gt;&lt;td&gt;tinyint&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;SdkMessageRequestField&lt;/td&gt;&lt;td&gt;customizationlevel&lt;/td&gt;&lt;td&gt;tinyint&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;SdkMessageRequestInput&lt;/td&gt;&lt;td&gt;customizationlevel&lt;/td&gt;&lt;td&gt;tinyint&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;SdkMessageResponse&lt;/td&gt;&lt;td&gt;customizationlevel&lt;/td&gt;&lt;td&gt;tinyint&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;SdkMessageResponseField&lt;/td&gt;&lt;td&gt;customizationlevel&lt;/td&gt;&lt;td&gt;tinyint&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/199106851038957806-9096546860332346957?l=mscrmuk.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://mscrmuk.blogspot.com/feeds/9096546860332346957/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=199106851038957806&amp;postID=9096546860332346957' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/199106851038957806/posts/default/9096546860332346957'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/199106851038957806/posts/default/9096546860332346957'/><link rel='alternate' type='text/html' href='http://mscrmuk.blogspot.com/2009/07/some-undocumented-crm-attribute-types.html' title='Some undocumented CRM attribute types'/><author><name>David Jennaway</name><uri>http://www.blogger.com/profile/09695858105618938443</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-199106851038957806.post-2804897413769020979</id><published>2009-07-23T18:19:00.000+01:00</published><updated>2009-07-23T18:31:05.999+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Reports'/><category scheme='http://www.blogger.com/atom/ns#' term='SQL Server'/><title type='text'>Reading RDL Definitions directly from a ReportServer database</title><content type='html'>&lt;p&gt;Just a quick post: I recently had to extract the report definitions (RDL) directly from a ReportServer database, as the ReprtServer installation was broken. This should be straightforward, but requires some work to convert the data to a readable format. This can be done with the following SQL query:&lt;/p&gt;&lt;p&gt;&lt;span style="font-family:courier new;font-size:85%;"&gt;select convert(varchar(max), convert(varbinary(max), content))&lt;br /&gt;from catalog&lt;br /&gt;where content is not null&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/199106851038957806-2804897413769020979?l=mscrmuk.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://mscrmuk.blogspot.com/feeds/2804897413769020979/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=199106851038957806&amp;postID=2804897413769020979' title='4 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/199106851038957806/posts/default/2804897413769020979'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/199106851038957806/posts/default/2804897413769020979'/><link rel='alternate' type='text/html' href='http://mscrmuk.blogspot.com/2009/05/reading-rdl-definitions-directly-from.html' title='Reading RDL Definitions directly from a ReportServer database'/><author><name>David Jennaway</name><uri>http://www.blogger.com/profile/09695858105618938443</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>4</thr:total></entry><entry><id>tag:blogger.com,1999:blog-199106851038957806.post-7167559908691562350</id><published>2009-07-05T18:51:00.001+01:00</published><updated>2009-07-05T18:51:00.410+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Announcement'/><title type='text'>MS Dynamics Top 100 Influential People</title><content type='html'>Sometimes it's good to come last. I was honoured and flattered to find my name at &lt;a href="http://dynamicsworld.co.uk/page009.html"&gt;no. 100 &lt;/a&gt;(that's me, last on the list) in “The Microsoft Dynamics Top 100 Influential People 2009" at DynamicsWorld.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;It's good to see several other CRM MVPs ahead of me on the list - you can find out who they are &lt;a href="http://dynamicsworld.co.uk/"&gt;here&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/199106851038957806-7167559908691562350?l=mscrmuk.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://mscrmuk.blogspot.com/feeds/7167559908691562350/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=199106851038957806&amp;postID=7167559908691562350' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/199106851038957806/posts/default/7167559908691562350'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/199106851038957806/posts/default/7167559908691562350'/><link rel='alternate' type='text/html' href='http://mscrmuk.blogspot.com/2009/07/ms-dynamics-top-100-influential-people.html' title='MS Dynamics Top 100 Influential People'/><author><name>David Jennaway</name><uri>http://www.blogger.com/profile/09695858105618938443</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-199106851038957806.post-1302387237914356025</id><published>2009-07-03T18:40:00.002+01:00</published><updated>2009-07-03T18:49:09.210+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Announcement'/><title type='text'>CRM 4 Update Rollup 5</title><content type='html'>&lt;p&gt;As several others have announced, &lt;a href="http://support.microsoft.com/kb/970141"&gt;CRM 4 Update Rollup 5&lt;/a&gt; has been released. There are a couple of notable points to make:&lt;/p&gt;&lt;ol&gt;&lt;li&gt;As with update rollups 3 and 4, the majority of the fixes have not been previously released as an individual hotfix. This is different from rollups 1 and 2, which were mostly a collection of previously released fixes. In general, I think that having fewer individually released fixes is a positive thing, but that has to be traded off against the frequency of rollups (currently about every 6 to 8 weeks), which is difficult to keep up with. Across our customers, we have deployments covering 5 different rollup levels, plus some customers on CRM 3, which needs a fair bit of management, especially with regard to schema compatibility&lt;/li&gt;&lt;li&gt;So, schema compatibility. Apparently, UR5 schemas cannot be imported into versions prior to UR2, but also, pre-UR2 schemas cannot be imported into UR5. I've got some investigation to do on this, but the most important factor for me is being able to use one development environment that can be used to export (and import if necessary) schemas to all rollup versions of CRM 4. Up to now I've rarely applied rollups to development environments, but it looks like from now on, UR2 will be a minimum requirement for a development environment. Either way, it makes life harder than it should be.&lt;/li&gt;&lt;/ol&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/199106851038957806-1302387237914356025?l=mscrmuk.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://mscrmuk.blogspot.com/feeds/1302387237914356025/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=199106851038957806&amp;postID=1302387237914356025' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/199106851038957806/posts/default/1302387237914356025'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/199106851038957806/posts/default/1302387237914356025'/><link rel='alternate' type='text/html' href='http://mscrmuk.blogspot.com/2009/07/crm-4-update-rollup-5.html' title='CRM 4 Update Rollup 5'/><author><name>David Jennaway</name><uri>http://www.blogger.com/profile/09695858105618938443</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-199106851038957806.post-2709365849179739263</id><published>2009-06-16T19:38:00.002+01:00</published><updated>2009-06-16T19:41:43.959+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='SQL Server 2008'/><category scheme='http://www.blogger.com/atom/ns#' term='Deployment'/><category scheme='http://www.blogger.com/atom/ns#' term='Reports'/><category scheme='http://www.blogger.com/atom/ns#' term='Troubleshooting'/><title type='text'>Report Server location and the error: The specified path is not a metabase path</title><content type='html'>&lt;p&gt;One of the ‘known’ issues with using CRM 4.0 and ESRV0008 is that CRM does not realise that SQL 2008 Reporting Services hosts the ReportServer application outside of IIS. Hence, when you try and edit the ReportServer URL in CRM Deployment Manager, or install CRM, you may get the error "The specified path is not a metabase path". As I said, this is a known issue, and a workaround is described at &lt;a href="http://support.microsoft.com/kb/957053"&gt;http://support.microsoft.com/kb/957053&lt;/a&gt; (issue no. 6 in the article).&lt;/p&gt;&lt;p&gt;The problem though is that this workaround doesn’t always, well, work. I tried this, with no success whatsoever. Eventually, I went back to some other issues CRM had had with identifying IIS metadata in the past with CRM 3.0 (e.g. &lt;a href="http://support.microsoft.com/kb/916164"&gt;http://support.microsoft.com/kb/916164&lt;/a&gt; ). What I had to do was temporarily change the IIS bindings so that the default web-site (i.e. web-site with ID=1) was on port 80. As long as this is the case when you edit the Report Server URL, then everything works. Fortunately, all I was doing was editing an organisation in an existing deployment, and could arrange downtime to temporarily change web-site bindings; if you’re installing a new CRM deployment it may be harder to play with web-site bindings. For completeness, the steps to make this work were:&lt;/p&gt;&lt;ol&gt;&lt;li&gt;In IIS Manager, create a new web-site with bindings that match those of the ReportServer URL, as per issue 6 in KB 957053 (link above)&lt;/li&gt;&lt;li&gt;In IIS Manager, change the current web-site bindings so that the web-site with ID=1 is on port 80 with no host-headers (if necessary turn off your phone and don’t check email while people try and complain they can’t access their web-sites)&lt;/li&gt;&lt;li&gt;In CRM Deployment Manager, disable the organisation, edit the organisation an put in the ReportServer URL you want and continue till the organisation has been updated successfully. Enable the organisation&lt;/li&gt;&lt;li&gt;Back in IIS Manager, change the web-site bindings back to how they were, turn your phone back on, and find someone/something else to blame for the temporary outage&lt;/li&gt;&lt;/ol&gt;&lt;p&gt;Why Microsoft code things assuming the default web-site is on port 80 is beyond me. Oh well.&lt;/p&gt;&lt;p&gt;During my investigations I found out a few more things:&lt;/p&gt;&lt;ul&gt;&lt;li&gt;McAfee anti-virus software hooks into some popular alternate ports (in this case 8081), and it’s not easy to diagnose conflicts when you put ReportServer and McAfee on the same port&lt;/li&gt;&lt;li&gt;Configuring multiple bindings for the ReportServer URL works fine&lt;/li&gt;&lt;li&gt;'All' the above does is make sure that CRM populates the ReportServer with the correct folders, reports, data sources and permissions. It is possible to set all this up manually and get it to work, but it’s very tedious and you may need to change the Guids that identify the reports within either CRM or Report Server&lt;/li&gt;&lt;/ul&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/199106851038957806-2709365849179739263?l=mscrmuk.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://mscrmuk.blogspot.com/feeds/2709365849179739263/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=199106851038957806&amp;postID=2709365849179739263' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/199106851038957806/posts/default/2709365849179739263'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/199106851038957806/posts/default/2709365849179739263'/><link rel='alternate' type='text/html' href='http://mscrmuk.blogspot.com/2009/06/report-server-location-and-error.html' title='Report Server location and the error: The specified path is not a metabase path'/><author><name>David Jennaway</name><uri>http://www.blogger.com/profile/09695858105618938443</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-199106851038957806.post-7916077808039716091</id><published>2009-05-22T16:16:00.003+01:00</published><updated>2009-05-22T16:35:21.872+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Design Patterns'/><category scheme='http://www.blogger.com/atom/ns#' term='Team Blog'/><title type='text'>CRM Design Patterns - and back on the MSCRM Team Blog</title><content type='html'>I seem to be using my invitations to post on the &lt;a href="http://blogs.msdn.com/crm/"&gt;MSCRM Team blog&lt;/a&gt; as a prompt to publish posts - I've posted a starter post on &lt;a href="http://blogs.msdn.com/crm/archive/2009/05/21/data-design-for-crm-projects-customisation-approaches.aspx"&gt;Design Patterns&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;I'm intending this to be the first in a series of posts on Design Patterns for MS CRM. I'm using the term 'Design Pattern' deliberately to echo the same term used in object-oriented design, though I'm not intending the posts to be particularly formal or prescriptive. If you're interested in the more formal ideas of design patterns, &lt;a href="http://en.wikipedia.org/wiki/Design_pattern_(computer_science)"&gt;wikipedia &lt;/a&gt;as good a place as any to start.&lt;br /&gt;&lt;br /&gt;My reasons for investing time in this are two-fold:&lt;br /&gt;&lt;ol&gt;&lt;li&gt;I don't like having to do thinkgs more than once. When designing MS CRM solutions for a customer probably about 90% of the design decisions I make now are wholly or partly based on a previous, similar design for another customer. A lot of this information is in my head; the intention of building design patterns is to create a structure to be able to communicate this information to others&lt;/li&gt;&lt;li&gt;MS CRM solutions are a mix of out-of-the-box functionality, and specific customisations and extensions. This gives a lot of options, and a lot of additional considerations beyond traditional ground-up development, or out-of-box deployment, and I think there's a lot of new and interesting design work that can be done in this environment&lt;/li&gt;&lt;/ol&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/199106851038957806-7916077808039716091?l=mscrmuk.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://mscrmuk.blogspot.com/feeds/7916077808039716091/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=199106851038957806&amp;postID=7916077808039716091' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/199106851038957806/posts/default/7916077808039716091'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/199106851038957806/posts/default/7916077808039716091'/><link rel='alternate' type='text/html' href='http://mscrmuk.blogspot.com/2009/05/crm-design-patterns-and-back-on-mscrm.html' title='CRM Design Patterns - and back on the MSCRM Team Blog'/><author><name>David Jennaway</name><uri>http://www.blogger.com/profile/09695858105618938443</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-199106851038957806.post-1191590376206019907</id><published>2009-04-20T10:17:00.002+01:00</published><updated>2009-04-20T10:22:30.505+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Auditing'/><category scheme='http://www.blogger.com/atom/ns#' term='Reports'/><category scheme='http://www.blogger.com/atom/ns#' term='Team Blog'/><title type='text'>Using the IIS Logs to get CRM Usage information</title><content type='html'>I've been posting on the &lt;a href="http://blogs.msdn.com/crm"&gt;Microsoft CRM Team blog&lt;/a&gt; again.&lt;br /&gt;&lt;br /&gt;The &lt;a href="http://blogs.msdn.com/crm/archive/2009/04/08/crm-usage-reporting-unleashed.aspx"&gt;article&lt;/a&gt; describes how to make use of the IIS logs to get useful information about who is accessing CRM and when.&lt;br /&gt;&lt;br /&gt;This technique uses some SQL objects (tables, view and functions), and a reporting services report. The source code for these is available on the &lt;a href="http://code.msdn.microsoft.com/IISLoggingCRM"&gt;MSDN Code Gallery&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/199106851038957806-1191590376206019907?l=mscrmuk.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://mscrmuk.blogspot.com/feeds/1191590376206019907/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=199106851038957806&amp;postID=1191590376206019907' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/199106851038957806/posts/default/1191590376206019907'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/199106851038957806/posts/default/1191590376206019907'/><link rel='alternate' type='text/html' href='http://mscrmuk.blogspot.com/2009/04/using-iis-logs-to-get-crm-usage.html' title='Using the IIS Logs to get CRM Usage information'/><author><name>David Jennaway</name><uri>http://www.blogger.com/profile/09695858105618938443</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-199106851038957806.post-654365347081271263</id><published>2009-02-02T21:46:00.002Z</published><updated>2009-02-02T21:59:33.976Z</updated><category scheme='http://www.blogger.com/atom/ns#' term='SQL Server 2008'/><category scheme='http://www.blogger.com/atom/ns#' term='Announcement'/><title type='text'>CRM and SQL 2008 Whitepaper</title><content type='html'>MS have released an interesting white paper about how you can use some of the new SQL 2008 features with CRM - &lt;a href="http://www.microsoft.com/downloads/details.aspx?FamilyID=b5bb47a4-5ece-4a2a-a9b5-5435264f627d&amp;amp;DisplayLang=en"&gt;http://www.microsoft.com/downloads/details.aspx?FamilyID=b5bb47a4-5ece-4a2a-a9b5-5435264f627d&amp;amp;DisplayLang=en&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;The row compression feature, along with the sparse columns, look very useful for reducing the number of pages needed by a table, which is important for ad-hoc advanced finds which use able scans, and pre-filtered reports.&lt;br /&gt;&lt;br /&gt;Filtered indexes can be very useful, especially on the statecode for relatively volatile entities. For instance, the ability to use filtered indexes on open cases or opportunities could make a big difference to overall index storage&lt;br /&gt;&lt;br /&gt;I need to do some more testing before I'm convinced on the benefits of the page compression. I could see it working for large quantities of relatively static data, such as a large account or contact table, but I think the processing overhead on data modification (which is always hard to quantify) means that I'd be reluctant to use it on more volatile data (e.g. opportunities, cases, activities).&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/199106851038957806-654365347081271263?l=mscrmuk.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://mscrmuk.blogspot.com/feeds/654365347081271263/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=199106851038957806&amp;postID=654365347081271263' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/199106851038957806/posts/default/654365347081271263'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/199106851038957806/posts/default/654365347081271263'/><link rel='alternate' type='text/html' href='http://mscrmuk.blogspot.com/2009/02/crm-and-sql-2008-whitepaper.html' title='CRM and SQL 2008 Whitepaper'/><author><name>David Jennaway</name><uri>http://www.blogger.com/profile/09695858105618938443</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-199106851038957806.post-8483949458506696786</id><published>2009-01-26T18:22:00.004Z</published><updated>2009-01-26T18:28:41.592Z</updated><category scheme='http://www.blogger.com/atom/ns#' term='SQL Server 2008'/><category scheme='http://www.blogger.com/atom/ns#' term='SSIS'/><title type='text'>Office 2007 System Driver - errors in SSIS if you don't have them</title><content type='html'>A quick post, as I didn't find any others out there giving all the details you may need. SQL 2008 SSIS supports the Office 2007 file formats, but requires the &lt;a href="http://www.microsoft.com/downloads/thankyou.aspx?familyId=7554f536-8c28-4598-9b72-ef94e038c891&amp;amp;displayLang=en"&gt;Office 2007 System Driver&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;If you deploy a package onto a machine without these drivers, you get errors like the following when the component is validated:&lt;br /&gt;&lt;br /&gt;SSIS Error Code DTS_E_OLEDB_NOPROVIDER_ERROR&lt;br /&gt;The requested OLE DB provider Microsoft.ACE.OLEDB.12.0 is not registered&lt;br /&gt;Hresult: 0x80040154  Description: "Class not registered"&lt;br /&gt;&lt;br /&gt;Installing the Office 2007 System Driver should fix this.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/199106851038957806-8483949458506696786?l=mscrmuk.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://mscrmuk.blogspot.com/feeds/8483949458506696786/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=199106851038957806&amp;postID=8483949458506696786' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/199106851038957806/posts/default/8483949458506696786'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/199106851038957806/posts/default/8483949458506696786'/><link rel='alternate' type='text/html' href='http://mscrmuk.blogspot.com/2009/01/office-2007-system-driver-errors-in.html' title='Office 2007 System Driver - errors in SSIS if you don&apos;t have them'/><author><name>David Jennaway</name><uri>http://www.blogger.com/profile/09695858105618938443</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-199106851038957806.post-5342478425734879384</id><published>2009-01-23T15:55:00.004Z</published><updated>2009-01-23T16:05:20.408Z</updated><category scheme='http://www.blogger.com/atom/ns#' term='SQL Server'/><title type='text'>Some SQL Snippets</title><content type='html'>&lt;span xmlns=""&gt;&lt;p&gt;Over time (don't ask how long – suffice to say I first used Microsoft SQL Server on OS/2) you pick up a fair amount of useful SQL Server knowledge. This post is intended to be a random collection of snippets that I use and remember, and I expect to add to the post periodically as I encounter further uses for SQL knowledge. So, in no particular order...&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;strong&gt;Finding SQL objects that contain a particular string&lt;/strong&gt;&lt;br /&gt;The definition of SQL objects can be accessed via the sys.syscomments view in the SQL database, and can be queried. The following example returns the name of objects that contain 'Test' somewhere within the definition. The object_name function is a quick way to get the name of an object from its id – the other way is to join to the sys.objects view.&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;span style="font-family:Courier New;"&gt;&lt;span style="font-size:85%;"&gt;select distinct object_name(id) from sys.syscomments where text like '%Test%'&lt;/span&gt;&lt;br /&gt;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;Note that this only works if the SQL object definition was not encrypted with the WITH ENCRYPTION option&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;strong&gt;Granting Permissions to a set of objects&lt;/strong&gt;&lt;br /&gt;I've yet to find a good user-interface in SQL for setting permissions on a set of objects quickly, so I tend to use SQL commands. The following procedure shows how to use a cursor to iterate through a set of objects and execute a dynamically-built GRANT statement on them&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;span style="font-family:Courier New;"&gt;&lt;span style="font-size:85%;"&gt;&lt;span style="color:blue;"&gt;declare&lt;/span&gt; cur &lt;span style="color:blue;"&gt;cursor&lt;/span&gt; &lt;span style="color:blue;"&gt;fast_forward&lt;/span&gt; &lt;/span&gt;&lt;span style="font-size:85%;color:blue;"&gt;for&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style="font-family:Courier New;"&gt;&lt;span style="font-size:85%;"&gt;&lt;span style="color:blue;"&gt;select&lt;/span&gt; &lt;span style="color:blue;"&gt;name&lt;/span&gt; &lt;span style="color:blue;"&gt;from&lt;/span&gt; &lt;span style="color:green;"&gt;sys.objects&lt;/span&gt;&lt;br /&gt;&lt;span style="color:blue;"&gt;where&lt;/span&gt; &lt;span style="color:blue;"&gt;type&lt;/span&gt; &lt;span style="color:gray;"&gt;=&lt;/span&gt; &lt;span style="color:red;"&gt;'V'&lt;/span&gt; &lt;span style="color:gray;"&gt;and&lt;/span&gt; &lt;span style="color:blue;"&gt;name&lt;/span&gt; &lt;span style="color:gray;"&gt;like&lt;/span&gt; &lt;span style="color:red;"&gt;'vw_%'&lt;/span&gt; &lt;/span&gt;&lt;span style="font-size:85%;color:green;"&gt;-- Get all views, beginning vw_&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style="font-family:Courier New;"&gt;&lt;span style="font-size:85%;"&gt;&lt;span style="color:blue;"&gt;declare&lt;/span&gt; @obj &lt;span style="color:blue;"&gt;sysname&lt;/span&gt;&lt;span style="color:gray;"&gt;,&lt;/span&gt; @sql &lt;span style="color:blue;"&gt;nvarchar&lt;/span&gt;&lt;span style="color:gray;"&gt;(&lt;/span&gt;2000&lt;/span&gt;&lt;span style="font-size:85%;color:gray;"&gt;)&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="font-family:Courier New;"&gt;&lt;span style="font-size:85%;"&gt;&lt;span style="color:blue;"&gt;open&lt;/span&gt; cur&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="font-family:Courier New;"&gt;&lt;span style="font-size:85%;"&gt;&lt;span style="color:blue;"&gt;fetch&lt;/span&gt; &lt;span style="color:blue;"&gt;next&lt;/span&gt; &lt;span style="color:blue;"&gt;from&lt;/span&gt; cur &lt;span style="color:blue;"&gt;into&lt;/span&gt; @obj&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="font-family:Courier New;"&gt;&lt;span style="font-size:85%;"&gt;&lt;span style="color:blue;"&gt;while&lt;/span&gt; &lt;span style="color:fuchsia;"&gt;@@fetch_status&lt;/span&gt; &lt;span style="color:gray;"&gt;=&lt;/span&gt; 0&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="font-family:Courier New;font-size:85%;color:blue;"&gt;begin&lt;br /&gt;&lt;/span&gt;&lt;span style="font-family:Courier New;"&gt;&lt;span style="font-size:85%;"&gt;&lt;span style="color:blue;"&gt;set&lt;/span&gt; @sql &lt;span style="color:gray;"&gt;=&lt;/span&gt; &lt;span style="color:red;"&gt;'GRANT SELECT ON '&lt;/span&gt; &lt;span style="color:gray;"&gt;+&lt;/span&gt; @obj &lt;span style="color:gray;"&gt;+&lt;/span&gt; &lt;span style="color:red;"&gt;' TO public'&lt;/span&gt;&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="font-family:Courier New;"&gt;&lt;span style="font-size:85%;color:green;"&gt;-- grant select permission to public&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="font-family:Courier New;"&gt;&lt;span style="font-size:85%;"&gt;&lt;span style="color:blue;"&gt;exec&lt;/span&gt; &lt;span style="color:gray;"&gt;(&lt;/span&gt;@sql&lt;/span&gt;&lt;span style="font-size:85%;color:gray;"&gt;)&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="font-family:Courier New;"&gt;&lt;span style="font-size:85%;"&gt;&lt;span style="color:blue;"&gt;fetch&lt;/span&gt; &lt;span style="color:blue;"&gt;next&lt;/span&gt; &lt;span style="color:blue;"&gt;from&lt;/span&gt; cur &lt;span style="color:blue;"&gt;into&lt;/span&gt; @obj&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="font-family:Courier New;font-size:85%;color:blue;"&gt;end&lt;br /&gt;&lt;/span&gt;&lt;span style="font-family:Courier New;"&gt;&lt;span style="font-size:85%;"&gt;&lt;span style="color:blue;"&gt;close&lt;/span&gt; cur&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="font-family:Courier New;"&gt;&lt;span style="font-size:85%;"&gt;&lt;span style="color:blue;"&gt;deallocate&lt;/span&gt; cur &lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;strong&gt;Outputting stored procedure information to a table&lt;br /&gt;&lt;/strong&gt;There are cases when you might want to use the results of a stored procedure in a table structure for future processing. There's not an EXECUTE INTO statement but you can use INSERT ... EXECUTE. You can also use this with dynamically constructed SQL, using EXECUTE (@sql). The following example uses both EXECUTE syntaxes, andshows how to iterate though the names of 'tables' from a linked server – this is used to query Excel spreadsheets where there is a dynamic range of identically structured worksheets&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;span style="font-family:Courier New;"&gt;&lt;span style="font-size:85%;"&gt;&lt;span style="color:blue;"&gt;create&lt;/span&gt;&lt;br /&gt;&lt;span style="color:blue;"&gt;table&lt;/span&gt; #excelsheets &lt;/span&gt;&lt;span style="font-size:85%;color:green;"&gt;-- Store names of spreadsheets in Excel&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="font-family:Courier New;font-size:85%;color:gray;"&gt;( &lt;/span&gt;&lt;span style="font-family:Courier New;"&gt;&lt;span style="font-size:85%;"&gt;TABLE_CAT &lt;span style="color:blue;"&gt;sysname&lt;/span&gt; &lt;/span&gt;&lt;span style="font-size:85%;color:gray;"&gt;null&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="font-family:Courier New;"&gt;&lt;span style="font-size:85%;"&gt;&lt;span style="color:gray;"&gt;,&lt;/span&gt;TABLE_SCHEM &lt;span style="color:blue;"&gt;sysname&lt;/span&gt; &lt;/span&gt;&lt;span style="font-size:85%;color:gray;"&gt;null&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="font-family:Courier New;"&gt;&lt;span style="font-size:85%;"&gt;&lt;span style="color:gray;"&gt;,&lt;/span&gt;TABLE_NAME &lt;span style="color:blue;"&gt;sysname&lt;/span&gt; &lt;span style="color:gray;"&gt;not&lt;/span&gt; &lt;/span&gt;&lt;span style="font-size:85%;color:gray;"&gt;null&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="font-family:Courier New;"&gt;&lt;span style="font-size:85%;"&gt;&lt;span style="color:gray;"&gt;,&lt;/span&gt;TABLE_TYPE &lt;span style="color:blue;"&gt;sysname&lt;/span&gt; &lt;/span&gt;&lt;span style="font-size:85%;color:gray;"&gt;null&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="font-family:Courier New;"&gt;&lt;span style="font-size:85%;"&gt;&lt;span style="color:gray;"&gt;,&lt;/span&gt;REMARKS &lt;span style="color:blue;"&gt;nvarchar&lt;/span&gt;&lt;span style="color:gray;"&gt;(&lt;/span&gt;255&lt;span style="color:gray;"&gt;)&lt;/span&gt; &lt;/span&gt;&lt;span style="font-size:85%;color:gray;"&gt;null &lt;/span&gt;&lt;/span&gt;&lt;span style="font-family:Courier New;font-size:85%;color:gray;"&gt;)&lt;br /&gt;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style="font-family:Courier New;"&gt;&lt;span style="font-size:85%;"&gt;&lt;span style="color:blue;"&gt;insert&lt;/span&gt; #excelsheets &lt;span style="color:blue;"&gt;execute&lt;/span&gt; &lt;span style="color:maroon;"&gt;sp_tables_ex&lt;/span&gt; &lt;span style="color:red;"&gt;'EXCELDYNAMIC'&lt;/span&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="font-size:85%;color:green;"&gt;-- EXCELDYNAMIC is a linked server&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style="font-family:Courier New;"&gt;&lt;span style="font-size:85%;"&gt;&lt;span style="color:blue;"&gt;create&lt;/span&gt; &lt;span style="color:blue;"&gt;table&lt;/span&gt; #tmp&lt;br /&gt;&lt;/span&gt;&lt;span style="font-size:85%;color:green;"&gt;-- Temporary storage of data, so results can be output as one result set&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="font-family:Courier New;font-size:85%;color:gray;"&gt;( &lt;/span&gt;&lt;span style="font-family:Courier New;"&gt;&lt;span style="font-size:85%;"&gt;TABLE_NAME &lt;/span&gt;&lt;span style="font-size:85%;color:blue;"&gt;sysname&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="font-family:Courier New;"&gt;&lt;span style="font-size:85%;"&gt;&lt;span style="color:gray;"&gt;,&lt;/span&gt;[Month] &lt;/span&gt;&lt;span style="font-size:85%;color:blue;"&gt;int&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="font-family:Courier New;"&gt;&lt;span style="font-size:85%;"&gt;&lt;span style="color:gray;"&gt;,&lt;/span&gt;[Target] &lt;span style="color:blue;"&gt;decimal&lt;/span&gt;&lt;span style="color:gray;"&gt;(&lt;/span&gt;10&lt;span style="color:gray;"&gt;,&lt;/span&gt;2&lt;/span&gt;&lt;span style="font-size:85%;color:gray;"&gt;) &lt;/span&gt;&lt;/span&gt;&lt;span style="font-family:Courier New;font-size:85%;color:gray;"&gt;)&lt;br /&gt;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style="font-family:Courier New;"&gt;&lt;span style="font-size:85%;"&gt;&lt;span style="color:blue;"&gt;declare&lt;/span&gt; cur &lt;span style="color:blue;"&gt;cursor&lt;/span&gt; &lt;span style="color:blue;"&gt;fast_forward&lt;/span&gt;&lt;br /&gt;&lt;span style="color:blue;"&gt;for&lt;/span&gt; &lt;span style="color:blue;"&gt;select&lt;/span&gt; TABLE_NAME &lt;span style="color:blue;"&gt;from&lt;/span&gt; #excelsheets&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="font-family:Courier New;"&gt;&lt;span style="font-size:85%;"&gt;&lt;span style="color:blue;"&gt;declare&lt;/span&gt; @tbl &lt;span style="color:blue;"&gt;sysname&lt;/span&gt;&lt;span style="color:gray;"&gt;,&lt;/span&gt; @sql &lt;span style="color:blue;"&gt;nvarchar&lt;/span&gt;&lt;span style="color:gray;"&gt;(&lt;/span&gt;4000&lt;/span&gt;&lt;span style="font-size:85%;color:gray;"&gt;)&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="font-family:Courier New;"&gt;&lt;span style="font-size:85%;"&gt;&lt;span style="color:blue;"&gt;open&lt;/span&gt; cur&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="font-family:Courier New;"&gt;&lt;span style="font-size:85%;"&gt;&lt;span style="color:blue;"&gt;fetch&lt;/span&gt; &lt;span style="color:blue;"&gt;next&lt;/span&gt; &lt;span style="color:blue;"&gt;from&lt;/span&gt; cur &lt;span style="color:blue;"&gt;into&lt;/span&gt; @tbl&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="font-family:Courier New;"&gt;&lt;span style="font-size:85%;"&gt;&lt;span style="color:blue;"&gt;while&lt;/span&gt; &lt;span style="color:fuchsia;"&gt;@@fetch_status&lt;/span&gt; &lt;span style="color:gray;"&gt;=&lt;/span&gt; 0&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="font-family:Courier New;font-size:85%;color:blue;"&gt;begin&lt;br /&gt;&lt;/span&gt;&lt;span style="font-family:Courier New;"&gt;&lt;span style="font-size:85%;color:green;"&gt;-- Build dynamic SQL statement. It would be nice to pass the statement as a parameter to OPENQUERY, but that's not permitted&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="font-family:Courier New;font-size:10;"&gt;&lt;span style="font-size:85%;"&gt;&lt;span style="color:blue;"&gt;set&lt;/span&gt; @sql &lt;span style="color:gray;"&gt;= &lt;/span&gt;&lt;span style="color:red;"&gt;'Select '''&lt;/span&gt; &lt;span style="color:gray;"&gt;+&lt;/span&gt; @tbl &lt;span style="color:gray;"&gt;+&lt;/span&gt; &lt;span style="color:red;"&gt;''' as TABLE_NAME, [Month], [Target] FROM EXCELDYNAMIC...['&lt;/span&gt; &lt;span style="color:gray;"&gt;+&lt;/span&gt; @tbl &lt;span style="color:gray;"&gt;+&lt;/span&gt; &lt;/span&gt;&lt;span style="font-size:85%;color:red;"&gt;']'&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="font-family:Courier New;"&gt;&lt;span style="font-size:85%;"&gt;&lt;span style="color:blue;"&gt;insert&lt;/span&gt; #tmp &lt;span style="color:blue;"&gt;exec&lt;/span&gt; &lt;span style="color:gray;"&gt;(&lt;/span&gt;@sql&lt;/span&gt;&lt;span style="font-size:85%;color:gray;"&gt;)&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="font-family:Courier New;"&gt;&lt;span style="font-size:85%;"&gt;&lt;span style="color:blue;"&gt;fetch&lt;/span&gt; &lt;span style="color:blue;"&gt;next&lt;/span&gt; &lt;span style="color:blue;"&gt;from&lt;/span&gt; cur &lt;span style="color:blue;"&gt;into&lt;/span&gt; @tbl&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="font-family:Courier New;font-size:85%;color:blue;"&gt;end&lt;br /&gt;&lt;/span&gt;&lt;span style="font-family:Courier New;font-size:85%;color:green;"&gt;-- Cleanup and output results&lt;br /&gt;&lt;/span&gt;&lt;span style="font-family:Courier New;"&gt;&lt;span style="font-size:85%;"&gt;&lt;span style="color:blue;"&gt;close&lt;/span&gt; cur&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="font-family:Courier New;"&gt;&lt;span style="font-size:85%;"&gt;&lt;span style="color:blue;"&gt;deallocate&lt;/span&gt; cur&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="font-family:Courier New;"&gt;&lt;span style="font-size:85%;"&gt;&lt;span style="color:blue;"&gt;select&lt;/span&gt; &lt;span style="color:gray;"&gt;*&lt;/span&gt; &lt;span style="color:blue;"&gt;from&lt;/span&gt; #tmp&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="font-family:Courier New;"&gt;&lt;span style="font-size:85%;"&gt;&lt;span style="color:blue;"&gt;drop&lt;/span&gt; &lt;span style="color:blue;"&gt;table&lt;/span&gt; #tmp&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="font-family:Courier New;"&gt;&lt;span style="font-size:85%;"&gt;&lt;span style="color:blue;"&gt;drop&lt;/span&gt; &lt;span style="color:blue;"&gt;table&lt;/span&gt; #excelsheets&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;/span&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/199106851038957806-5342478425734879384?l=mscrmuk.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://mscrmuk.blogspot.com/feeds/5342478425734879384/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=199106851038957806&amp;postID=5342478425734879384' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/199106851038957806/posts/default/5342478425734879384'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/199106851038957806/posts/default/5342478425734879384'/><link rel='alternate' type='text/html' href='http://mscrmuk.blogspot.com/2009/01/some-sql-snippets.html' title='Some SQL Snippets'/><author><name>David Jennaway</name><uri>http://www.blogger.com/profile/09695858105618938443</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-199106851038957806.post-8182416835700907810</id><published>2009-01-22T12:49:00.003Z</published><updated>2009-01-22T12:55:56.251Z</updated><category scheme='http://www.blogger.com/atom/ns#' term='Reports'/><category scheme='http://www.blogger.com/atom/ns#' term='CRM 4.0'/><title type='text'>Viewing CRM 4.0 Reports in Report Manager</title><content type='html'>Some of my previous posts (e.g. &lt;a href="http://mscrmuk.blogspot.com/2008/01/scheduling-and-emailing-reports-with.html"&gt;http://mscrmuk.blogspot.com/2008/01/scheduling-and-emailing-reports-with.html&lt;/a&gt;) were written based on CRM 3.0. Most of the reporting principles are similar for CRM 4.0, but the reports are configured slightly differently within Report Manager. The key differences are:&lt;br /&gt;&lt;ol&gt;&lt;li&gt;The CRM items are hidden by default in Report Manager. If you browse to the OrganisationName_MSCRM folder you won't see the hidden items. To see them, click on the 'Show Details' button on the right of the toolbar&lt;/li&gt;&lt;li&gt;The CRM 4.0 reports are stored in a sub-folder called 4.0. Click on this folder to see the reports&lt;/li&gt;&lt;li&gt;CRM 4.0 specifies the ReportID Guid as the report name, and the friendly name is now in the Description fields&lt;/li&gt;&lt;/ol&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/199106851038957806-8182416835700907810?l=mscrmuk.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://mscrmuk.blogspot.com/feeds/8182416835700907810/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=199106851038957806&amp;postID=8182416835700907810' title='3 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/199106851038957806/posts/default/8182416835700907810'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/199106851038957806/posts/default/8182416835700907810'/><link rel='alternate' type='text/html' href='http://mscrmuk.blogspot.com/2009/01/viewing-crm-40-reports-in-report.html' title='Viewing CRM 4.0 Reports in Report Manager'/><author><name>David Jennaway</name><uri>http://www.blogger.com/profile/09695858105618938443</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>3</thr:total></entry><entry><id>tag:blogger.com,1999:blog-199106851038957806.post-2934625078228166759</id><published>2009-01-15T22:02:00.003Z</published><updated>2009-01-15T22:04:42.621Z</updated><category scheme='http://www.blogger.com/atom/ns#' term='News'/><category scheme='http://www.blogger.com/atom/ns#' term='Announcement'/><category scheme='http://www.blogger.com/atom/ns#' term='CRM 4.0'/><title type='text'>CRM 4.0 Update Rollup 2</title><content type='html'>Update Rollup 2 for CRM 4.0 has been released, which is a pretty fast turnaround after the recent Update Rollup 1. Ive not had time to look at many of the fixes yet, but Ill add to this post if anything interesting crops up.&lt;br /&gt;&lt;br /&gt;Information about the hotfix: &lt;a href="http://support.microsoft.com/default.aspx?kbid=959419"&gt;http://support.microsoft.com/default.aspx?kbid=959419&lt;/a&gt;&lt;br /&gt;Download link: &lt;a href="http://www.microsoft.com/downloads/details.aspx?familyid=aa671769-61e9-45c4-919f-c88199aa4241&amp;amp;displaylang=en&amp;amp;tm"&gt;http://www.microsoft.com/downloads/details.aspx?familyid=aa671769-61e9-45c4-919f-c88199aa4241&amp;amp;displaylang=en&amp;amp;tm&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/199106851038957806-2934625078228166759?l=mscrmuk.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://mscrmuk.blogspot.com/feeds/2934625078228166759/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=199106851038957806&amp;postID=2934625078228166759' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/199106851038957806/posts/default/2934625078228166759'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/199106851038957806/posts/default/2934625078228166759'/><link rel='alternate' type='text/html' href='http://mscrmuk.blogspot.com/2009/01/crm-40-update-rollup-2.html' title='CRM 4.0 Update Rollup 2'/><author><name>David Jennaway</name><uri>http://www.blogger.com/profile/09695858105618938443</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-199106851038957806.post-4647563773347176727</id><published>2009-01-06T09:19:00.003Z</published><updated>2009-01-07T19:31:35.990Z</updated><category scheme='http://www.blogger.com/atom/ns#' term='Error Codes'/><category scheme='http://www.blogger.com/atom/ns#' term='Troubleshooting'/><title type='text'>CRM Error Codes</title><content type='html'>Something that's cropped up on a couple of CRM forums recently is how to get more information about a CRM error code. Error codes can be displayed in one of three formats:&lt;br /&gt;&lt;ol&gt;&lt;li&gt;Decimal, e.g. -2147206371&lt;/li&gt;&lt;li&gt;Hex with the 0x prefix - e.g. 0x80043B1D&lt;/li&gt;&lt;li&gt;Hex without the prefix - e.g. 80043B1D&lt;/li&gt;&lt;/ol&gt;&lt;p&gt;The CRM SDK documentation has a reasonable set of information about each error &lt;a href="http://msdn.microsoft.com/en-gb/library/bb930493.aspx"&gt;here&lt;/a&gt;, but only refers to error codes in the last of the listed formats (e.g. 80043B1D). To convert the second format to the third format, just remove the 0x prefix. &lt;/p&gt;&lt;p&gt;The easiest way to convert the first (decimal) format is to use the Windows calculator utility (calc.exe), as follows:&lt;/p&gt;&lt;ol&gt;&lt;li&gt;Open the calculator in scientific mode&lt;/li&gt;&lt;li&gt;Check the Decimal (Dec) option is set&lt;/li&gt;&lt;li&gt;Paste in the error code - e.g. -2147206371&lt;/li&gt;&lt;li&gt;Select 'Hex' to convert it to Hex, this will then look like: FFFFFFFF80043B1D&lt;/li&gt;&lt;li&gt;Remove the leading FFFFFFFF. You can then find the resulting code, e.g. 80043B1D, in the error codes&lt;/li&gt;&lt;/ol&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/199106851038957806-4647563773347176727?l=mscrmuk.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://mscrmuk.blogspot.com/feeds/4647563773347176727/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=199106851038957806&amp;postID=4647563773347176727' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/199106851038957806/posts/default/4647563773347176727'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/199106851038957806/posts/default/4647563773347176727'/><link rel='alternate' type='text/html' href='http://mscrmuk.blogspot.com/2009/01/crm-error-codes.html' title='CRM Error Codes'/><author><name>David Jennaway</name><uri>http://www.blogger.com/profile/09695858105618938443</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-199106851038957806.post-135821685318789950</id><published>2008-12-14T19:45:00.004Z</published><updated>2008-12-14T20:10:20.599Z</updated><category scheme='http://www.blogger.com/atom/ns#' term='Customisation'/><category scheme='http://www.blogger.com/atom/ns#' term='Deployment'/><title type='text'>Invalid Argument error when importing unpublished entities</title><content type='html'>If, like I did recently, you export an entity before it has been published, you will get an 'Invalid Argument' error when importing the entity if it has any relationships.&lt;br /&gt;&lt;br /&gt;The reason for this is that the relationship attribute will have no display name, which results in the error. The simplest solution would be to go back to the original deployment, publish the entity, then export again. But, if that's not an option, you can fix the problem within the exported xml as follows:&lt;br /&gt;&lt;br /&gt;The invalid relationship xml will look like the following:&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family:courier new;font-size:85%;"&gt;&amp;lt;field name=&amp;quot;pjv_targetid&amp;quot; requiredlevel=&amp;quot;required&amp;quot; imemode=&amp;quot;auto&amp;quot; lookupstyle=&amp;quot;single&amp;quot; lookupbrowse=&amp;quot;0&amp;quot;&amp;gt;&lt;br /&gt;&amp;lt;displaynames /&amp;gt;&lt;br /&gt;&amp;lt;/field&amp;gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;The problem is that the displaynames element is blank. This can be changed to something like the following&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family:courier new;font-size:85%;"&gt;&amp;lt;displaynames&amp;gt;&lt;br /&gt;&amp;lt;displayname description=&amp;quot;Target&amp;quot; languagecode=&amp;quot;1033&amp;quot; /&amp;gt;&lt;br /&gt;&amp;lt;/displaynames&amp;gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;The languagecode attribute will need to be set to the correct value for your deployment. Many other elements will have this value set in the customizations.xml file&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/199106851038957806-135821685318789950?l=mscrmuk.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://mscrmuk.blogspot.com/feeds/135821685318789950/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=199106851038957806&amp;postID=135821685318789950' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/199106851038957806/posts/default/135821685318789950'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/199106851038957806/posts/default/135821685318789950'/><link rel='alternate' type='text/html' href='http://mscrmuk.blogspot.com/2008/12/invalid-argument-error-when-importing.html' title='Invalid Argument error when importing unpublished entities'/><author><name>David Jennaway</name><uri>http://www.blogger.com/profile/09695858105618938443</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-199106851038957806.post-4231377561592659722</id><published>2008-11-24T16:37:00.001Z</published><updated>2008-11-24T17:56:46.484Z</updated><category scheme='http://www.blogger.com/atom/ns#' term='MVP'/><title type='text'>More CRM MVPs</title><content type='html'>This a belated welcome to all recently awarded CRM MVPs. At the time of writing there are now 29 of us &lt;a href="https://mvp.support.microsoft.com/communities/mvp.aspx?product=1&amp;amp;competency=Dynamics+CRM"&gt;worldwide&lt;/a&gt;. I've updated the blog list to reflect the new MVPs - as far as I can tell these are up-to-date, but let me know if not&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/199106851038957806-4231377561592659722?l=mscrmuk.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://mscrmuk.blogspot.com/feeds/4231377561592659722/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=199106851038957806&amp;postID=4231377561592659722' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/199106851038957806/posts/default/4231377561592659722'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/199106851038957806/posts/default/4231377561592659722'/><link rel='alternate' type='text/html' href='http://mscrmuk.blogspot.com/2008/11/more-crm-mvps.html' title='More CRM MVPs'/><author><name>David Jennaway</name><uri>http://www.blogger.com/profile/09695858105618938443</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-199106851038957806.post-542922281488096652</id><published>2008-11-19T16:19:00.004Z</published><updated>2008-11-19T16:37:22.092Z</updated><category scheme='http://www.blogger.com/atom/ns#' term='Reports'/><category scheme='http://www.blogger.com/atom/ns#' term='Code Gallery'/><category scheme='http://www.blogger.com/atom/ns#' term='CRM 4.0'/><title type='text'>Using the Reporting Services Execution Log with CRM 4.0</title><content type='html'>I've contributed another article to the &lt;a href="http://blogs.msdn.com/crm/archive/2008/11/19/auditing-report-execution-using-the-reportserver-database.aspx"&gt;Microsoft CRM Team Blog&lt;/a&gt;. This is about making good use of the Reporting Services Execution Log with CRM 4.0 reports.&lt;br /&gt;&lt;br /&gt;In the past I've found the execution log to be very useful for getting statistics on when reports were run, and the overall performance. However, CRM 4.0 introduced some complexities around using the log effectively. One issue is that the report name is not stored in Reporting Services, and another issue is that, if you use the Reporting Services connector, then the user name is not recorded in the execution log. The &lt;a href="http://blogs.msdn.com/crm/archive/2008/11/19/auditing-report-execution-using-the-reportserver-database.aspx"&gt;article &lt;/a&gt;describes how to resolve these issues.&lt;br /&gt;&lt;br /&gt;I've added some support files for this to the &lt;a href="http://code.msdn.microsoft.com/RSExecutionLogCRM40"&gt;MSDN Code gallery&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/199106851038957806-542922281488096652?l=mscrmuk.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://mscrmuk.blogspot.com/feeds/542922281488096652/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=199106851038957806&amp;postID=542922281488096652' title='3 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/199106851038957806/posts/default/542922281488096652'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/199106851038957806/posts/default/542922281488096652'/><link rel='alternate' type='text/html' href='http://mscrmuk.blogspot.com/2008/11/using-reporting-services-execution-log.html' title='Using the Reporting Services Execution Log with CRM 4.0'/><author><name>David Jennaway</name><uri>http://www.blogger.com/profile/09695858105618938443</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>3</thr:total></entry><entry><id>tag:blogger.com,1999:blog-199106851038957806.post-1978168517257778202</id><published>2008-11-17T17:51:00.003Z</published><updated>2008-11-17T18:06:19.613Z</updated><category scheme='http://www.blogger.com/atom/ns#' term='SQL Server 2008'/><category scheme='http://www.blogger.com/atom/ns#' term='Reports'/><title type='text'>Report Builder 2.0 for SQL 2008 - No need for a report model</title><content type='html'>I've always considered the Report Builder tool that ships with SQL Reporting Services to be a good tool for generating reports without SQL knowledge, and in the context of CRM it's much more powerful than the CRM 4.0 Report Wizard.&lt;br /&gt;&lt;br /&gt;One drawback of the Report Builder for SQL 2005 was that it needed a Report Model to abstract the underlying data, and Report Models are not dynamic (see below for why this was a pain). One major advantage of SQL 2008 is that it ships with a new version of Report Builder, &lt;a href="http://www.microsoft.com/downloads/details.aspx?FamilyID=9f783224-9871-4eea-b1d5-f3140a253db6&amp;amp;displaylang=en"&gt;Report Builder 2.0&lt;/a&gt;, that allows direct connections to the SQL database. This will make it a lot more useful in CRM deployments, especially when your schema changes. A good overview of the use of Report Builder 2.0 can be found &lt;a href="http://blogs.msdn.com/crm/archive/2008/11/10/reports-for-crm-4-0-using-sql-server-2008-and-report-builder-2-0.aspx"&gt;here&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;&lt;strong&gt;Why Report Models are a pain with CRM&lt;/strong&gt;&lt;br /&gt;Earlier, I said 'Report Models are not dynamic' Put another way, if you built your Report Model on your CRM database, then added a new attribute to an entity, you would have to regenerate your Report Model. In itself this wouldn't be too bad, but when you generate a Report Model from a filtered view you end up with a lot of unnecessary attributes, and a fair bit of work to do to provide a sensible set of attributes in the Report Model. To get round this we wrote a set of tools to manipulate the Report Model files directly and automate a lot of the rebuilding. This saved a lot of time, but still required a deployment process to allow reports against new attributes or entities.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/199106851038957806-1978168517257778202?l=mscrmuk.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://mscrmuk.blogspot.com/feeds/1978168517257778202/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=199106851038957806&amp;postID=1978168517257778202' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/199106851038957806/posts/default/1978168517257778202'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/199106851038957806/posts/default/1978168517257778202'/><link rel='alternate' type='text/html' href='http://mscrmuk.blogspot.com/2008/11/report-builder-20-for-sql-2008-no-need.html' title='Report Builder 2.0 for SQL 2008 - No need for a report model'/><author><name>David Jennaway</name><uri>http://www.blogger.com/profile/09695858105618938443</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-199106851038957806.post-574155542439265971</id><published>2008-10-22T15:35:00.002+01:00</published><updated>2008-10-22T16:02:18.262+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Plugin'/><category scheme='http://www.blogger.com/atom/ns#' term='Workflow'/><category scheme='http://www.blogger.com/atom/ns#' term='CRM 4.0'/><title type='text'>Deploying Custom Workflow Activities - Add authorizedType</title><content type='html'>This is the first of an intended two posts about registering custom workflow activities, and regards the initial deployment; a subsequent post will address updates and versioning issues.&lt;br /&gt;&lt;br /&gt;The &lt;a href="http://msdn.microsoft.com/en-gb/library/cc151144.aspx"&gt;CRM 4.0 SDK&lt;/a&gt; gives a reasonable overview of registering a custom workflow activity, covering the following steps:&lt;br /&gt;&lt;ol&gt;&lt;li&gt;Building / Deploying a plugin registration tool&lt;/li&gt;&lt;li&gt;Registering the assembly&lt;/li&gt;&lt;li&gt;Adding referenced assemblies to the GAC&lt;/li&gt;&lt;li&gt;Stopping and restarting the CRM Async Service&lt;/li&gt;&lt;/ol&gt;&lt;p&gt;However, one important point is omitted - adding your activity classes as an authorizedType within the web.config file. Workflow in CRM 4.0 uses the Windows Workflow Foundation (WWF) which, as a relatively new .Net technology, includes a reasonable security model to reduce the risk of malicious code being deployed within it.&lt;/p&gt;&lt;p&gt;The security model in WWF will only allow a permitted list of classes to be called as custom activities. In CRM 4.0 this list is stored in the web.config file in the root of the CRM website, and looks like this:&lt;/p&gt;&lt;p&gt;&lt;span style="font-family:courier new;font-size:85%;"&gt;&amp;lt;System.Workflow.ComponentModel.WorkflowCompiler&amp;gt;&lt;br /&gt; &amp;lt;authorizedTypes&amp;gt;&lt;br /&gt;  &amp;lt;authorizedType Assembly=&amp;quot;System.Workflow.Activities, Version=3.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35&amp;quot; Namespace=&amp;quot;System.Workflow.Activities&amp;quot; TypeName=&amp;quot;IfElseActivity&amp;quot; Authorized=&amp;quot;True&amp;quot;/&amp;gt;&lt;br /&gt;  &amp;lt;authorizedType Assembly=&amp;quot;System.Workflow.Activities, Version=3.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35&amp;quot; Namespace=&amp;quot;System.Workflow.Activities&amp;quot; TypeName=&amp;quot;IfElseBranchActivity&amp;quot; Authorized=&amp;quot;True&amp;quot;/&amp;gt;&lt;br /&gt; &amp;lt;/authorizedTypes&amp;gt;&lt;br /&gt;&amp;lt;/System.Workflow.ComponentModel.WorkflowCompiler&amp;gt;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;For your custom activity to be permitted, you have to add an entry as an &lt;authorizedtype&gt; element; for example:&lt;/p&gt;&lt;p&gt;&lt;span style="font-family:courier new;font-size:85%;"&gt;&amp;lt;authorizedType Assembly=&amp;quot;MyAssembly, Version=4.0.0.0, Culture=neutral, PublicKeyToken=&amp;quot;7766554433221100&amp;quot; Namespace=&amp;quot;MyActivities&amp;quot; TypeName=&amp;quot;*&amp;quot; Authorized=&amp;quot;True&amp;quot;/&amp;gt;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;Note that I've used an asterisk (*) to indicate all classes in the given namespace and assembly are permitted; you could reference an individual class if you prefer. Also note that the assembly is referenced by the strong name, as the assembly has been digitally signed when it was compiled.&lt;/p&gt;&lt;p&gt;This raises the question 'what happens if you don't do this step?' If you don't, you can deploy the workflow plugin, and use it in a workflow rule, but you get an error when you try to publish the workflow rule. Unfortunately the message you get is unhelpful; it's a variation of 'An unexpected error has occurred'. If you dig deeper, and enable tracing on the server, you do get a useful message in the w3wp log, such as the following:&lt;/p&gt;&lt;p&gt;&lt;span style="font-family:courier new;font-size:85%;"&gt;Workflow compilation failed:WF363: Type MyActivities.Demo, MyAssembly, Version=4.0.0.0, Culture=neutral, PublicKeyToken="7766554433221100 is not marked as authorized in the application configuration file.&lt;/span&gt;&lt;/p&gt;&lt;p&gt;Once you find it, this message is pretty useful, as it tells you most of the problem, and also references the assembly in exactly the same way as you need to in web.config&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/199106851038957806-574155542439265971?l=mscrmuk.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://mscrmuk.blogspot.com/feeds/574155542439265971/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=199106851038957806&amp;postID=574155542439265971' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/199106851038957806/posts/default/574155542439265971'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/199106851038957806/posts/default/574155542439265971'/><link rel='alternate' type='text/html' href='http://mscrmuk.blogspot.com/2008/10/deploying-custom-workflow-activities.html' title='Deploying Custom Workflow Activities - Add authorizedType'/><author><name>David Jennaway</name><uri>http://www.blogger.com/profile/09695858105618938443</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-199106851038957806.post-3097058746805867573</id><published>2008-10-15T14:19:00.004+01:00</published><updated>2008-10-15T14:22:05.719+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Reports'/><category scheme='http://www.blogger.com/atom/ns#' term='CRM 4.0'/><title type='text'>Report Wizard: Query execution failed for data set 'DSMain'</title><content type='html'>There is a problem with the CRM 4.0 Report Wizard that can result in an error like the following:&lt;br /&gt;&lt;span style="font-family:courier new;font-size:85%;"&gt;An error has occurred during report processing.Query execution failed for data set 'DSMain'.The column 'accountid' was specified multiple times for 'account0'. The column 'accountid' was specified multiple times for 'opportunity1'.&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;strong&gt;Explanation of the problem&lt;/strong&gt;&lt;br /&gt;The ultimate cause is how the Report Wizard stores the Filtering Criteria for reports based on the account entity. The Report Wizard stores the query for any criteria as a combination of all fields in the account entity, and all fields in the related primary contact. When the report is run, the SQL query attempts to use the results of the following (or similar) as a table alias:&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family:courier new;font-size:85%;"&gt;select DISTINCT account0.*, accountprimarycontactidcontactcontactid.* from FilteredAccount as account0 left outer join FilteredContact as accountprimarycontactidcontactcontactid on (account0.primarycontactid  =  accountprimarycontactidcontactcontactid.contactid) where (account0.statecode = 0)&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;This returns two fields called accountid (one from the account entity, and one from the contact), which breaks the main SQL query for the report, and gives the error above.&lt;br /&gt;&lt;br /&gt;&lt;strong&gt;Resolution&lt;/strong&gt;&lt;br /&gt;The way to resolve this is to ensure that, when you create the report with the Report Wizard, you do not specify any criteria for the account entity. This will cause the Report Wizard to store the query as solely against the account entity. Once you’ve created the report, you can happily edit the default filter to whatever you want, and the report will work fine – the key factor is not having any criteria when you first create the report.&lt;br /&gt;&lt;br /&gt;Unfortunately there’s not an easy way to fix existing reports with this problem – it should be possible to edit the data in the DefaultFilter column in the reportbase table, but this is unsupported. I’d suggest in this scenario that you’re best off recreating the report from scratch&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/199106851038957806-3097058746805867573?l=mscrmuk.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://mscrmuk.blogspot.com/feeds/3097058746805867573/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=199106851038957806&amp;postID=3097058746805867573' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/199106851038957806/posts/default/3097058746805867573'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/199106851038957806/posts/default/3097058746805867573'/><link rel='alternate' type='text/html' href='http://mscrmuk.blogspot.com/2008/10/report-wizard-query-execution-failed.html' title='Report Wizard: Query execution failed for data set &apos;DSMain&apos;'/><author><name>David Jennaway</name><uri>http://www.blogger.com/profile/09695858105618938443</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-199106851038957806.post-3734958149880739464</id><published>2008-10-11T10:11:00.001+01:00</published><updated>2008-10-15T14:23:36.045+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='SQL Server'/><category scheme='http://www.blogger.com/atom/ns#' term='Installation'/><title type='text'>SQL Server: The instance name must be the same as computer name</title><content type='html'>This is something I’ve posted about on newsgroups, but one of my colleagues encountered it recently, and I think it deserves a blog entry.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;The CRM Environment Diagnostics Wizard may throw the error ‘The instance name must be the same as computer name’. The most common cause of this is if the SQL Server has been renamed after SQL Server was installed. The reason is that, at installation time, SQL Server stores the computer name in a system table, sysservers. This information is not updated when the computer is renamed, and the error from the CRM Environment Diagnostics Wizard indicates that the entry in sysservers does not match the current computer name.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;You can diagnose and resolve this by using some SQL system stored procedures. One of them lists the data in sysservers, the other 2 allow you to modify the data to reflect the current machine name.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;To check if this is the issue, use SQL Management Studio (or Query Analyzer for SQL 2000) to execute the following query:&lt;br /&gt;&lt;span style="font-family:courier new;font-size:85%;"&gt;sp_helpserver&lt;/span&gt;&lt;br /&gt;This will return output like the following:&lt;br /&gt;&lt;span style="font-size:85%;"&gt;Name,network_name,status,id,collation_name,connect_timeout,query_timeout&lt;br /&gt;ORGNAME,ORIGNAME,rpc,rpc out,use remote collation,0,null,0,0&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;If the value in the name column does not match the current computer name, then you have to use the following SQL stored procedures to fix the problem. Note that sp_helpserver normally returns one record, but can return more records if you have configured linked servers. If this is the case, it is the row with id=0 that matters.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;To change the information you have to first remove the incorrect record, then add the correct one, with the following queries:&lt;br /&gt;&lt;span style="font-family:courier new;font-size:85%;"&gt;sp_dropserver ‘ORIGNAME’ &lt;/span&gt;-- where ORIGNAME is the name returned by sp_helpserver&lt;br /&gt;&lt;span style="font-family:courier new;font-size:85%;"&gt;sp_addserver ‘CURRENTNAME’, ‘LOCAL’&lt;/span&gt; – where CURRENTNAME is the current computer name&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;If you use named instances, refer to them in the form SERVERNAME\INSTANCENAME. It may then be necessary to restart SQL Server after these changes, but I'm not sure of this. It can't harm though if you can.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;There is a KB article about this &lt;a href="http://support.microsoft.com/kb/857505"&gt;here&lt;/a&gt;. This descibes a similar solution, but be warned of a couple of minor issues with the solution - it fails to specify that quotes are required around the parameters to sp_dropserver and sp_addserver, and I have a feeling (though can't provide concrete evidence) that running sp_helpserver is more reliable than select @@servername.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/199106851038957806-3734958149880739464?l=mscrmuk.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://mscrmuk.blogspot.com/feeds/3734958149880739464/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=199106851038957806&amp;postID=3734958149880739464' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/199106851038957806/posts/default/3734958149880739464'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/199106851038957806/posts/default/3734958149880739464'/><link rel='alternate' type='text/html' href='http://mscrmuk.blogspot.com/2008/10/sql-server-instance-name-must-be-same.html' title='SQL Server: The instance name must be the same as computer name'/><author><name>David Jennaway</name><uri>http://www.blogger.com/profile/09695858105618938443</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-199106851038957806.post-4080099416497240739</id><published>2008-10-10T10:05:00.002+01:00</published><updated>2008-10-10T10:09:33.168+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='SSIS'/><category scheme='http://www.blogger.com/atom/ns#' term='Excel'/><category scheme='http://www.blogger.com/atom/ns#' term='SQL Server'/><title type='text'>Excel Data Type issues with OLEDB and SSIS</title><content type='html'>&lt;div&gt;I recently met an annoying issue when reading Excel data in SSIS. The issue was when a column contained a mix of data-types – in this case string and numeric information. The problem comes from the fact that Excel does not have a concept of column data-types, and the issues in SSIS come from the way the OLE-DB provider for Excel attempts to resolve this.&lt;/div&gt;&lt;div&gt;&lt;/div&gt;&lt;br /&gt;&lt;div&gt;I found the information I needed in an excellent blog post &lt;a href="http://blog.lab49.com/archives/196"&gt;here&lt;/a&gt;, and I won’t repeat the content here. One additional point that is specific to SSIS is how to add the IMEX extended property to the connection string. In Visual Studio 2005 (I’ve not checked other versions) you can only do this by editing the ConnectionString property directly in the Properties window – the dialog box doesn’t offer this option. See the image below.&lt;/div&gt;&lt;br /&gt;&lt;div&gt;&lt;img id="BLOGGER_PHOTO_ID_5255449346486861058" style="DISPLAY: block; MARGIN: 0px auto 10px; WIDTH: 647px; CURSOR: hand; HEIGHT: 55px; TEXT-ALIGN: center" height="55" alt="" src="http://4.bp.blogspot.com/_q3OlQztdu1Y/SO8bVghofQI/AAAAAAAAAA8/vjDMhPShm9E/s320/Excel_IMEX.jpg" width="454" border="0" /&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/199106851038957806-4080099416497240739?l=mscrmuk.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://mscrmuk.blogspot.com/feeds/4080099416497240739/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=199106851038957806&amp;postID=4080099416497240739' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/199106851038957806/posts/default/4080099416497240739'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/199106851038957806/posts/default/4080099416497240739'/><link rel='alternate' type='text/html' href='http://mscrmuk.blogspot.com/2008/10/excel-data-type-issues-with-oledb-and.html' title='Excel Data Type issues with OLEDB and SSIS'/><author><name>David Jennaway</name><uri>http://www.blogger.com/profile/09695858105618938443</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://4.bp.blogspot.com/_q3OlQztdu1Y/SO8bVghofQI/AAAAAAAAAA8/vjDMhPShm9E/s72-c/Excel_IMEX.jpg' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-199106851038957806.post-3332032996753193223</id><published>2008-09-14T16:21:00.001+01:00</published><updated>2008-09-14T16:21:00.749+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='SQL Server'/><title type='text'>SQL Linked Server by IP Address</title><content type='html'>&lt;div&gt;A recent SQL Server problem I had was to setup a Linked Server from one SQL 2005 server to another, with a couple of specific requirements: The destination server could only be accessed by IP address, but the customer wanted to be able to identify the server by name in SQL code.&lt;br /&gt;&lt;/div&gt;&lt;br /&gt;&lt;div&gt;This should have been simple, but as I'm blogging about it you may be able to guess that it wasn't quite so straightforward...&lt;/div&gt;&lt;br /&gt;&lt;div&gt;It started promisingly. This is how to add a SQL linked server via SQL Management Studio if you can access it by name:&lt;/div&gt;&lt;br /&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;img id="BLOGGER_PHOTO_ID_5244050120678481794" style="DISPLAY: block; MARGIN: 0px auto 10px; CURSOR: hand; TEXT-ALIGN: center" alt="" src="http://3.bp.blogspot.com/_q3OlQztdu1Y/SMabzPNin4I/AAAAAAAAAAc/4x7zg63Ke6I/s320/LinkedServer_SQL.jpg" border="0" /&gt; If you want to specify the other parameters, it seemed to make sense to specify 'Other data source', and 'Microsoft OLE DB Provider for SQL Server':&lt;img id="BLOGGER_PHOTO_ID_5244050817396058962" style="DISPLAY: block; MARGIN: 0px auto 10px; CURSOR: hand; TEXT-ALIGN: center" alt="" src="http://1.bp.blogspot.com/_q3OlQztdu1Y/SMacbyr9K1I/AAAAAAAAAAk/KTsH_k_kRSE/s320/LinkedServer_SQL_Other.jpg" border="0" /&gt; That was easy... till I tried to query the server, which failed with a timeout. Then, when I opended the properties of the Linked Server, the Data Source information had gone:&lt;br /&gt;&lt;br /&gt;&lt;p&gt;&lt;img id="BLOGGER_PHOTO_ID_5244052434599084658" style="DISPLAY: block; MARGIN: 0px auto 10px; CURSOR: hand; TEXT-ALIGN: center" alt="" src="http://1.bp.blogspot.com/_q3OlQztdu1Y/SMad57PNAnI/AAAAAAAAAAs/Jsu2ziTQoog/s320/LinkedServer_SQL_Other_Revert.jpg" border="0" /&gt;&lt;br /&gt;&lt;/p&gt;If you specify the OLE DB Provider for SQL Server, then the Data Source is lost.&lt;br /&gt;&lt;br /&gt;&lt;p&gt;To get round this, I had to add the linked server via the sp_addlinkedserver system stored procedure, and specify a provider of 'SQLNCLI' (the native SQL client), and not SQLOLEDB (the OleDb provider for SQL Server). The following example shows how to do it.&lt;/p&gt;&lt;p&gt;sp_addlinkedserver&lt;br /&gt;@server = 'REMOTESQL' -- Name used in queries&lt;br /&gt;, @provider = 'SQLNCLI' -- SQL Native Client&lt;br /&gt;, @srvproduct = '' -- Cannot be null, and if 'SQL Server' then you cannot specify the datasrc&lt;br /&gt;, @datasrc = 'SERVER=10.0.0.1' -- IP Address of the server&lt;br /&gt;, @catalog = 'MYDB' -- database name on the server, if required&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/199106851038957806-3332032996753193223?l=mscrmuk.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://mscrmuk.blogspot.com/feeds/3332032996753193223/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=199106851038957806&amp;postID=3332032996753193223' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/199106851038957806/posts/default/3332032996753193223'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/199106851038957806/posts/default/3332032996753193223'/><link rel='alternate' type='text/html' href='http://mscrmuk.blogspot.com/2008/09/sql-linked-server-by-ip-address.html' title='SQL Linked Server by IP Address'/><author><name>David Jennaway</name><uri>http://www.blogger.com/profile/09695858105618938443</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://3.bp.blogspot.com/_q3OlQztdu1Y/SMabzPNin4I/AAAAAAAAAAc/4x7zg63Ke6I/s72-c/LinkedServer_SQL.jpg' height='72' width='72'/><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-199106851038957806.post-4905314295119704753</id><published>2008-09-09T15:34:00.005+01:00</published><updated>2008-09-12T22:35:34.823+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Callouts'/><category scheme='http://www.blogger.com/atom/ns#' term='CRM 3.0'/><title type='text'>Notification.asmx</title><content type='html'>While investigating a stability issue on a customer's CRM 3.0 Server recently, I figured I needed to identify what the calls to notification.asmx were. These calls are made every 30 seconds, and can be identified in the IIS logs as follows:&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;2008-09-08 11:11:44 192.168.2.107 POST /MSCRMServices/notification.asmx&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;Each call results in a SQL query to the MSCRM database, like the following:&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;exec sp_executesql N'Select EventId, EventData, CreatedOn From Notification Where CreatedOn &gt; @CreatedOn', &lt;a href="mailto:N"&gt;mailto:N&lt;/a&gt; datetime', @CreatedOn = 'Aug 14 2008 3:08:02:370PM'&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;A reasonably detailed check on the internet suggested nobody else knew what notification.asmx was doing, or if they did, they weren't telling.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;I won't bore you with the details of how I found it, other than my past experience with CRM 1.2 helped, but in case you're interested, it's used for processing CRM 1.2-style callouts. Unfortunately this had noting to do with the ultimate problem, but at least I now know to eliminate it from my enquiries.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/199106851038957806-4905314295119704753?l=mscrmuk.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://mscrmuk.blogspot.com/feeds/4905314295119704753/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=199106851038957806&amp;postID=4905314295119704753' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/199106851038957806/posts/default/4905314295119704753'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/199106851038957806/posts/default/4905314295119704753'/><link rel='alternate' type='text/html' href='http://mscrmuk.blogspot.com/2008/09/notificationasmx.html' title='Notification.asmx'/><author><name>David Jennaway</name><uri>http://www.blogger.com/profile/09695858105618938443</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-199106851038957806.post-3691254796122167663</id><published>2008-09-08T08:44:00.004+01:00</published><updated>2008-09-08T09:10:22.583+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Client Code'/><category scheme='http://www.blogger.com/atom/ns#' term='Customisation'/><category scheme='http://www.blogger.com/atom/ns#' term='CRM 4.0'/><title type='text'>Cannot set Price List when Previewing Form</title><content type='html'>I came across a quirk of the Preview functionality of the CRM 4.0 Form Editor. When previewing an entity with a relationship to the price list - e.g. opportunity, quote - the Price List lookup doesn't display any price lists, so you can't set one. As far as I can tell this is due to the multi-currency functionality - the lookup normally filters by currency, but this logic is missing from the preview. Manually setting a currency in the preview form doesn't help.&lt;br /&gt;&lt;br /&gt;This caused me an issue once when testing client script, but there's a fairly simple way around it - you can still set the price list code. This is something I commonly do if the customer has just the one price list. Here is some sample code I use in the form load event:&lt;br /&gt;&lt;br /&gt;&lt;span style="font-size:85%;"&gt;if (crmForm.FormType == 1)&lt;/span&gt;&lt;br /&gt;&lt;span style="font-size:85%;"&gt;{&lt;/span&gt;&lt;br /&gt;&lt;span style="font-size:85%;"&gt;var o = new Object(); &lt;/span&gt;&lt;br /&gt;&lt;span style="font-size:85%;"&gt;o.id = '{A0E0F731-E96C-DD11-AABD-0003FF74F5B7}'; /* Change this Guid */&lt;/span&gt;&lt;br /&gt;&lt;span style="font-size:85%;"&gt;o.typename = 'pricelevel';&lt;/span&gt;&lt;br /&gt;&lt;span style="font-size:85%;"&gt;o.name = 'Standard Price List';&lt;/span&gt;&lt;br /&gt;&lt;span style="font-size:85%;"&gt;var a = new Array();&lt;/span&gt;&lt;br /&gt;&lt;span style="font-size:85%;"&gt;a[0] = o;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-size:85%;"&gt;crmForm.all.pricelevelid.DataValue = a;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-size:85%;"&gt;}&lt;/span&gt;&lt;br /&gt;&lt;span style="font-size:85%;"&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-size:85%;"&gt;Note that this is only appropriate in a single-currency scenario. If you have multiple currencies, you'd be better off putting the code in the change event for the currency field, and picking an appropriate price list for the currency.&lt;/span&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/199106851038957806-3691254796122167663?l=mscrmuk.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://mscrmuk.blogspot.com/feeds/3691254796122167663/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=199106851038957806&amp;postID=3691254796122167663' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/199106851038957806/posts/default/3691254796122167663'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/199106851038957806/posts/default/3691254796122167663'/><link rel='alternate' type='text/html' href='http://mscrmuk.blogspot.com/2008/09/cannot-set-price-list-when-previewing.html' title='Cannot set Price List when Previewing Form'/><author><name>David Jennaway</name><uri>http://www.blogger.com/profile/09695858105618938443</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-199106851038957806.post-6071216783116911436</id><published>2008-09-04T11:47:00.004+01:00</published><updated>2010-11-24T08:12:07.265Z</updated><category scheme='http://www.blogger.com/atom/ns#' term='Configuration'/><category scheme='http://www.blogger.com/atom/ns#' term='SQL Server'/><category scheme='http://www.blogger.com/atom/ns#' term='CRM 4.0'/><category scheme='http://www.blogger.com/atom/ns#' term='CRM 3.0'/><title type='text'>SQL Timeouts in CRM - Generic SQL Error</title><content type='html'>I often find myself answering forum posts about SQL errors (the most common error is 'Generic SQL Error'). By far the most likely cause of this error is a timeout when accessing SQL server. If this is a case your options are to increase the timeout, or to try and ensure the query does not take so long.&lt;br /&gt;&lt;br /&gt;&lt;strong&gt;Increase the Timeout&lt;/strong&gt;&lt;br /&gt;The SQL timeout is controlled by a registry value on each CRM server:&lt;br /&gt;&lt;br /&gt;HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\MSCRM\OLEDBTimeout&lt;br /&gt;&lt;br /&gt;This value does not exist by default, and if it does not exist then the default value will be 30 seconds. To change it, add the registry value (of type DWORD), and put in the value you want (measured in seconds). Then you have to recycle the CrmAppPool application pool for the change to take effect (this is a step most Microsoft documentation omits to mention); do this we IISReset, or less drastically via &lt;a href="http://mscrmuk.blogspot.com/2007/11/redeploying-callouts-by-recycling.html"&gt;iisapp.vbs&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;strong&gt;Reduce the time taken by the query&lt;/strong&gt;&lt;br /&gt;This may not be so simple, as you may have little control over the query. If the query is run as a result of your code (e.g. through a RetrieveMultiple request), then you may be able to make useful changes. For example, RetrieveMultiple requests on activities are not necessarily processed very efficiently by CRM (the problem is the way that is accesses the activity parties), and I've been able to make significant improvements by using a FetchXml query instead, which gives closer control over the joins used.&lt;br /&gt;&lt;br /&gt;Otherwise, the other query optimisation option is to add indexes in SQL Server. This is a massive topic in its own right (I used to deliver 5 day training courses just on this topic), so I'm not going to go into detail here. The general steps are:&lt;br /&gt;&lt;ol&gt;&lt;li&gt;Identify the SQL query that takes the time - I use CRM tracing for this - &lt;a href="http://support.microsoft.com/kb/907490"&gt;http://support.microsoft.com/kb/907490&lt;/a&gt;&lt;/li&gt;&lt;li&gt;Use the SQL Management Studio and SQL Profiler to identify the query execution plan and to get recommendations about possible indexes&lt;/li&gt;&lt;/ol&gt;&lt;p&gt;There are 2 important things to take into account:&lt;/p&gt;&lt;ol&gt;&lt;li&gt;Although adding an index may improve the performance of one query, it can adversely affect other SQL operations - most obviously data updates. There is no easy solution to this, though the SQL Profiler can help you if you capture and analyse a representative sample of SQL operations&lt;/li&gt;&lt;li&gt;Some out-dated CRM documentation suggested that it is unsupported to add indexes to the MSCRM database. However, adding indexes is supported, providing the index does not implement any constraints (i.e. it's not a UNIQUE index)&lt;/li&gt;&lt;/ol&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/199106851038957806-6071216783116911436?l=mscrmuk.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://mscrmuk.blogspot.com/feeds/6071216783116911436/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=199106851038957806&amp;postID=6071216783116911436' title='9 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/199106851038957806/posts/default/6071216783116911436'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/199106851038957806/posts/default/6071216783116911436'/><link rel='alternate' type='text/html' href='http://mscrmuk.blogspot.com/2008/09/sql-timeouts-in-crm-generic-sql-error.html' title='SQL Timeouts in CRM - Generic SQL Error'/><author><name>David Jennaway</name><uri>http://www.blogger.com/profile/09695858105618938443</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>9</thr:total></entry><entry><id>tag:blogger.com,1999:blog-199106851038957806.post-8362007520813222866</id><published>2008-09-01T12:50:00.003+01:00</published><updated>2008-09-01T13:00:06.734+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Announcement'/><category scheme='http://www.blogger.com/atom/ns#' term='CRM 4.0'/><title type='text'>CRM SDK Update - 4.0.6</title><content type='html'>There's been a new release of the CRM 4.0 SDK - available here &lt;a href="http://www.microsoft.com/downloads/details.aspx?FamilyId=82E632A7-FAF9-41E0-8EC1-A2662AAE9DFB&amp;amp;displaylang=en"&gt;http://www.microsoft.com/downloads/details.aspx?FamilyId=82E632A7-FAF9-41E0-8EC1-A2662AAE9DFB&amp;amp;displaylang=en&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;There are no major changes in this release, but there are a few aspects of note:&lt;br /&gt;&lt;ol&gt;&lt;li&gt;The Plug-in example code now uses the DynamicEntity class as recommended&lt;/li&gt;&lt;li&gt;The code for use of ImportXml, ExportXml and PublishXml looks like it now passes all required XML nodes&lt;/li&gt;&lt;li&gt;There are now instructions for setting up a web reference in Visual Studio 2008&lt;/li&gt;&lt;li&gt;The PrependOrgName client-side function is now documented (and hence supported)&lt;/li&gt;&lt;/ol&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/199106851038957806-8362007520813222866?l=mscrmuk.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://mscrmuk.blogspot.com/feeds/8362007520813222866/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=199106851038957806&amp;postID=8362007520813222866' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/199106851038957806/posts/default/8362007520813222866'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/199106851038957806/posts/default/8362007520813222866'/><link rel='alternate' type='text/html' href='http://mscrmuk.blogspot.com/2008/09/crm-sdk-update-406.html' title='CRM SDK Update - 4.0.6'/><author><name>David Jennaway</name><uri>http://www.blogger.com/profile/09695858105618938443</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-199106851038957806.post-950163973632253211</id><published>2008-08-31T10:57:00.001+01:00</published><updated>2008-09-01T12:09:34.723+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Server code'/><category scheme='http://www.blogger.com/atom/ns#' term='Plugin'/><category scheme='http://www.blogger.com/atom/ns#' term='Code Gallery'/><category scheme='http://www.blogger.com/atom/ns#' term='CRM 4.0'/><title type='text'>Hiding System Views in CRM 4.0</title><content type='html'>In CRM 3.0 it was relatively easy to hide one of the built-in system views - all you had to do was share the view with an empty team, which converted the view to a userquery entity. However, CRM 4.0 does not support this.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;There is an alternative route, but it required plug-in coding. Rather than have to write code for each deployment, I created a standard plug-in that can be used to hide any views, based on some XML configuration. The source code and compiled code is available on the &lt;a href="http://code.msdn.microsoft.com/crm40hidesystemviews"&gt;MSDN Code Gallery&lt;/a&gt;, along with a sample configuration file.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/199106851038957806-950163973632253211?l=mscrmuk.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://mscrmuk.blogspot.com/feeds/950163973632253211/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=199106851038957806&amp;postID=950163973632253211' title='9 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/199106851038957806/posts/default/950163973632253211'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/199106851038957806/posts/default/950163973632253211'/><link rel='alternate' type='text/html' href='http://mscrmuk.blogspot.com/2008/08/hiding-system-views-in-crm-40.html' title='Hiding System Views in CRM 4.0'/><author><name>David Jennaway</name><uri>http://www.blogger.com/profile/09695858105618938443</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>9</thr:total></entry><entry><id>tag:blogger.com,1999:blog-199106851038957806.post-6155997090380479925</id><published>2008-08-29T10:46:00.000+01:00</published><updated>2008-09-01T13:00:44.353+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Server code'/><category scheme='http://www.blogger.com/atom/ns#' term='Plugin'/><category scheme='http://www.blogger.com/atom/ns#' term='CRM 4.0'/><title type='text'>Plug-ins - differences between Target and Image Entity</title><content type='html'>In a plug-in there are potentially several ways to access entity data relevant to the plug-in action. For example, on the create message you can access the data on the new entity instance in one of the following ways:&lt;br /&gt;&lt;ol&gt;&lt;li&gt;Via the Target &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_0"&gt;InputParameter&lt;/span&gt;&lt;/li&gt;&lt;li&gt;Via an Image Entity registered on the step&lt;/li&gt;&lt;li&gt;Via a Retrieve request in the plug-in code&lt;/li&gt;&lt;/ol&gt;&lt;p&gt;These do not always work in the same way, as follows:&lt;/p&gt;&lt;p&gt;&lt;strong&gt;Availability of the data by stage &lt;/strong&gt;&lt;/p&gt;&lt;p&gt;The general rules are:&lt;/p&gt;&lt;ol&gt;&lt;li&gt;&lt;span class="blsp-spelling-error" id="SPELLING_ERROR_1"&gt;InputParameter&lt;/span&gt; is available in all stages. It can be modified in the &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_2"&gt;pre&lt;/span&gt;-stage, but changing it in the post-stage will have no effect&lt;/li&gt;&lt;li&gt;A &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_3"&gt;PostImage&lt;/span&gt; Entity is available in the post-stage, and a &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_4"&gt;PreImage&lt;/span&gt; Entity in the &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_5"&gt;pre&lt;/span&gt;-stage only&lt;/li&gt;&lt;li&gt;If using a Retrieve in the plug-in, then the data returned depends on the stage. In the &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_6"&gt;pre&lt;/span&gt;-stage, you will see the data before the modification, whereas in the post-stage you see the data after the modification&lt;/li&gt;&lt;li&gt;Some Image Entities are not relevant for some messages - e.g. there is no &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_7"&gt;PreImage&lt;/span&gt; for a Create message, and no &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_8"&gt;PostImage&lt;/span&gt; for a Delete message&lt;/li&gt;&lt;/ol&gt;&lt;p&gt;&lt;strong&gt;Data in the Name attribute&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;If the message is updating &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_9"&gt;CRM&lt;/span&gt; (e.g. a Create or Update message) then the &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_10"&gt;InputParameter&lt;/span&gt; only contains the minimum information that needs to be saved to &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_11"&gt;CRM&lt;/span&gt;. A consequence of this is that the name attribute of any of the following data types is null:&lt;/p&gt;&lt;ul&gt;&lt;li&gt;&lt;span class="blsp-spelling-error" id="SPELLING_ERROR_12"&gt;Lookup&lt;/span&gt;&lt;/li&gt;&lt;li&gt;Owner&lt;/li&gt;&lt;li&gt;Customer&lt;/li&gt;&lt;li&gt;&lt;span class="blsp-spelling-error" id="SPELLING_ERROR_13"&gt;Picklist&lt;/span&gt;&lt;/li&gt;&lt;li&gt;Boolean&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;So, if your code needs to access the name, then you cannot rely on the &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_14"&gt;InputParameter&lt;/span&gt;, and have to use either the Image Entity or a Retrieve to get the data.&lt;/p&gt;&lt;p&gt;My preference is to use an Image Entity, mostly as this reduces the code I have to write. The &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_15"&gt;CRM&lt;/span&gt; &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_16"&gt;SDK&lt;/span&gt; also suggests that this is more efficient, though I've not done any thorough performance testing on this to determine if this is relevant.&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/199106851038957806-6155997090380479925?l=mscrmuk.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://mscrmuk.blogspot.com/feeds/6155997090380479925/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=199106851038957806&amp;postID=6155997090380479925' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/199106851038957806/posts/default/6155997090380479925'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/199106851038957806/posts/default/6155997090380479925'/><link rel='alternate' type='text/html' href='http://mscrmuk.blogspot.com/2008/09/plug-ins-differences-between-target-and.html' title='Plug-ins - differences between Target and Image Entity'/><author><name>David Jennaway</name><uri>http://www.blogger.com/profile/09695858105618938443</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-199106851038957806.post-3348353973056595867</id><published>2008-07-31T15:46:00.003+01:00</published><updated>2008-08-04T10:40:40.843+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Plugin'/><category scheme='http://www.blogger.com/atom/ns#' term='CRM 4.0'/><title type='text'>"Invalid Domain Name" error when registering plug-ins</title><content type='html'>On a couple of occasions recently I've had an error "Invalid domain name. Domain name is either invalid or unreachable" when registering a plug-in with the RegisterSolutionRequest.&lt;br /&gt;&lt;br /&gt;It looks to me like this is a spurious message, possibly caused by a timeout. My reasons for thinking this are:&lt;br /&gt;- I get the message on a VPC image which is the CRM server, SQL server and domain controller. If the domain was really unreachable, that would mean AD or DNS were not working and I'd expect other problems.&lt;br /&gt;- The message does not always occur. Registering exactly the same solution and steps normally works fine. It's not a persistent error.&lt;br /&gt;- It only occurs for me when registering a large number of steps, which again is consistent with it being a timeout issue.&lt;br /&gt;&lt;br /&gt;So, my general recommendation if getting this error is to try again, possibly registering fewer steps at a time. If I find out any moe on this, I'll post it here.&lt;br /&gt;&lt;br /&gt;&lt;strong&gt;Update - 4 Aug 08&lt;/strong&gt;&lt;br /&gt;It seems an alternative reason for this error is if the RegisterSolutionRequest (or similar request) is submitted by code that is running as one of the built-in accounts - e.g. NetworkService. I could image how this occurs, as these accounts are identified as e.g. NT AUTHORITY\NetworkService, and the platform code may be looking for a domain called 'NT AUTHORITY'.&lt;br /&gt;&lt;br /&gt;Only members of the Deployment Administrators role can register plug-ins, and it appears that CRM only allows user accounts to be added to this role (the dialog for adding users does give the option to add built-in security principals). Therefore it looks like it's not possible to register plug-ins via one of the built-in accounts - an example of this would be via code that itself is running in a plug-in&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/199106851038957806-3348353973056595867?l=mscrmuk.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://mscrmuk.blogspot.com/feeds/3348353973056595867/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=199106851038957806&amp;postID=3348353973056595867' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/199106851038957806/posts/default/3348353973056595867'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/199106851038957806/posts/default/3348353973056595867'/><link rel='alternate' type='text/html' href='http://mscrmuk.blogspot.com/2008/07/invalid-domain-name-error-when.html' title='&quot;Invalid Domain Name&quot; error when registering plug-ins'/><author><name>David Jennaway</name><uri>http://www.blogger.com/profile/09695858105618938443</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-199106851038957806.post-8190044409017146055</id><published>2008-06-27T08:52:00.005+01:00</published><updated>2008-06-27T09:22:53.653+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Customisation'/><category scheme='http://www.blogger.com/atom/ns#' term='CRM 4.0'/><title type='text'>Associated views on Quote Product and Order Product entities</title><content type='html'>The facility for adding Write-In products to the Order and Quote entities is implemented within CRM through 2 associated views on each of the Quote Product (quotedetail) and Order Product (salesorderdetail) entities. These are used for the Existing Products and Write-In Products navigation items respectively.&lt;br /&gt;&lt;br /&gt;This can have effects elsewhere, however. If you create a custom one to many relationship from another entity to the Quote Product or Order Product entity, then only one of the associated views is used within the parent entity. This can cause a problem, because neither associated view displays all the data (one displays the write-in products only, and the other displays the existing products only). For example, the default associated view is the Existing Products view, so write-in products would not be displayed.&lt;br /&gt;&lt;br /&gt;There are 2 possible solutions to this. One is to change which is the default view, the other is to change the filtering within one of the views. Both of these are configured via attributes of the savedquery entity. These can be modified in a supported way by using the CrmService.Update method for the savedquery entity, or in an unsupported way by modifying field values directly in the savedquerybase SQL table.&lt;br /&gt;&lt;br /&gt;Which associated view is displayed is controlled by the IsDefault attribute - if you change this then it's your responsibility to ensure only one view has this set to true.&lt;br /&gt;&lt;br /&gt;The filtering is applied based on the ColumnSetXml attribute, which is essentially a FetchXml expression. For example, the ColumnSetXml for the Existing Product view is:&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family:courier new;font-size:85%;"&gt;&amp;lt;columnset version="3.0"&amp;gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;font-size:85%;"&gt;&amp;lt;filter type="and"&amp;gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;font-size:85%;"&gt;&amp;lt;condition column="isproductoverridden" value="0" operator="eq" /&amp;gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;font-size:85%;"&gt;&amp;lt;/filter&amp;gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;font-size:85%;"&gt;&amp;lt;column&amp;gt;productid&amp;lt;/column&amp;gt;&amp;lt;column&amp;gt;priceperunit&amp;lt;/column&amp;gt;&amp;lt;column&amp;gt;quantity&amp;lt;/column&amp;gt;&amp;lt;column&amp;gt;extendedamount&amp;lt;/column&amp;gt;&amp;lt;column&amp;gt;salesorderdetailid&amp;lt;/column&amp;gt;&amp;lt;ascend&amp;gt;productid&amp;lt;/ascend&amp;gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;font-size:85%;"&gt;&amp;lt;/columnset&amp;gt;&lt;/span&gt;&lt;br /&gt;&lt;p&gt;If you wanted this view to include all Quote Products, then you could remove the whole filter and condition elements. Note that such a change would necessarily affect the Existing Product view within the Quote entity.&lt;/p&gt;&lt;p&gt;&lt;span style="font-size:85%;"&gt;&lt;/span&gt; &lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/199106851038957806-8190044409017146055?l=mscrmuk.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://mscrmuk.blogspot.com/feeds/8190044409017146055/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=199106851038957806&amp;postID=8190044409017146055' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/199106851038957806/posts/default/8190044409017146055'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/199106851038957806/posts/default/8190044409017146055'/><link rel='alternate' type='text/html' href='http://mscrmuk.blogspot.com/2008/06/associated-views-on-quote-product-and.html' title='Associated views on Quote Product and Order Product entities'/><author><name>David Jennaway</name><uri>http://www.blogger.com/profile/09695858105618938443</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-199106851038957806.post-7348899412192911553</id><published>2008-06-20T16:30:00.009+01:00</published><updated>2009-03-05T15:53:54.551Z</updated><category scheme='http://www.blogger.com/atom/ns#' term='Server code'/><category scheme='http://www.blogger.com/atom/ns#' term='Plugin'/><category scheme='http://www.blogger.com/atom/ns#' term='CRM 4.0'/><title type='text'>Plugin Parameters</title><content type='html'>Although the &lt;a href="http://msdn.microsoft.com/en-us/library/bb928212.aspx"&gt;CRM 4.0 SDK&lt;/a&gt; is generally pretty comprehensive, I find it doesn't contain as much information as I'd like about the information passed to plugins for each of the messages.&lt;br /&gt;&lt;br /&gt;The following table lists the main parameters passed to plugins on the most common messages. If the message you want isn't listed here, post a comment and I'll update the table.&lt;br /&gt;&lt;div&gt;&lt;br /&gt;&lt;table border="1"&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td&gt;&lt;b&gt;Message&lt;/b&gt;&lt;/td&gt;&lt;td&gt;&lt;b&gt;Parameter&lt;/b&gt;&lt;/td&gt;&lt;td&gt;&lt;b&gt;Direction&lt;/b&gt;&lt;/td&gt;&lt;td&gt;&lt;b&gt;Type&lt;/b&gt;&lt;/td&gt;&lt;td&gt;&lt;b&gt;Comments&lt;/b&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;Assign&lt;/td&gt;&lt;td&gt;Assignee&lt;/td&gt;&lt;td&gt;Input&lt;/td&gt;&lt;td&gt;SecurityPrincipal&lt;/td&gt;&lt;td&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;Assign&lt;/td&gt;&lt;td&gt;Target&lt;/td&gt;&lt;td&gt;Input&lt;/td&gt;&lt;td&gt;Moniker&lt;/td&gt;&lt;td&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;CancelSalesOrder&lt;/td&gt;&lt;td&gt;OrderClose&lt;/td&gt;&lt;td&gt;Input&lt;/td&gt;&lt;td&gt;DynamicEntity&lt;/td&gt;&lt;td&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;Close&lt;/td&gt;&lt;td&gt;*ActivityClose&lt;/td&gt;&lt;td&gt;Input&lt;/td&gt;&lt;td&gt;DynamicEntity&lt;/td&gt;&lt;td&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;Close&lt;/td&gt;&lt;td&gt;Status&lt;/td&gt;&lt;td&gt;Input&lt;/td&gt;&lt;td&gt;Int32&lt;/td&gt;&lt;td&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;Create&lt;/td&gt;&lt;td&gt;id&lt;/td&gt;&lt;td&gt;Output&lt;/td&gt;&lt;td&gt;Guid&lt;/td&gt;&lt;td&gt;Only available on the Post Stage&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;Create&lt;/td&gt;&lt;td&gt;Target&lt;/td&gt;&lt;td&gt;Input&lt;/td&gt;&lt;td&gt;DynamicEntity&lt;/td&gt;&lt;td&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;Delete&lt;/td&gt;&lt;td&gt;Target&lt;/td&gt;&lt;td&gt;Input&lt;/td&gt;&lt;td&gt;Moniker&lt;/td&gt;&lt;td&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;Execute&lt;/td&gt;&lt;td&gt;FetchXml&lt;/td&gt;&lt;td&gt;Input&lt;/td&gt;&lt;td&gt;String&lt;/td&gt;&lt;td&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;Execute&lt;/td&gt;&lt;td&gt;FetchXmlResult&lt;/td&gt;&lt;td&gt;Output&lt;/td&gt;&lt;td&gt;String&lt;/td&gt;&lt;td&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;GrantAccess&lt;/td&gt;&lt;td&gt;PrincipalAccess&lt;/td&gt;&lt;td&gt;Input&lt;/td&gt;&lt;td&gt;PrincipalAccess&lt;/td&gt;&lt;td&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;GrantAccess&lt;/td&gt;&lt;td&gt;Target&lt;/td&gt;&lt;td&gt;Input&lt;/td&gt;&lt;td&gt;Moniker&lt;/td&gt;&lt;td&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;Handle&lt;/td&gt;&lt;td&gt;SourceQueueId&lt;/td&gt;&lt;td&gt;Input&lt;/td&gt;&lt;td&gt;Guid&lt;/td&gt;&lt;td&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;Handle&lt;/td&gt;&lt;td&gt;Target&lt;/td&gt;&lt;td&gt;Input&lt;/td&gt;&lt;td&gt;DynamicEntity&lt;/td&gt;&lt;td&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;Lose&lt;/td&gt;&lt;td&gt;*ActivityClose&lt;/td&gt;&lt;td&gt;Input&lt;/td&gt;&lt;td&gt;DynamicEntity&lt;/td&gt;&lt;td&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;Lose&lt;/td&gt;&lt;td&gt;Status&lt;/td&gt;&lt;td&gt;Input&lt;/td&gt;&lt;td&gt;Int32&lt;/td&gt;&lt;td&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;Retrieve&lt;/td&gt;&lt;td&gt;BusinessEntity&lt;/td&gt;&lt;td&gt;Output&lt;/td&gt;&lt;td&gt;DynamicEntity&lt;/td&gt;&lt;td&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;Retrieve&lt;/td&gt;&lt;td&gt;ColumnSet&lt;/td&gt;&lt;td&gt;Input&lt;/td&gt;&lt;td&gt;ColumnSetBase&lt;/td&gt;&lt;td&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;Retrieve&lt;/td&gt;&lt;td&gt;Target&lt;/td&gt;&lt;td&gt;Input&lt;/td&gt;&lt;td&gt;Moniker&lt;/td&gt;&lt;td&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;RetrieveExchangeRate&lt;/td&gt;&lt;td&gt;ExchangeRate&lt;/td&gt;&lt;td&gt;Output&lt;/td&gt;&lt;td&gt;Decimal&lt;/td&gt;&lt;td&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;RetrieveExchangeRate&lt;/td&gt;&lt;td&gt;TransactionCurrencyId&lt;/td&gt;&lt;td&gt;Input&lt;/td&gt;&lt;td&gt;Guid&lt;/td&gt;&lt;td&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;RetrieveMultiple&lt;/td&gt;&lt;td&gt;BusinessEntityCollection&lt;/td&gt;&lt;td&gt;Output&lt;/td&gt;&lt;td&gt;BusinessEntityCollection&lt;/td&gt;&lt;td&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;RetrieveMultiple&lt;/td&gt;&lt;td&gt;Query&lt;/td&gt;&lt;td&gt;Input&lt;/td&gt;&lt;td&gt;QueryExpression&lt;/td&gt;&lt;td&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;RetrieveMultiple&lt;/td&gt;&lt;td&gt;ReturnDynamicEntities&lt;/td&gt;&lt;td&gt;Input&lt;/td&gt;&lt;td&gt;Boolean&lt;/td&gt;&lt;td&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;RetrievePrincipalAccess&lt;/td&gt;&lt;td&gt;AccessRights&lt;/td&gt;&lt;td&gt;Output&lt;/td&gt;&lt;td&gt;AccessRights&lt;/td&gt;&lt;td&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;RetrievePrincipalAccess&lt;/td&gt;&lt;td&gt;Principal&lt;/td&gt;&lt;td&gt;Input&lt;/td&gt;&lt;td&gt;SecurityPrincipal&lt;/td&gt;&lt;td&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;RetrievePrincipalAccess&lt;/td&gt;&lt;td&gt;Target&lt;/td&gt;&lt;td&gt;Input&lt;/td&gt;&lt;td&gt;Moniker&lt;/td&gt;&lt;td&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;RevokeAccess&lt;/td&gt;&lt;td&gt;Revokee&lt;/td&gt;&lt;td&gt;Input&lt;/td&gt;&lt;td&gt;PrincipalAccess&lt;/td&gt;&lt;td&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;RevokeAccess&lt;/td&gt;&lt;td&gt;Target&lt;/td&gt;&lt;td&gt;Input&lt;/td&gt;&lt;td&gt;Moniker&lt;/td&gt;&lt;td&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;Route&lt;/td&gt;&lt;td&gt;EndpointId&lt;/td&gt;&lt;td&gt;Input&lt;/td&gt;&lt;td&gt;Guid&lt;/td&gt;&lt;td&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;Route&lt;/td&gt;&lt;td&gt;RouteType&lt;/td&gt;&lt;td&gt;Input&lt;/td&gt;&lt;td&gt;RouteType&lt;/td&gt;&lt;td&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;Route&lt;/td&gt;&lt;td&gt;SourceQueueId&lt;/td&gt;&lt;td&gt;Input&lt;/td&gt;&lt;td&gt;Guid&lt;/td&gt;&lt;td&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;Route&lt;/td&gt;&lt;td&gt;Target&lt;/td&gt;&lt;td&gt;Input&lt;/td&gt;&lt;td&gt;Moniker&lt;/td&gt;&lt;td&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;Send&lt;/td&gt;&lt;td&gt;EmailId&lt;/td&gt;&lt;td&gt;Input&lt;/td&gt;&lt;td&gt;Guid&lt;/td&gt;&lt;td&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;Send&lt;/td&gt;&lt;td&gt;IssueSend&lt;/td&gt;&lt;td&gt;Input&lt;/td&gt;&lt;td&gt;Boolean&lt;/td&gt;&lt;td&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;Send&lt;/td&gt;&lt;td&gt;Subject&lt;/td&gt;&lt;td&gt;Output&lt;/td&gt;&lt;td&gt;String&lt;/td&gt;&lt;td&gt;This is the subject after the tracking token has been added&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;Send&lt;/td&gt;&lt;td&gt;TrackingToken&lt;/td&gt;&lt;td&gt;Input&lt;/td&gt;&lt;td&gt;String&lt;/td&gt;&lt;td&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;SetStateDynamicEntity&lt;/td&gt;&lt;td&gt;EntityMoniker&lt;/td&gt;&lt;td&gt;Input&lt;/td&gt;&lt;td&gt;Moniker&lt;/td&gt;&lt;td&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;SetStateDynamicEntity&lt;/td&gt;&lt;td&gt;State&lt;/td&gt;&lt;td&gt;Input&lt;/td&gt;&lt;td&gt;String&lt;/td&gt;&lt;td&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;SetStateDynamicEntity&lt;/td&gt;&lt;td&gt;Status&lt;/td&gt;&lt;td&gt;Input&lt;/td&gt;&lt;td&gt;Int32&lt;/td&gt;&lt;td&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;Update&lt;/td&gt;&lt;td&gt;Target&lt;/td&gt;&lt;td&gt;Input&lt;/td&gt;&lt;td&gt;DynamicEntity&lt;/td&gt;&lt;td&gt;To get the Primary Key, find the KeyProperty within the DynamicEntity&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;Win&lt;/td&gt;&lt;td&gt;*ActivityClose&lt;/td&gt;&lt;td&gt;Input&lt;/td&gt;&lt;td&gt;DynamicEntity&lt;/td&gt;&lt;td&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;Win&lt;/td&gt;&lt;td&gt;QuoteClose&lt;/td&gt;&lt;td&gt;Input&lt;/td&gt;&lt;td&gt;DynamicEntity&lt;/td&gt;&lt;td&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;Win&lt;/td&gt;&lt;td&gt;Status&lt;/td&gt;&lt;td&gt;Input&lt;/td&gt;&lt;td&gt;Int32&lt;/td&gt;&lt;td&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;br /&gt;&lt;/div&gt;&lt;br /&gt;Notes:&lt;br /&gt;*ActivityClose. For the Win, Lose and Close messages, one of the parameters is an activity type whose name depends on the primary entity - e.g. the Win message could have a QuoteClose or OpportunityClose entity passed to it&lt;br /&gt;&lt;br /&gt;To gather this information I used the plugin tools described on the &lt;a href="http://blogs.msdn.com/crm/archive/2008/05/21/plugins-which-message-and-which-pipeline.aspx"&gt;MSCRM Team blog&lt;/a&gt;. The source code for these tools can be found here:&lt;br /&gt;&lt;a href="http://code.msdn.microsoft.com/crm40pluginbulk"&gt;Bulk Registration Tool&lt;/a&gt;&lt;br /&gt;&lt;a href="http://code.msdn.microsoft.com/crm40pluginlogger"&gt;Plugin Logger&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;Other Links:&lt;br /&gt;&lt;a href="http://msdn.microsoft.com/en-us/library/cc151086.aspx"&gt;Plugin Development&lt;/a&gt;&lt;br /&gt;&lt;a href="http://msdn.microsoft.com/en-us/library/cc151101.aspx"&gt;Plugin Messages&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/199106851038957806-7348899412192911553?l=mscrmuk.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://mscrmuk.blogspot.com/feeds/7348899412192911553/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=199106851038957806&amp;postID=7348899412192911553' title='6 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/199106851038957806/posts/default/7348899412192911553'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/199106851038957806/posts/default/7348899412192911553'/><link rel='alternate' type='text/html' href='http://mscrmuk.blogspot.com/2008/06/plugin-parameters.html' title='Plugin Parameters'/><author><name>David Jennaway</name><uri>http://www.blogger.com/profile/09695858105618938443</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>6</thr:total></entry><entry><id>tag:blogger.com,1999:blog-199106851038957806.post-7792579570100341498</id><published>2008-06-19T11:45:00.003+01:00</published><updated>2008-06-19T12:04:22.936+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Reports'/><category scheme='http://www.blogger.com/atom/ns#' term='CRM 4.0'/><title type='text'>Reports in IFrames - Updated for CRM 4.0</title><content type='html'>One of my earlier posts here and on the &lt;a href="http://blogs.msdn.com/crm/"&gt;CRM Team Blog&lt;/a&gt; was about &lt;a href="http://blogs.msdn.com/crm/archive/2007/10/04/writing-reports-to-display-in-iframes-and-from-isv-config.aspx"&gt;writing reports to display in IFrames and via ISV.Config&lt;/a&gt;. This was written for CRM 3.0, and although the principle remains the same for CRM 4.0, a couple of changes are required to the report parameters.&lt;br /&gt;&lt;br /&gt;&lt;strong&gt;Extra Parameters passed by CRM&lt;/strong&gt;&lt;br /&gt;To support multi-tenancy and multi-language deployments, CRM 4.0 passes additional parameters on the query string when the 'pass record object-type...' option is set for the IFrame. These extra parameters are orgname, UserLCID and OrgLCID.&lt;br /&gt;&lt;br /&gt;For the report to work in reporting services you will have to add parameters with these names to your report. The orgname parameter has to be a string, the UserLCID and OrgLCID can be either strings or integers. As with the type and typename parameters, these new parameters don't have to be used in the report, they just need to exist for reporting services to accept values for them on the query string.&lt;br /&gt;&lt;br /&gt;&lt;strong&gt;Changes to the query string for ISV.Config buttons&lt;/strong&gt;&lt;br /&gt;In CRM 4.0, Microsoft have standardised the parameters such that they are the same for IFrames and ISV.Config buttons. This means that your report should have parameters id, type, typename, orgname, UserLCID and OrgLCID.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/199106851038957806-7792579570100341498?l=mscrmuk.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://mscrmuk.blogspot.com/feeds/7792579570100341498/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=199106851038957806&amp;postID=7792579570100341498' title='6 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/199106851038957806/posts/default/7792579570100341498'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/199106851038957806/posts/default/7792579570100341498'/><link rel='alternate' type='text/html' href='http://mscrmuk.blogspot.com/2008/06/reports-in-iframes-updated-for-crm-40.html' title='Reports in IFrames - Updated for CRM 4.0'/><author><name>David Jennaway</name><uri>http://www.blogger.com/profile/09695858105618938443</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>6</thr:total></entry><entry><id>tag:blogger.com,1999:blog-199106851038957806.post-1426255587661455293</id><published>2008-06-11T17:47:00.003+01:00</published><updated>2008-06-11T17:57:29.836+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Server code'/><title type='text'>'This entity is already locked' message</title><content type='html'>I recently had to debug some code that threw the 'This entity is already locked' error message (code 80043B1D) when updating an order product (salesorderdetail) entity.&lt;br /&gt;&lt;br /&gt;This error can occur even if the state of both the order and order product allowed editing. The error occurs if the productid property is set on the BusinessEntity that is passed to the Update method. A general principle when coding with the CRM platform is that, if a property value is set on an entity passed to the Update method, then the CRM platform will assume that the value has been changed.&lt;br /&gt;&lt;br /&gt;In this case, if the productid is passed, CRM assumes that you are trying to change the product, which is not permitted if the ispricelocked attribute is set to true on the order. So, the solution is to always ensure that you know which attributes are actually changing, and ensure that only these properties and the primary key value are passed to the update method.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/199106851038957806-1426255587661455293?l=mscrmuk.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://mscrmuk.blogspot.com/feeds/1426255587661455293/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=199106851038957806&amp;postID=1426255587661455293' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/199106851038957806/posts/default/1426255587661455293'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/199106851038957806/posts/default/1426255587661455293'/><link rel='alternate' type='text/html' href='http://mscrmuk.blogspot.com/2008/06/this-entity-is-already-locked-message.html' title='&apos;This entity is already locked&apos; message'/><author><name>David Jennaway</name><uri>http://www.blogger.com/profile/09695858105618938443</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-199106851038957806.post-240047912805574566</id><published>2008-06-03T19:09:00.009+01:00</published><updated>2008-06-04T10:21:46.013+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Plugin'/><category scheme='http://www.blogger.com/atom/ns#' term='Workflow'/><category scheme='http://www.blogger.com/atom/ns#' term='CRM 4.0'/><title type='text'>Differences between Workflow and Plugins in CRM 4.0</title><content type='html'>A common question I get is ‘what is the difference between workflow and plugins, and when should I use one or the other ?’. This article is intended to be a comprehensive answer to these 2 questions.&lt;br /&gt;&lt;br /&gt;First of all, I want to clarify the distinction between what I consider 3 distinct categories of workflow – the terminology is my own:&lt;br /&gt;&lt;ul&gt;&lt;li&gt;&lt;strong&gt;Simple workflow&lt;/strong&gt;. This is one or more workflow rules created within the MSCRM interface, and which do not include custom workflow activities.&lt;/li&gt;&lt;li&gt;&lt;strong&gt;Workflow with custom workflow activities&lt;/strong&gt;. I’ll explain more about custom workflow activities later in this article; for now the key point is that a custom workflow activity is .Net code that is written to perform functions not possible in simple workflow, and this code can be called from a workflow rule&lt;/li&gt;&lt;li&gt;&lt;strong&gt;Workflows created with the Workflow Designer&lt;/strong&gt; in Windows Workflow Foundation. It is possible to build workflows outside of the CRM user interface, but I’m not going to include them in this article.&lt;/li&gt;&lt;/ul&gt;&lt;strong&gt;Simple workflows&lt;/strong&gt;&lt;br /&gt;The main characteristics of simple workflows are:&lt;br /&gt;&lt;ul&gt;&lt;li&gt;* Creating a simple workflow involves no code&lt;/li&gt;&lt;li&gt;Workflows run only on the CRM server – workflow processing is not available within a client that is offline&lt;/li&gt;&lt;li&gt;Workflows run asynchronously – any data changes made within a workflow rule will not show up immediately within the CRM user interface&lt;/li&gt;&lt;li&gt;Workflows can be run manually or automatically. The automatic running of workflows is based on several data modification events&lt;/li&gt;&lt;li&gt;Workflow rules are entity specific&lt;/li&gt;&lt;li&gt;The state and stage of a workflow instance can be viewed within the CRM user interface by any CRM user with appropriate permissions&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;Some limitations of workflows are:&lt;/p&gt;&lt;ul&gt;&lt;li&gt;Workflow rules cannot be created for all entities&lt;/li&gt;&lt;li&gt;Although workflow rules can be triggered by the most common data modification events, there are some events that don’t trigger workflow rules&lt;/li&gt;&lt;li&gt;* Simple workflows offering limited capability to perform calculations&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;Characteristics and limitations marked with an asterix (*) do not apply if using custom workflow activities; the others do still apply.&lt;/p&gt;&lt;p&gt;&lt;strong&gt;Custom workflow activities&lt;/strong&gt;&lt;br /&gt;Custom workflow activities allow you to extend the capabilities of workflow rules. Three common uses are to perform calculations on CRM data, to access CRM functionality that is not available in the out-of-the-box workflow activities, and to access external data.&lt;br /&gt;&lt;br /&gt;Custom workflow activities are written as .Net assemblies which have to be registered on the CRM server. These assemblies can include information about parameters that can be passed into or out of the activity.&lt;/p&gt;&lt;p&gt;&lt;strong&gt;Plugins&lt;/strong&gt;&lt;br /&gt;A plugin is .Net code that is registered on the CRM server. A plugin assembly can be registered for one or more steps – these steps correspond to the combination of the message (event), entity and stage. An example of a step would be the Create message for the account entity on the pre-event stage. Registration of the assembly and steps is part of the plugin deployment process, and there is no direct user interaction with plugins&lt;br /&gt;&lt;br /&gt;The main characteristics of plugins are:&lt;/p&gt;&lt;ul&gt;&lt;li&gt;They have to be written as .Net code&lt;/li&gt;&lt;li&gt;Although they typically run on the CRM server, they can be deployed and configured to run on a CRM client that is offline&lt;/li&gt;&lt;li&gt;They can run either synchronously or asynchronously. If they run synchronously, any data changes made within the plugin will show up immediately within the CRM user interface&lt;/li&gt;&lt;li&gt;Synchronous plugins can run on either the pre-event or post-event stage. The pre-event stage happens before data is written to the CRM database, and a plugin registered on a pre-event step can cancel the data writing and provide an error message to the user.&lt;/li&gt;&lt;li&gt;More entities can have plugins registered for them than can have workflow rules&lt;/li&gt;&lt;li&gt;Plugins can run on more events than can workflow rules. An example is that plugins can run on data retrieval, not just modification events&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;The main limitations of plugins are:&lt;/p&gt;&lt;ul&gt;&lt;li&gt;Plugins cannot be run manually; they only run on the steps for which they are registered&lt;/li&gt;&lt;li&gt;There is no user interaction with plugins, other than error messages that might be throw by a synchronous plugin&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;&lt;strong&gt;Sample Scenarios&lt;/strong&gt;&lt;br /&gt;So, having covered the main characteristics and limitations of simple workflows, custom workflow activities and plugins, when should you choose one or another ? Here are some common scenarios:&lt;br /&gt;&lt;br /&gt;&lt;strong&gt;What you want to achieve can be done with a simple workflow, and it is acceptable or desirable for this to happen asynchronously and on the server only&lt;/strong&gt;&lt;br /&gt;In this case I’d go with simple workflows; there’s no point writing code if you don’t have to.&lt;br /&gt;&lt;br /&gt;&lt;strong&gt;What you want to achieve has to run synchronously&lt;br /&gt;&lt;/strong&gt;If so, workflow won’t do, so it would have to be a plugin. An alternative could be to use client script, but I don’t intend to complicate this article by including this in any more detail&lt;br /&gt;&lt;br /&gt;&lt;strong&gt;You need to be able to cancel the data operation&lt;br /&gt;&lt;/strong&gt;A pre-event plugin is the only option covered here, though again client script should be considered&lt;br /&gt;&lt;br /&gt;&lt;strong&gt;You want to give users the discretion to run the operation manually&lt;/strong&gt;&lt;br /&gt;Here you’ll need a workflow. Whether or not you need a custom workflow activity depends on the complexity of the operations. Again, there may be an option outside of the scope of this article – to write an ASP .Net application that is called from an ISV Config button&lt;br /&gt;&lt;br /&gt;&lt;strong&gt;You need to write custom code, but you want users to decide whether this code should run, and under what circumstances&lt;/strong&gt;&lt;br /&gt;In this case I’d go with a custom workflow activity, as you could make this available for users to add to their own workflows &lt;/p&gt;&lt;p&gt;&lt;strong&gt;Further Information&lt;/strong&gt;&lt;br /&gt;There is more detail about how to write and deploy plugins and custom workflow assemblies within the &lt;a href="http://msdn.microsoft.com/en-us/library/bb928212.aspx"&gt;CRM 4.0 SDK&lt;/a&gt;, though unfortunately there’s not a lot of information about when to choose one or the other.&lt;br /&gt;&lt;br /&gt;The classroom training material ‘Extending Microsoft Dynamics CRM 4.0’, course number 8969, should have more information both about building plugins and custom workflow assemblies, and when to use them. This course will also cover other solution technologies such as client script and ASP .Net extensions.&lt;/p&gt;&lt;p&gt;One of the MS team, Humberto Lezama has also produced a useful matrix indicating the relative merits of workflow and plugins. This can be found &lt;a href="http://blogs.msdn.com/lezamax/archive/2008/04/02/plug-in-or-workflow.aspx"&gt;here&lt;/a&gt;&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/199106851038957806-240047912805574566?l=mscrmuk.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://mscrmuk.blogspot.com/feeds/240047912805574566/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=199106851038957806&amp;postID=240047912805574566' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/199106851038957806/posts/default/240047912805574566'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/199106851038957806/posts/default/240047912805574566'/><link rel='alternate' type='text/html' href='http://mscrmuk.blogspot.com/2008/06/differences-between-workflow-and.html' title='Differences between Workflow and Plugins in CRM 4.0'/><author><name>David Jennaway</name><uri>http://www.blogger.com/profile/09695858105618938443</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-199106851038957806.post-5137890536829623504</id><published>2008-06-02T15:22:00.001+01:00</published><updated>2008-06-02T15:26:06.293+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='News'/><category scheme='http://www.blogger.com/atom/ns#' term='CRM 4.0'/><title type='text'>CRM SDK version 4.0.5 has been released</title><content type='html'>The CRM 4.0 SDK has been updated again, and is available for download &lt;a href="http://www.microsoft.com/downloads/details.aspx?FamilyID=82E632A7-FAF9-41E0-8EC1-A2662AAE9DFB"&gt;here&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;A decent overview of the changes can be found on the &lt;a href="http://blogs.msdn.com/crm/archive/2008/05/30/microsoft-dynamics-crm-sdk-now-with-vb-net-sample-code.aspx"&gt;CRM Team Blog&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/199106851038957806-5137890536829623504?l=mscrmuk.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://mscrmuk.blogspot.com/feeds/5137890536829623504/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=199106851038957806&amp;postID=5137890536829623504' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/199106851038957806/posts/default/5137890536829623504'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/199106851038957806/posts/default/5137890536829623504'/><link rel='alternate' type='text/html' href='http://mscrmuk.blogspot.com/2008/06/crm-sdk-version-405-has-been-released.html' title='CRM SDK version 4.0.5 has been released'/><author><name>David Jennaway</name><uri>http://www.blogger.com/profile/09695858105618938443</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-199106851038957806.post-5715638612761318427</id><published>2008-05-22T09:33:00.005+01:00</published><updated>2008-06-02T15:27:46.793+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Server code'/><category scheme='http://www.blogger.com/atom/ns#' term='News'/><category scheme='http://www.blogger.com/atom/ns#' term='Code Gallery'/><title type='text'>Blog Update - Links to Code Gallery Resources</title><content type='html'>I've added an extra section to this blog. This is a list of all my published resources on the &lt;a href="http://code.msdn.microsoft.com/"&gt;MSDN Code Gallery&lt;/a&gt;, along with a link to all other CRM-related resources there. At the time of posting, there were 66 resources in the code gallery with a CRM tag.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/199106851038957806-5715638612761318427?l=mscrmuk.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://mscrmuk.blogspot.com/feeds/5715638612761318427/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=199106851038957806&amp;postID=5715638612761318427' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/199106851038957806/posts/default/5715638612761318427'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/199106851038957806/posts/default/5715638612761318427'/><link rel='alternate' type='text/html' href='http://mscrmuk.blogspot.com/2008/05/blog-update-links-to-code-gallery.html' title='Blog Update - Links to Code Gallery Resources'/><author><name>David Jennaway</name><uri>http://www.blogger.com/profile/09695858105618938443</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-199106851038957806.post-1782343616333876754</id><published>2008-05-22T09:15:00.003+01:00</published><updated>2008-05-22T09:20:31.778+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Server code'/><category scheme='http://www.blogger.com/atom/ns#' term='Plugin'/><category scheme='http://www.blogger.com/atom/ns#' term='Team Blog'/><category scheme='http://www.blogger.com/atom/ns#' term='Code Gallery'/><category scheme='http://www.blogger.com/atom/ns#' term='CRM 4.0'/><title type='text'>Posting on Microsoft Dynamics CRM Team Blog</title><content type='html'>I've been invited to post again on the &lt;a href="http://blogs.msdn.com/crm"&gt;Microsoft Dynamics &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_0"&gt;CRM&lt;/span&gt; Team Blog&lt;/a&gt;. This time I've included information about &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_1"&gt;plugin&lt;/span&gt; messages, and how a couple of tools can be used to record information about all &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_2"&gt;plugin&lt;/span&gt; events on a &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_3"&gt;CRM&lt;/span&gt; 4.0 deployment. The article is here: &lt;a href="http://blogs.msdn.com/crm/archive/2008/05/21/plugins-which-message-and-which-pipeline.aspx"&gt;http://blogs.msdn.com/crm/archive/2008/05/21/plugins-which-message-and-which-pipeline.aspx&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;The two tools are both available on the &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_4"&gt;MSDN&lt;/span&gt; Code Gallery:&lt;br /&gt;&lt;a href="http://code.msdn.microsoft.com/crm40pluginbulk"&gt;http://code.msdn.microsoft.com/crm40pluginbulk&lt;/a&gt;&lt;br /&gt;&lt;a href="http://code.msdn.microsoft.com/crm40pluginlogger"&gt;http://code.msdn.microsoft.com/crm40pluginlogger&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/199106851038957806-1782343616333876754?l=mscrmuk.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://mscrmuk.blogspot.com/feeds/1782343616333876754/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=199106851038957806&amp;postID=1782343616333876754' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/199106851038957806/posts/default/1782343616333876754'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/199106851038957806/posts/default/1782343616333876754'/><link rel='alternate' type='text/html' href='http://mscrmuk.blogspot.com/2008/05/posting-on-microsoft-dynamics-crm-team.html' title='Posting on Microsoft Dynamics CRM Team Blog'/><author><name>David Jennaway</name><uri>http://www.blogger.com/profile/09695858105618938443</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-199106851038957806.post-716423680908056698</id><published>2008-05-21T08:13:00.001+01:00</published><updated>2008-05-22T09:22:38.458+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Server code'/><category scheme='http://www.blogger.com/atom/ns#' term='Plugin'/><category scheme='http://www.blogger.com/atom/ns#' term='Code Gallery'/><category scheme='http://www.blogger.com/atom/ns#' term='CRM 4.0'/><title type='text'>Some Plugin Tools</title><content type='html'>I've posted 2 resources (.Net projects) to the &lt;a href="http://code.msdn.microsoft.com/"&gt;MSDN Code Gallery&lt;/a&gt; to assist with writing and deploying plugins for CRM 4.0.&lt;br /&gt;&lt;br /&gt;One tool is a &lt;a href="http://code.msdn.microsoft.com/crm40pluginlogger"&gt;logging tool&lt;/a&gt; This writes details about any plugin event to SQL tables. This records standard event data - date, message, primary entity, stage and pipeline - and also any data passed in property bags - InputParameter, OutputParameter, PreEntityImage, PostEntityImage and SharedVariable. I find this very useful when determining what information is passed for each message.&lt;br /&gt;&lt;br /&gt;The other tool is a &lt;a href="http://code.msdn.microsoft.com/crm40pluginbulk"&gt;registration tool&lt;/a&gt;. This is a set of enhancements to the plugindeveloper that is included in the &lt;a href="http://msdn.microsoft.com/en-us/library/bb928212.aspx"&gt;CRM 4.0.4 SDK&lt;/a&gt;. The main enhancement is to allow registration of a plugin against all messages or all entities. I use this in conjunction with the logging tool to allow me to quickly build an environment that captures all customisable plugin events on a CRM deployment. This tool makes use of the sdkmessagefilter class to determine which combinations of plugin event and message are available on a CRM deployment&lt;br /&gt;&lt;br /&gt;Both resources on the Code Gallery contain the full source code, which is made available under the Microsoft Public License (Ms-PL), as well as installation instructions&lt;br /&gt;&lt;br /&gt;More information about these tools, and an explanation of the code will shortly be posted on the &lt;a href="http://blogs.msdn.com/crm/"&gt;Microsoft Dynamics CRM Team Blog&lt;/a&gt;. Rather than repeat the content here, I'll post a link when it's live.&lt;br /&gt;&lt;br /&gt;Updated 21-05-08: The Team Blog link is &lt;a href="http://blogs.msdn.com/crm/archive/2008/05/21/plugins-which-message-and-which-pipeline.aspx"&gt;http://blogs.msdn.com/crm/archive/2008/05/21/plugins-which-message-and-which-pipeline.aspx&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/199106851038957806-716423680908056698?l=mscrmuk.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://mscrmuk.blogspot.com/feeds/716423680908056698/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=199106851038957806&amp;postID=716423680908056698' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/199106851038957806/posts/default/716423680908056698'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/199106851038957806/posts/default/716423680908056698'/><link rel='alternate' type='text/html' href='http://mscrmuk.blogspot.com/2008/05/some-plugin-tools.html' title='Some Plugin Tools'/><author><name>David Jennaway</name><uri>http://www.blogger.com/profile/09695858105618938443</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-199106851038957806.post-3287207674576053345</id><published>2008-04-21T15:02:00.005+01:00</published><updated>2008-04-21T16:00:37.004+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='CRM 4.0'/><category scheme='http://www.blogger.com/atom/ns#' term='Upgrade'/><category scheme='http://www.blogger.com/atom/ns#' term='CRM 3.0'/><title type='text'>CRM 4.0 Upgrade error. An item with the same key has already been added</title><content type='html'>Recently when testing a CRM 4.0 upgrade for a customer, I got the error 'An item with the same key has already been added'. I'm not the first to have met this problem (see the MS newsgroup), and probably won't be the last).&lt;br /&gt;&lt;br /&gt;From what I've found so far there are 2 possible causes, both to do with CRM believing there are duplicate field names. Either a duplication has occured between a custom field, and a virtual field, or you have somehow got a duplicate entry in FieldXml.&lt;br /&gt;&lt;br /&gt;&lt;strong&gt;Duplication between a custom field, and a virtual field&lt;/strong&gt;&lt;br /&gt;For certain field types (boolean, picklist and lookup), CRM creates an additional attribute in the metadata for the text of the field. This attrbiute is not physically stored, and is considered to be a 'virtual' field. The virtaul attribute has the name of the base field + a suffix of 'name'. For example, the prioritycode picklist field results in a corresponding prioritycodename virtual field, and a custom lookup field new_accountid would result in a virtual field new_accountidname (there is also a new_accountiddsc virtual).&lt;br /&gt;&lt;br /&gt;This can cause a problem if you created an additional, physical field with the same name as a virtual field. CRM will let you do this, but the upgrade could fail.&lt;br /&gt;&lt;br /&gt;To determine if this is a potential problem, run the following SQL script in the METABASE SQL database. This will return a list of any duplicates (you'll need dbo rights to run the script)&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family:courier new;font-size:85%;"&gt;select e.name as entity, a.name as attribute, count(*) &lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;font-size:85%;"&gt;from attribute a join entity e on a.entityid = e.entityid&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;font-size:85%;"&gt;group by e.name, a.name&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;font-size:85%;"&gt;having count(*) &gt; 1&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;If you've found duplicates, your only solution is to remove the duplicate field from CRM.&lt;br /&gt;&lt;br /&gt;Duplicate entry in FieldXml&lt;br /&gt;CRM stores metadata in several places in CRM. One of them is the OrganizationUIBase table in the MSCRM database. Within this table, some data is stored in the FieldXml field. This is an XML document that looks something like this:&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family:courier new;font-size:85%;"&gt;&amp;lt;entity name="prism_utilisationperiod" objecttypecode="10003"&amp;gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;font-size:85%;"&gt;&amp;lt;fields&amp;gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;font-size:85%;"&gt;&amp;lt;field name="prism_utilisationperiodid" requiredlevel="na"&amp;gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;font-size:85%;"&gt;&amp;lt;displaynames&amp;gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;font-size:85%;"&gt;&amp;lt;displayname description="UtilisationPeriod" languagecode="1033" /&amp;gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;font-size:85%;"&gt;&amp;lt;/displaynames&amp;gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;font-size:85%;"&gt;&amp;lt;/field&amp;gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;font-size:85%;"&gt;&amp;lt;field name="createdon" requiredlevel="na" format="date"&amp;gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;font-size:85%;"&gt;&amp;lt;displaynames&amp;gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;font-size:85%;"&gt;&amp;lt;displayname description="Created On" languagecode="1033" /&amp;gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;font-size:85%;"&gt;&amp;lt;/displaynames&amp;gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;font-size:85%;"&gt;&amp;lt;/field&amp;gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;font-size:85%;"&gt;&amp;lt;/fields&amp;gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;font-size:85%;"&gt;&amp;lt;/entity&amp;gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;There should only be one field element for each CRM attribute, but the problem I had was that a field element was duplicated.&lt;br /&gt;&lt;br /&gt;To determine any duplicate fields, use the following SQL in the MSCRM database:&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family:courier new;font-size:85%;"&gt;declare @fieldXml nvarchar(max), @otc int, @idoc int&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;font-size:85%;"&gt;declare curEntity cursor fast_forward for&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;font-size:85%;"&gt;select ObjectTypeCode, FieldXml from OrganizationUIBase where InProduction = 1&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;font-size:85%;"&gt;open curEntity&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;font-size:85%;"&gt;fetch next from curEntity into @otc, @fieldXml&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;font-size:85%;"&gt;while @@fetch_status = 0&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;font-size:85%;"&gt;begin&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;font-size:85%;"&gt;EXEC sp_xml_preparedocument @idoc OUTPUT, @fieldXml&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;font-size:85%;"&gt;if exists ( select name as field from OpenXML(@idoc, '/entity/fields/field') WITH (name nvarchar(64)) group by name having count(*) &amp;gt; 1 )&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;font-size:85%;"&gt;select @otc as otc, name as field, count(*) as occurences &lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;font-size:85%;"&gt;from OpenXML(@idoc, '/entity/fields/field') WITH (name nvarchar(64))&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;font-size:85%;"&gt;group by name&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;font-size:85%;"&gt;having count(*) &amp;gt; 1&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;font-size:85%;"&gt;EXEC sp_xml_removedocument @idoc &lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;font-size:85%;"&gt;fetch next from curEntity into @otc, @fieldXml&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;font-size:85%;"&gt;end&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;font-size:85%;"&gt;close curEntity&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;font-size:85%;"&gt;deallocate curEntity&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;This will list the objecttypecode and attribute name of any duplicates. If you have duplicates, the resolution is to export the customisations for the relevant entities, delete any duplicate field elements from the customisation xml, then reimport the xml and publish the entities.&lt;br /&gt;&lt;br /&gt;Credit is due to Michael Hohne and Kesh Patel who've contributed to finding the problems and solutions.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/199106851038957806-3287207674576053345?l=mscrmuk.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://mscrmuk.blogspot.com/feeds/3287207674576053345/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=199106851038957806&amp;postID=3287207674576053345' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/199106851038957806/posts/default/3287207674576053345'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/199106851038957806/posts/default/3287207674576053345'/><link rel='alternate' type='text/html' href='http://mscrmuk.blogspot.com/2008/04/crm-40-upgrade-error-item-with-same-key.html' title='CRM 4.0 Upgrade error. An item with the same key has already been added'/><author><name>David Jennaway</name><uri>http://www.blogger.com/profile/09695858105618938443</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-199106851038957806.post-5510400904845834467</id><published>2008-04-03T17:37:00.002+01:00</published><updated>2008-04-03T18:10:46.300+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Email Templates'/><category scheme='http://www.blogger.com/atom/ns#' term='CRM 3.0'/><title type='text'>Email Templates with Custom Entities</title><content type='html'>I've recently been doing some development work creating emails based on templates. In most cases this is &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_0"&gt;straightforward&lt;/span&gt;, once you've applied &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_1"&gt;CRM&lt;/span&gt; 3.0 Update &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_2"&gt;Rollup&lt;/span&gt; 1, 2 or 3, and also updated any web references. However, there are a couple of quirks I found when trying to use custom entities.&lt;br /&gt;&lt;br /&gt;First; you can only use Global templates with custom entities. &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_3"&gt;CRM&lt;/span&gt; 3.0 does not allow you to create an entity-specific template. This led to the first quirk; I was using a &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_4"&gt;QueryExpression&lt;/span&gt; to find a specific template by name, and also &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_5"&gt;templatetypecode&lt;/span&gt; (as &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_6"&gt;CRM&lt;/span&gt; allows you to create templates with the same name but on different entities). When searching for a Global template, the &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_7"&gt;templatetypecode&lt;/span&gt; is &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_8"&gt;systemuser&lt;/span&gt;, rather than null as I was expecting.&lt;br /&gt;&lt;br /&gt;Next, when using &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_9"&gt;InstantiateTemplateRequest&lt;/span&gt;, it failed if the &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_10"&gt;ObjectType&lt;/span&gt; were set to any custom entity. The error message is the unhelpful 'An unexpected error &lt;span class="blsp-spelling-corrected" id="SPELLING_ERROR_11"&gt;occurred&lt;/span&gt;'. Again, the solution is to treat a Global template as if it were actually a template for the &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_12"&gt;systemuser&lt;/span&gt; entity. Therefore to make it work you have to specify an &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_13"&gt;ObjectId&lt;/span&gt; and &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_14"&gt;ObjectType&lt;/span&gt; for a &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_15"&gt;systemuser&lt;/span&gt; - it doesn't seem to matter which &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_16"&gt;systemuserid&lt;/span&gt; you use.&lt;br /&gt;&lt;br /&gt;Putting this together, the following code shows how to create an email based on a template for a custom entity:&lt;br /&gt;&lt;blockquote&gt;&lt;p&gt;&lt;br /&gt;&lt;span style="font-family:courier new;font-size:85%;"&gt;public email &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_17"&gt;CreateEmailFromGlobalTemplate&lt;/span&gt;(string &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_18"&gt;TemplateName&lt;/span&gt;, string &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_19"&gt;EntityTypeName&lt;/span&gt;, &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_20"&gt;Guid&lt;/span&gt; &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_21"&gt;ObjectId&lt;/span&gt;, &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_22"&gt;Guid&lt;/span&gt; &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_23"&gt;SomeUserId&lt;/span&gt;) &lt;br /&gt;&lt;/span&gt;&lt;span style="font-family:courier new;font-size:85%;"&gt;{  &lt;br /&gt; &lt;/span&gt;&lt;span style="font-family:courier new;font-size:85%;"&gt;&lt;span class="blsp-spelling-error" id="SPELLING_ERROR_24"&gt;QueryByAttribute&lt;/span&gt; &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_25"&gt;qa&lt;/span&gt; = new &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_26"&gt;QueryByAttribute&lt;/span&gt;();&lt;br /&gt; &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_27"&gt;qa&lt;/span&gt;.&lt;span class="blsp-spelling-error" id="SPELLING_ERROR_28"&gt;EntityName&lt;/span&gt; = EntityName.template.ToString();&lt;br /&gt; &lt;/span&gt;&lt;span style="font-family:courier new;font-size:85%;"&gt;&lt;span class="blsp-spelling-error" id="SPELLING_ERROR_29"&gt;qa&lt;/span&gt;.Attributes  = new string[] {"title", "&lt;span class="blsp-spelling-error" id="SPELLING_ERROR_30"&gt;templatetypecode&lt;/span&gt;"};&lt;br /&gt; &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_31"&gt;qa&lt;/span&gt;.Values = new object[] {&lt;span class="blsp-spelling-error" id="SPELLING_ERROR_32"&gt;TemplateName&lt;/span&gt;, EntityName.systemuser.ToString()};  // Use &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_33"&gt;systemuser&lt;/span&gt; for global template &lt;br /&gt; &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_34"&gt;ColumnSet&lt;/span&gt; cs = new &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_35"&gt;ColumnSet&lt;/span&gt;(); &lt;br /&gt; cs.Attributes = new string[]{"&lt;span class="blsp-spelling-error" id="SPELLING_ERROR_36"&gt;templateid&lt;/span&gt;"}; &lt;br /&gt; &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_37"&gt;qa&lt;/span&gt;.&lt;span class="blsp-spelling-error" id="SPELLING_ERROR_38"&gt;ColumnSet&lt;/span&gt; = cs; &lt;br /&gt; &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_39"&gt;BusinessEntityCollection&lt;/span&gt; &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_40"&gt;bec&lt;/span&gt; = &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_41"&gt;svc&lt;/span&gt;.&lt;span class="blsp-spelling-error" id="SPELLING_ERROR_42"&gt;RetrieveMultiple&lt;/span&gt;(&lt;span class="blsp-spelling-error" id="SPELLING_ERROR_43"&gt;qa&lt;/span&gt;); &lt;br /&gt; if (&lt;span class="blsp-spelling-error" id="SPELLING_ERROR_44"&gt;bec&lt;/span&gt; == null &amp;amp;&amp;amp; bec.BusinessEntities.Length == 0) &lt;br /&gt;  throw new Exception("Cannot find template"); &lt;br /&gt; &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_45"&gt;Guid&lt;/span&gt; &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_46"&gt;templateId&lt;/span&gt; = ((template) bec.BusinessEntities[0]).templateid.Value; &lt;br /&gt; &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_47"&gt;InstantiateTemplateRequest&lt;/span&gt; &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_48"&gt;req&lt;/span&gt; = new &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_49"&gt;InstantiateTemplateRequest&lt;/span&gt;(); &lt;br /&gt; &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_50"&gt;req&lt;/span&gt;.&lt;span class="blsp-spelling-error" id="SPELLING_ERROR_51"&gt;ObjectId&lt;/span&gt; = &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_52"&gt;SomeUserId&lt;/span&gt;;  // Any valid &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_53"&gt;systemuserid&lt;/span&gt; &lt;br /&gt; &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_54"&gt;req&lt;/span&gt;.&lt;span class="blsp-spelling-error" id="SPELLING_ERROR_55"&gt;ObjectType&lt;/span&gt; = EntityName.systemuser.ToString();  // Use &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_56"&gt;systemuser&lt;/span&gt; for global template &lt;br /&gt; &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_57"&gt;req&lt;/span&gt;.&lt;span class="blsp-spelling-error" id="SPELLING_ERROR_58"&gt;TemplateId&lt;/span&gt; = &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_59"&gt;templateId&lt;/span&gt;; &lt;br /&gt; &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_60"&gt;InstantiateTemplateResponse&lt;/span&gt; resp = (&lt;span class="blsp-spelling-error" id="SPELLING_ERROR_61"&gt;InstantiateTemplateResponse&lt;/span&gt;) &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_62"&gt;svc&lt;/span&gt;.Execute(&lt;span class="blsp-spelling-error" id="SPELLING_ERROR_63"&gt;req&lt;/span&gt;); &lt;br /&gt; if (resp == null &amp;amp;&amp;amp; resp.BusinessEntityCollection.BusinessEntities.Length == 0) &lt;br /&gt;  throw new Exception("Cannot create email"); &lt;br /&gt; email &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_64"&gt;newMail&lt;/span&gt; = (email) resp.BusinessEntityCollection.BusinessEntities[0]; &lt;br /&gt; &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_65"&gt;newMail&lt;/span&gt;.&lt;span class="blsp-spelling-error" id="SPELLING_ERROR_66"&gt;regardingobjectid&lt;/span&gt; = new &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_67"&gt;Lookup&lt;/span&gt;(); &lt;br /&gt; newMail.regardingobjectid.type = &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_68"&gt;EntityTypeName&lt;/span&gt;; &lt;br /&gt; newMail.regardingobjectid.Value = &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_69"&gt;ObjectId&lt;/span&gt;; &lt;br /&gt;&lt;/span&gt;&lt;span style="font-family:courier new;font-size:85%;"&gt; return &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_70"&gt;newMail&lt;/span&gt;; &lt;br /&gt;}&lt;/span&gt;&lt;br /&gt;&lt;/p&gt;&lt;/blockquote&gt;&lt;br /&gt;One more thing to bear in mind: If you use &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_71"&gt;InstantiateTemplateRequest&lt;/span&gt; then the code has to run under a &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_72"&gt;CRM&lt;/span&gt; context of a live user, rather than the SYSTEM user, otherwise you will get the error 'The specified users settings have not yet been created' - I guess because &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_73"&gt;CRM&lt;/span&gt; also looks at user templates&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/199106851038957806-5510400904845834467?l=mscrmuk.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://mscrmuk.blogspot.com/feeds/5510400904845834467/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=199106851038957806&amp;postID=5510400904845834467' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/199106851038957806/posts/default/5510400904845834467'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/199106851038957806/posts/default/5510400904845834467'/><link rel='alternate' type='text/html' href='http://mscrmuk.blogspot.com/2008/04/email-templates-with-custom-entities.html' title='Email Templates with Custom Entities'/><author><name>David Jennaway</name><uri>http://www.blogger.com/profile/09695858105618938443</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-199106851038957806.post-7464697295756997589</id><published>2008-03-03T18:11:00.000Z</published><updated>2008-04-03T18:19:16.329+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Workflow'/><category scheme='http://www.blogger.com/atom/ns#' term='CRM 3.0'/><title type='text'>Workflow assembly. Trying to make a Lookup parameter optional</title><content type='html'>When creating a workflow assembly for CRM 3.0, CRM has no proper understanding of optional parameters. The best way to cope with this is to specify a default value in the workflow.config file, but I found a weird issue with parameters of type lookup.&lt;br /&gt;&lt;br /&gt;What I expected to able to do was specify a default of {00000000-0000-0000-0000-000000000000} which would map to Guid.Empty. Creating a rule in Workflow Manager was fine, but when it came the running the rule, it failed prior to calling the assembly with the following error in Workflow Monitor:&lt;br /&gt;&lt;br /&gt;'Error code = 800040005. The Microsoft CRM server is unavailable. There is a problem communicating with the Microsoft CRM server.' This is obviously an incorrect error message, given the message itself was written to the CRM server. Further investigation showed the problem was with the above Guid, and anything other than an empty Guid works fine, so I now use {FFFFFFFF-FFFF-FFFF-FFFF-FFFFFFFFFFFF}&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/199106851038957806-7464697295756997589?l=mscrmuk.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://mscrmuk.blogspot.com/feeds/7464697295756997589/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=199106851038957806&amp;postID=7464697295756997589' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/199106851038957806/posts/default/7464697295756997589'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/199106851038957806/posts/default/7464697295756997589'/><link rel='alternate' type='text/html' href='http://mscrmuk.blogspot.com/2008/03/workflow-assembly-trying-to-make-lookup.html' title='Workflow assembly. Trying to make a Lookup parameter optional'/><author><name>David Jennaway</name><uri>http://www.blogger.com/profile/09695858105618938443</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-199106851038957806.post-7896729200355072919</id><published>2008-01-30T19:00:00.000Z</published><updated>2008-01-30T19:11:34.564Z</updated><category scheme='http://www.blogger.com/atom/ns#' term='Server code'/><category scheme='http://www.blogger.com/atom/ns#' term='Customisation'/><category scheme='http://www.blogger.com/atom/ns#' term='Reports'/><title type='text'>MSDN Code Gallery</title><content type='html'>Microsoft have just made the new &lt;a href="http://code.msdn.microsoft.com/"&gt;MSDN Code Gallery&lt;/a&gt; live. This is a site for sharing sample code, and I've posted some of my example code from previous blog articles. So far I've posted the following 4 resources:&lt;br /&gt;&lt;br /&gt;&lt;a class="Bold" id="ctl00_Content_NewProjects_Sidebar_ProjectRepeater_ctl00_ProjectLink" href="http://code.msdn.microsoft.com/mscrmlocaldatagroup"&gt;MSCRM: Automate Local Data Group creation&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;a class="Bold" id="ctl00_Content_NewProjects_Sidebar_ProjectRepeater_ctl01_ProjectLink" href="http://code.msdn.microsoft.com/MSCRMFilesByAccount"&gt;Microsoft CRM report of all files related to an account&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;a class="Bold" id="ctl00_Content_NewProjects_Sidebar_ProjectRepeater_ctl04_ProjectLink" href="http://code.msdn.microsoft.com/MSCRMPageHost"&gt;MSCRM - web page hosting to extend client script&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;a class="Bold" id="ctl00_Content_NewProjects_Sidebar_ProjectRepeater_ctl05_ProjectLink" href="http://code.msdn.microsoft.com/MSCRMIFrameReports"&gt;Writing reports to use in IFrames and from ISV.Config in Microsoft Dynamics CRM&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;For reference, if you want to search for CRM examples, there's an emerging tagging protocol to tag all CRM examples as both CRM and Dynamics, so you can search on either tag. I'm also tagging samples with reports as 'Reporting Services'&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/199106851038957806-7896729200355072919?l=mscrmuk.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://mscrmuk.blogspot.com/feeds/7896729200355072919/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=199106851038957806&amp;postID=7896729200355072919' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/199106851038957806/posts/default/7896729200355072919'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/199106851038957806/posts/default/7896729200355072919'/><link rel='alternate' type='text/html' href='http://mscrmuk.blogspot.com/2008/01/msdn-code-gallery.html' title='MSDN Code Gallery'/><author><name>David Jennaway</name><uri>http://www.blogger.com/profile/09695858105618938443</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-199106851038957806.post-9173047192401565218</id><published>2008-01-26T14:13:00.000Z</published><updated>2008-01-27T18:10:43.166Z</updated><category scheme='http://www.blogger.com/atom/ns#' term='Reports'/><title type='text'>Scheduling and emailing reports with CRM</title><content type='html'>A common customer request is to be able to schedule CRM reports and automatically send the report to one or more users by email. This can be done without the need for any code, but needs a combination of configuration within both CRM and Reporting Services.&lt;br /&gt;&lt;br /&gt;&lt;strong&gt;CRM Configuration&lt;/strong&gt;&lt;br /&gt;CRM reports are designed to be run under the context of the user running the report so as to return only the data that user has permission to see. Due to this configuration, Reporting Services will not permit you to schedule CRM Reports out of the box (if you try, you'll get the error 'Subscriptions cannot be created because the credentials used to run the report are not stored') . The easiest way to resolve this issue is to download the CRM Report Scheduling Wizard from &lt;a href="http://www.microsoft.com/downloads/details.aspx?FamilyID=a101d4d9-6463-4a45-899b-3c3ee979c4d0&amp;amp;DisplayLang=en"&gt;here&lt;/a&gt; and install it on the CRM server.&lt;br /&gt;&lt;br /&gt;Then, navigate to Workplace, Reports in CRM, select the report you want to schedule, and go to More Actions, Schedule Report. As you will do the scheduling later within Report Manager, I'd suggest you select the following options:&lt;br /&gt;&lt;ul&gt;&lt;li&gt;Generate snapshots 'On demand'&lt;/li&gt;&lt;li&gt;'Make snapshots available only to me'&lt;/li&gt;&lt;li&gt;Specify any parameter values&lt;/li&gt;&lt;li&gt;You then need to specify the credentials under which the report will run. This needs to be a valid CRM user&lt;/li&gt;&lt;li&gt;'Yes, generate the snapshot now'&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;&lt;strong&gt;Reporting Services configuration&lt;/strong&gt;&lt;br /&gt;The rest of the configuration is done via Reporting Services. First of all, you may have to configure the email properties of Reporting Services. To do this open RSReportServer.config, which by default will be in the Reporting Services\ReportServer directory under the SQL installation directory in Program Files. Within the 'RSEmailDPConfiguration' element you will need to set values in, as a minimum, the 'SMTPServer' and 'From' elements. You may need to apply other settings. For more information see the documentation for &lt;a href="http://msdn2.microsoft.com/en-us/library/ms159155.aspx"&gt;SQL 2005&lt;/a&gt; or &lt;a href="http://msdn2.microsoft.com/en-us/library/aa972234(SQL.80).aspx"&gt;SQL 2000&lt;/a&gt;&lt;/p&gt;&lt;p&gt;&lt;strong&gt;Scheduling the Report in Report Manager&lt;/strong&gt;&lt;br /&gt;You can now schedule the report. Browse to Report Manager (by default it will be in the Reports virtual directory), go to the OrganisationName_MSCRM folder and the report you have scheduled (it's name will have the suffix On demand Snapshot). On the toolbar you should have a button 'New Subscription'. Click this, select 'Report Server E-mail' in the Delivered by drop down, and set all other options as required. (If 'Report Server E-mail' is not an option, go back to the instructions in the above paragraph&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/199106851038957806-9173047192401565218?l=mscrmuk.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://mscrmuk.blogspot.com/feeds/9173047192401565218/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=199106851038957806&amp;postID=9173047192401565218' title='14 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/199106851038957806/posts/default/9173047192401565218'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/199106851038957806/posts/default/9173047192401565218'/><link rel='alternate' type='text/html' href='http://mscrmuk.blogspot.com/2008/01/scheduling-and-emailing-reports-with.html' title='Scheduling and emailing reports with CRM'/><author><name>David Jennaway</name><uri>http://www.blogger.com/profile/09695858105618938443</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>14</thr:total></entry><entry><id>tag:blogger.com,1999:blog-199106851038957806.post-1578616561404987095</id><published>2008-01-14T16:07:00.000Z</published><updated>2008-01-14T22:53:21.890Z</updated><category scheme='http://www.blogger.com/atom/ns#' term='CRM 4.0'/><category scheme='http://www.blogger.com/atom/ns#' term='ASP .Net'/><category scheme='http://www.blogger.com/atom/ns#' term='Upgrade'/><title type='text'>CRM 4.0 Error with ISV pages: MultipleOrganizationSoapHeaderAuthenticationProvider</title><content type='html'>If you have a CRM 3.0 Server with custom ASP.Net pages in a virtual directory within the CRM website, when you upgrade the server to CRM 4.0, the custom pages fail, giving the error:&lt;br /&gt;&lt;br /&gt;Microsoft.Crm.WebServices.Crm2007.MultipleOrganizationSoapHeaderAuthenticationProvider, Microsoft.Crm.WebServices, Version=4.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35' doesn't exist&lt;br /&gt;&lt;br /&gt;You can also get the same error when creating a new virtual directory within the CRM website.&lt;br /&gt;&lt;br /&gt;The reason for the error is that CRM adds 2 HttpModules (MapOrg and CrmAuthentication) to web.config in the root of the CRM website. The CrmAuthentication HttpModule is in the microsoft.crm.webservices.dll assembly, which is not in the path of the custom virtual directory.&lt;br /&gt;There are two solutions to this. Either:&lt;br /&gt;&lt;ol&gt;&lt;li&gt;Ensure microsoft.crm.webservices.dll can be found. To do this, add it to the global assembly cache, then run iisreset (or recycle the CrmAppPool application pool)&lt;/li&gt;&lt;li&gt;Remove the CrmAuthentication HttpModule from the virtual directory. I haven't fully investigated whether this adversely impacts use of the CRM 4.0 web services endpoint, but can be safely done if the ASP &gt;net pages use the CRM 3.0 web services endpoint (or don't access CRM web services at all). To remove the HttpModule, add the following to the web.config in the custom virtual directory (within the system.web element):&lt;/li&gt;&lt;/ol&gt;&lt;p&gt;&lt;span style="font-family:courier new;font-size:85%;"&gt;&lt;httpmodules&gt;&amp;lt;httpModules&amp;gt;&lt;br /&gt; &amp;lt;remove name ="CrmAuthentication" /&amp;gt;&lt;br /&gt;&amp;lt;/httpModules&amp;gt;&lt;/httpmodules&gt;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;httpmodules&gt;&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/199106851038957806-1578616561404987095?l=mscrmuk.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://mscrmuk.blogspot.com/feeds/1578616561404987095/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=199106851038957806&amp;postID=1578616561404987095' title='6 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/199106851038957806/posts/default/1578616561404987095'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/199106851038957806/posts/default/1578616561404987095'/><link rel='alternate' type='text/html' href='http://mscrmuk.blogspot.com/2008/01/crm-40-error-with-isv-pages.html' title='CRM 4.0 Error with ISV pages: MultipleOrganizationSoapHeaderAuthenticationProvider'/><author><name>David Jennaway</name><uri>http://www.blogger.com/profile/09695858105618938443</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>6</thr:total></entry><entry><id>tag:blogger.com,1999:blog-199106851038957806.post-7117439393221452700</id><published>2007-12-20T21:49:00.000Z</published><updated>2007-12-23T22:03:22.029Z</updated><category scheme='http://www.blogger.com/atom/ns#' term='CRM 4.0'/><category scheme='http://www.blogger.com/atom/ns#' term='Installation'/><title type='text'>CRM 4.0 - Installation with no Internet Access</title><content type='html'>The current set of downloadable files for CRM 4.0 do not include some pre-requisite software (including .Net 3.0 framework and Visual C++ redistributable). If this software is not already installed and the setup program can't find it locally, the CRM setup program can download the files from the Internet, which is fine, if you have Internet access from the CRM server...&lt;br /&gt;&lt;br /&gt;If you don't have Internet access you can pre-install these components, except the Visual C++ redistributable which cannot be reliably detected, so the CRM setup program will always try to install it.&lt;br /&gt;&lt;br /&gt;Therefore, without Internet access, you have to have a local copy of the Visual C++ redistributable locally. Philip Richardson's &lt;a href="http://www.philiprichardson.org/blog/post/Installing-CRM-40-without-Internet-Access.aspx"&gt;blog&lt;/a&gt; describes where to put these files, so I won't bother repeating it here, but there are a couple of extra things that it might help to know:&lt;br /&gt;&lt;ol&gt;&lt;li&gt;CRM setup checks the version of the local copy of the redistributable, and if it's not what it expects, will again try to connect to the Internet. You can identify this scenario from the setup log; the message is "Error when checking signature", though oddly it's marked as an Info message&lt;/li&gt;&lt;li&gt;CRM setup only checks for local files when it starts. So if, like me, you get to the screen where it expects to download the files, realise it won't be able to, then copy them locally, then go Back, Forward, it won't help. Instead, exit setup completely and start over again&lt;/li&gt;&lt;/ol&gt;&lt;p&gt;As to Internet access from the CRM server, in most circumstances this can be achieved from a VPC image with the use of more than one network adapter. See my earlier &lt;a href="http://mscrmuk.blogspot.com/2007/11/external-access-from-virtual.html"&gt;post&lt;/a&gt;&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/199106851038957806-7117439393221452700?l=mscrmuk.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://mscrmuk.blogspot.com/feeds/7117439393221452700/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=199106851038957806&amp;postID=7117439393221452700' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/199106851038957806/posts/default/7117439393221452700'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/199106851038957806/posts/default/7117439393221452700'/><link rel='alternate' type='text/html' href='http://mscrmuk.blogspot.com/2007/12/crm-40-installation-with-no-internet.html' title='CRM 4.0 - Installation with no Internet Access'/><author><name>David Jennaway</name><uri>http://www.blogger.com/profile/09695858105618938443</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-199106851038957806.post-6695632972508042715</id><published>2007-12-20T14:49:00.000Z</published><updated>2007-12-20T15:00:52.297Z</updated><category scheme='http://www.blogger.com/atom/ns#' term='Client Code'/><category scheme='http://www.blogger.com/atom/ns#' term='CRM 4.0'/><category scheme='http://www.blogger.com/atom/ns#' term='Upgrade'/><title type='text'>CRM 4.0 - Client script changes from CRM 3.0</title><content type='html'>&lt;span style="font-family:arial;"&gt;This post is intended to be a dumping ground that I'll update as and when I, or my colleagues, find issues that may affect the upgrade of CRM 3.0 implementations with client script.&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:arial;"&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:arial;"&gt;&lt;strong&gt;RemoteCommand - removal of some options&lt;/strong&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:arial;"&gt;In CRM 3.0 it was possible to make unsupported use of the client-side RemoteCommand function to make server-side calls, e.g. the following got the current CRM user id&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family:courier new;font-size:85%;"&gt;var cmd = new RemoteCommand("SystemUser", "WhoAmI", "/MSCRMServices/");&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;font-size:85%;"&gt;var res = command.Execute(); &lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;font-size:85%;"&gt;if (res.Success) &lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;font-size:85%;"&gt; return res.ReturnValue.UserId;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:arial;font-size:85%;"&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:Arial;"&gt;What this did was make a request to the SystemUser.asmx (1st parameter) file in the MSCRMServices (3rd parameter) directory. Almost all of these files have been removed in CRM 4.0, so code like that above will fail.&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:Arial;"&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:Arial;"&gt;I can't see any obvious equivalent calls to make in CRM 4.0, but as the use of RemoteCommand is unsupported, I wouldn't expect there to be. My preferred option has always been to write a server-side wrapper around calls the CrmService web service, and call them directly using the XmlHttp ActiveX object, thus keeping within supported functionality.&lt;/span&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/199106851038957806-6695632972508042715?l=mscrmuk.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://mscrmuk.blogspot.com/feeds/6695632972508042715/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=199106851038957806&amp;postID=6695632972508042715' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/199106851038957806/posts/default/6695632972508042715'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/199106851038957806/posts/default/6695632972508042715'/><link rel='alternate' type='text/html' href='http://mscrmuk.blogspot.com/2007/12/crm-40-client-script-changes-from-crm.html' title='CRM 4.0 - Client script changes from CRM 3.0'/><author><name>David Jennaway</name><uri>http://www.blogger.com/profile/09695858105618938443</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-199106851038957806.post-4806907448912619909</id><published>2007-12-20T14:41:00.000Z</published><updated>2007-12-20T14:49:14.632Z</updated><category scheme='http://www.blogger.com/atom/ns#' term='CRM 4.0'/><category scheme='http://www.blogger.com/atom/ns#' term='Upgrade'/><title type='text'>CRM 4.0</title><content type='html'>As the RTM code for CRM 4.0 is now available (&lt;a href="http://philiprichardson.org/blog/post/CRM-40-Downloads.aspx"&gt;http://philiprichardson.org/blog/post/CRM-40-Downloads.aspx&lt;/a&gt;), I figure it's time to start recording some of the changes from CRM 3.0, and associated upgrade issues.&lt;br /&gt;&lt;br /&gt;As such I'm going to create a few posts that I'll add to as we find out more about CRM 4.0; the first ones will be on client script changes, server code and upgrade issues&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/199106851038957806-4806907448912619909?l=mscrmuk.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://mscrmuk.blogspot.com/feeds/4806907448912619909/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=199106851038957806&amp;postID=4806907448912619909' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/199106851038957806/posts/default/4806907448912619909'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/199106851038957806/posts/default/4806907448912619909'/><link rel='alternate' type='text/html' href='http://mscrmuk.blogspot.com/2007/12/crm-40.html' title='CRM 4.0'/><author><name>David Jennaway</name><uri>http://www.blogger.com/profile/09695858105618938443</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-199106851038957806.post-7081287657564830725</id><published>2007-12-20T12:19:00.000Z</published><updated>2007-12-20T12:26:31.705Z</updated><category scheme='http://www.blogger.com/atom/ns#' term='SSIS'/><category scheme='http://www.blogger.com/atom/ns#' term='SQL Server'/><title type='text'>Stored procedures in SSIS; the need for nocount</title><content type='html'>I've been doing a lot of SSIS work lately, and met an odd problem when using stored procedures in an OLEDB source. The general idea was to have a stored procedure that did some data modification, then finished with a SELECT statement to output logging information.&lt;br /&gt;&lt;br /&gt;When previewing the OLEDB source everything was fine, but running the package would give the following error in the pre-execute phase:&lt;br /&gt;'A rowset based on the SQL command was not returned by the OLE DB provider'&lt;br /&gt;&lt;br /&gt;It took a while to work out, but eventually the problem came down to the way that SQL Server returns information about the number of rows affected. The resolution is to put the following SQL statement at the start of the stored procedure defnition to prevent output of the number of rows:&lt;br /&gt;&lt;br /&gt;SET NOCOUNT ON&lt;br /&gt;&lt;br /&gt;After that it was all fine.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/199106851038957806-7081287657564830725?l=mscrmuk.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://mscrmuk.blogspot.com/feeds/7081287657564830725/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=199106851038957806&amp;postID=7081287657564830725' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/199106851038957806/posts/default/7081287657564830725'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/199106851038957806/posts/default/7081287657564830725'/><link rel='alternate' type='text/html' href='http://mscrmuk.blogspot.com/2007/12/stored-procedures-in-ssis-need-for.html' title='Stored procedures in SSIS; the need for nocount'/><author><name>David Jennaway</name><uri>http://www.blogger.com/profile/09695858105618938443</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-199106851038957806.post-8045921367838435654</id><published>2007-12-14T17:29:00.000Z</published><updated>2007-12-14T17:33:38.135Z</updated><category scheme='http://www.blogger.com/atom/ns#' term='Customisation'/><category scheme='http://www.blogger.com/atom/ns#' term='CRM 3.0'/><title type='text'>Automating Local Data Query Creation</title><content type='html'>I've been invited to post on the &lt;a href="http://blogs.msdn.com/crm/"&gt;Microsoft Dynamics CRM Team Blog&lt;/a&gt; again. This time I posted about how to automate the creation of the local data groups that specify what data each user of the Laptop client take offline.&lt;br /&gt;&lt;br /&gt;Rather than repeating the text, you can read the article &lt;a href="http://blogs.msdn.com/crm/archive/2007/12/14/crm-blog-automating-local-data-query-creation.aspx"&gt;here&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;I've posted sample code for the article on &lt;a href="http://www.codeplex.com/mscrmlocaldatagroup"&gt;CodePlex&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/199106851038957806-8045921367838435654?l=mscrmuk.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://mscrmuk.blogspot.com/feeds/8045921367838435654/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=199106851038957806&amp;postID=8045921367838435654' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/199106851038957806/posts/default/8045921367838435654'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/199106851038957806/posts/default/8045921367838435654'/><link rel='alternate' type='text/html' href='http://mscrmuk.blogspot.com/2007/12/automating-local-data-query-creation.html' title='Automating Local Data Query Creation'/><author><name>David Jennaway</name><uri>http://www.blogger.com/profile/09695858105618938443</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-199106851038957806.post-2384834431964488216</id><published>2007-12-03T11:44:00.000Z</published><updated>2007-12-03T12:29:28.687Z</updated><category scheme='http://www.blogger.com/atom/ns#' term='Client Code'/><category scheme='http://www.blogger.com/atom/ns#' term='Customisation'/><title type='text'>Providing different default views for different CRM users</title><content type='html'>Or, how to modify CRM grid pages via client script.&lt;br /&gt;&lt;br /&gt;CRM provides 2 standard ways to add custom client script into the CRM application; via form events, and through menu items and buttons in ISV.Config. Neither of these allows you to write code to control the default views for CRM entities&lt;br /&gt;&lt;br /&gt;However, there is a way round this. The approach is to create a host HTML (or ASP .Net) page that has no interface components itself, but contains the CRM page in an IFrame. This will appear exactly the same as the standard CRM page, but allows you to write client script in your host page that controls the CRM page, and hence change which view is displayed.&lt;br /&gt;&lt;br /&gt;Note that this approach has to be considered as unsupported, as it involves programmatic control over a picklist outside of a CRM form.&lt;br /&gt;&lt;br /&gt;&lt;strong&gt;Building the host page&lt;/strong&gt;&lt;br /&gt;There are 2 aspects of the host page; providing the HTML to host the IFrame without adding extraneous borders or padding, and adding client script that runs once the IFrame has loaded.&lt;br /&gt;&lt;br /&gt;The following HTML shows how to host the IFrame:&lt;br /&gt;&lt;span style="font-family:courier new;font-size:85%;"&gt;&lt;br /&gt;&amp;lt;body style="margin:0" onload="Init();"&amp;gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;font-size:85%;"&gt;&amp;lt;iframe onreadystatechange="ors();" id="ifr" src="about:blank" width="100%" height="100%" frameborder="0" leftmargin="0"&amp;gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;font-size:85%;"&gt;&amp;lt;/body&amp;gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;In this example I’m creating a generic page that can host most CRM grid pages, and I’m setting the src property of the IFrame programmatically:&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family:courier new;font-size:85%;"&gt;function Init()&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;font-size:85%;"&gt;{&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;font-size:85%;"&gt;var etc = getQS('etc');&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;font-size:85%;"&gt;if (etc != null)&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:Courier New;font-size:85%;"&gt;{&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;font-size:85%;"&gt;document.all.ifr.src = '/_root/homepage.aspx?etc=' + etc;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:Courier New;font-size:85%;"&gt;}&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;font-size:85%;"&gt;}&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;This src is the standard way to display most entity grids, with etc as the object type code of the entity.&lt;br /&gt;&lt;br /&gt;I’m using the onreadystatechange event to determine whether the IFrame has loaded:&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family:courier new;font-size:85%;"&gt;function ors()&lt;br /&gt;{&lt;br /&gt; if (event.srcElement.readyState == 'complete')&lt;br /&gt; {&lt;br /&gt;  var sView = getQS('view');&lt;br /&gt;  if (sView != null)&lt;br /&gt;   SetView(sView);&lt;br /&gt;  document.all.ifr.style.visibility = 'visible';&lt;br /&gt; }&lt;br /&gt; else&lt;br /&gt; {&lt;br /&gt;  document.all.ifr.style.visibility = 'hidden';&lt;br /&gt; }&lt;br /&gt;}&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;This checks the readyState property of the IFrame, which will equal ‘complete’ when the IFrame contents have loaded, and the IFrame contents after they have been modified.&lt;br /&gt;&lt;br /&gt;The following code shows how to modify which view is selected:&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family:courier new;font-size:85%;"&gt;function SetView(sView)&lt;br /&gt;{&lt;br /&gt; var ifDoc = document.frames['ifr'].document.all; // access IFrame contents&lt;br /&gt; var oSel = ifDoc['SavedQuerySelector'];  // picklist control to select view&lt;br /&gt; if (oSel != null)&lt;br /&gt; {&lt;br /&gt;  var v = GetSelectValue(oSel, sView);&lt;br /&gt;  if (v)&lt;br /&gt;  {&lt;br /&gt;   oSel.DefaultValue = v;&lt;br /&gt;   oSel.DataValue = v;&lt;br /&gt;   oSel.FireOnChange(); // need to fire this event to apply changes&lt;br /&gt;  }&lt;br /&gt; }&lt;br /&gt;}&lt;br /&gt;function GetSelectValue(oSel, sText)  // helper function to select item in picklist&lt;br /&gt;{&lt;br /&gt; for (var i=0;i&amp;lt;osel.options.length;i++)&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;font-size:85%;"&gt;{&lt;br /&gt;  if (oSel.options[i].text == sText) return oSel.options[i].value; &lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;font-size:85%;"&gt;}&lt;br /&gt;}&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;The code uses another helper function to access parameters passed on the query string. This function is oversimplified in that it doesn’t cope with all possible encoding issues, but is sufficient for this example:&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family:courier new;font-size:85%;"&gt;function getQS(name)&lt;br /&gt;{&lt;br /&gt; var ret = '';&lt;br /&gt; if (window.location.search != null &amp;amp;&amp;amp; window.location.search.length &gt; 1)&lt;br /&gt; {&lt;br /&gt;  var aQS = window.location.search.substring(1).split('&amp;amp;');&lt;br /&gt;  if (aQS != null)&lt;br /&gt;   for (var i=0;i&amp;lt;aQS.length;i++)&lt;br /&gt;    if (aQS[i].indexOf(name + '=') == 0)&lt;br /&gt;     ret = aQS[i].substring(name.length + 1).replace('%20', ' ');&lt;br /&gt; }&lt;br /&gt; return ret;&lt;br /&gt;}&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;Putting this all together, we have a page that will display an entity grid, and change the default view, based on 2 query string parameters. For example&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family:courier new;font-size:85%;"&gt;defaultViewChanger.htm?etc=1&amp;amp;view=Active%20Accounts&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;Will display the account grid, and set the view to the Active Accounts view (%20 is the encoding of a space, which is not permitted in a url).&lt;br /&gt;&lt;br /&gt;&lt;strong&gt;Setting different default views for different users&lt;/strong&gt;&lt;br /&gt;We now have a page that can programmatically change the default view. There are 2 ways this can be used to provide different default views to different users: a programmatic way that identifies the current user (and probably team or role membership) and hence determines the default view, or via permissions in SiteMap.&lt;br /&gt;&lt;br /&gt;I’m not intending the cover the programmatic route in detail here; my preference is to convert the page to an ASP .Net page that identifies the current user and their role, and populates the parameter to SetView in server code; an alternative approach in client code can be found &lt;a href="http://ronaldlemmen.blogspot.com/2006/05/finally-there-show-and-hide-fields.html"&gt;here&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;Another approach is to make use of the Privilege element in SiteMap to display different navigation links to different sets of users based on their permissions, as described in more detail &lt;a href="http://mscrmuk.blogspot.com/2007/11/using-permissions-to-personalise.html"&gt;here&lt;/a&gt;. Let’s assume we have 2 groups of users who want different default views of the account entity, group A (who are members of security role ‘roleA’) want to see My Active Accounts, and group B (members of ‘roleB’) who want to see Active Accounts.&lt;br /&gt;&lt;br /&gt;We can create a dummy entity in CRM called exc_acctsecurity and grant roleA write rights on the exc_acctsecurity entity, and grant roleB assign rights. Then we can modify SiteMap, replacing the SubAreas for the account entity to the following:&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family:courier new;font-size:85%;"&gt;&amp;lt;SubArea Id="nav_accthostA" Title="Accounts" Url="&lt;/span&gt;&lt;a href="http://server/defaultViewChanger.htm?etc=1&amp;amp;amp;view=My%20Active%20Accounts"&gt;&lt;span style="font-family:courier new;font-size:85%;"&gt;http://server/defaultViewChanger.htm?etc=1&amp;amp;amp;view=My%20Active%20Accounts&lt;/span&gt;&lt;/a&gt;&lt;span style="font-family:courier new;font-size:85%;"&gt;" Icon="/_imgs/ico_18_1.gif"&amp;gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;font-size:85%;"&gt;&amp;lt;Privilege Entity="exc_acctsecurity" Privilege="Write" /&amp;gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;font-size:85%;"&gt;&amp;lt;/SubArea&amp;gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;font-size:85%;"&gt;&amp;lt;SubArea Id="nav_accthostB" Title="Accounts" Url="&lt;/span&gt;&lt;a href="http://server/defaultViewChanger.htm?etc=1&amp;amp;amp;view=Active%20Accounts"&gt;&lt;span style="font-family:courier new;font-size:85%;"&gt;http://server/defaultViewChanger.htm?etc=1&amp;amp;amp;view=Active%20Accounts&lt;/span&gt;&lt;/a&gt;&lt;span style="font-family:courier new;font-size:85%;"&gt;" Icon="/_imgs/ico_18_1.gif"&amp;gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;font-size:85%;"&gt;&amp;lt;Privilege Entity="exc_acctsecurity" Privilege="Assign" /&amp;gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;font-size:85%;"&gt;&amp;lt;/SubArea&amp;gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;Note the use of XML encoding (&amp;amp;amp; instead of &amp;amp;).&lt;br /&gt;&lt;br /&gt;One drawback of this approach is that anybody in the System Administrator role will see both SubAreas.&lt;br /&gt;&lt;br /&gt;A complete example of the HTML and SiteMap can be found on &lt;a href="http://www.codeplex.com/MSCRMPageHost"&gt;CodePlex&lt;/a&gt;.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/199106851038957806-2384834431964488216?l=mscrmuk.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://mscrmuk.blogspot.com/feeds/2384834431964488216/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=199106851038957806&amp;postID=2384834431964488216' title='5 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/199106851038957806/posts/default/2384834431964488216'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/199106851038957806/posts/default/2384834431964488216'/><link rel='alternate' type='text/html' href='http://mscrmuk.blogspot.com/2007/12/providing-different-default-views-for.html' title='Providing different default views for different CRM users'/><author><name>David Jennaway</name><uri>http://www.blogger.com/profile/09695858105618938443</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>5</thr:total></entry><entry><id>tag:blogger.com,1999:blog-199106851038957806.post-7615334544081062802</id><published>2007-12-03T10:56:00.001Z</published><updated>2007-12-03T11:02:38.110Z</updated><category scheme='http://www.blogger.com/atom/ns#' term='Customisation'/><category scheme='http://www.blogger.com/atom/ns#' term='Reports'/><title type='text'>Viewing all files in CRM related to an account</title><content type='html'>I've recently published a second CRM related reporting services project on &lt;a href="http://www.codeplex.com/MSCRMFilesByAccount"&gt;codeplex&lt;/a&gt;. This one illustrates how to get a list of all files related to a CRM account. This includes files attached directly to the account or via related objects (e.g. contacts, opportunities, cases), and also includes both file and email attachments.&lt;br /&gt;&lt;br /&gt;Most of the work is done in the SQL, which I've written as a set of SQL views for ease of reading, rather than embedding all the SQL in the report.&lt;br /&gt;&lt;br /&gt;The project also illustrates how to link to CRM objects, within a report, as the report contains reporting services actions to display the CRM entity forms, and also actions on each file to link to the CRM file download dialog.&lt;br /&gt;&lt;br /&gt;This report is written so as to take parameters from a ISV.Config button, as described &lt;a href="http://blogs.msdn.com/crm/archive/2007/10/04/writing-reports-to-display-in-iframes-and-from-isv-config.aspx"&gt;here&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/199106851038957806-7615334544081062802?l=mscrmuk.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://mscrmuk.blogspot.com/feeds/7615334544081062802/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=199106851038957806&amp;postID=7615334544081062802' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/199106851038957806/posts/default/7615334544081062802'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/199106851038957806/posts/default/7615334544081062802'/><link rel='alternate' type='text/html' href='http://mscrmuk.blogspot.com/2007/12/viewing-all-files-in-crm-related-to.html' title='Viewing all files in CRM related to an account'/><author><name>David Jennaway</name><uri>http://www.blogger.com/profile/09695858105618938443</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-199106851038957806.post-8420310442920986120</id><published>2007-11-23T07:25:00.000Z</published><updated>2007-12-03T11:22:45.186Z</updated><category scheme='http://www.blogger.com/atom/ns#' term='Configuration'/><category scheme='http://www.blogger.com/atom/ns#' term='Virtual PC'/><title type='text'>External access from a Virtual Environment</title><content type='html'>&lt;p&gt;We do almost all our CRM development and testing within virtual images. This confers many benefits, but raises issues if you need connect the image to the outside world. One example is when registering software; another is when developing callouts / plugins that communicate with external web services.&lt;br /&gt;&lt;br /&gt;The major issue arises with a self-contained image that is a domain controller in its own domain, as well as a SQL server and CRM server. Active Directory depends on DNS, so the image has to be its own DNS server, which forces it to have a fixed IP address, which we place on separate IP private IP subnet (e.g. 192.168.x.0). This essentially prevents this IP address and adapter being used externally. With just the one adapter and IP address, you can’t change the IP address to a dynamic one (e.g. from DHCP), because within the image that breaks DNS, which breaks AD, which breaks CRM.&lt;br /&gt;&lt;br /&gt;So, the solution; add a separate network adapter to the image, using an external IP address. With Microsoft Virtual PC or Virtual Server, the steps to take are:&lt;/p&gt;&lt;ul&gt;&lt;li&gt;Turn off the image&lt;/li&gt;&lt;li&gt;Add a 2nd network adapter to the image, and associate it with the physical adapter in the host machine&lt;/li&gt;&lt;li&gt;Start the image, and set the IP address on the 2nd adapter to something that will work on the external network; either dynamically assigned via DHCP, or to a reserved static address&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;This resolves the IP addressing issue, and if you only need to connect to an external resource by IP address than that’s as much as you need. However, you may still have a DNS problem. I’ve not investigated all scenarios, but I have met cases when, even if the 2nd adapter is configured for with external DNS server, the image still uses its own DNS server for all DNS requests. In this scenario the simplest solution is to configure a forwarder for the virtual DNS server, so that it forwards all DNS requests that it cannot resolve to your known external DNS server. This can be configured with the DNS management snap-in.&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/199106851038957806-8420310442920986120?l=mscrmuk.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://mscrmuk.blogspot.com/feeds/8420310442920986120/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=199106851038957806&amp;postID=8420310442920986120' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/199106851038957806/posts/default/8420310442920986120'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/199106851038957806/posts/default/8420310442920986120'/><link rel='alternate' type='text/html' href='http://mscrmuk.blogspot.com/2007/11/external-access-from-virtual.html' title='External access from a Virtual Environment'/><author><name>David Jennaway</name><uri>http://www.blogger.com/profile/09695858105618938443</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-199106851038957806.post-8143699192390413793</id><published>2007-11-21T07:38:00.000Z</published><updated>2007-11-21T11:28:43.354Z</updated><category scheme='http://www.blogger.com/atom/ns#' term='Customisation'/><title type='text'>Using permissions to personalise SiteMap</title><content type='html'>CRM allows modification of the CRM application navigation structure via &lt;a href="http://msdn2.microsoft.com/en-us/library/aa682912.aspx"&gt;SiteMap&lt;/a&gt;. This is normally considered to provide one customised navigation structure for all CRM users, with the only difference between what one user sees and what one of their colleagues sees is what they have permission for.&lt;br /&gt;&lt;br /&gt;For most entries in SiteMap, whether they are displayed or not depends on the user’s permission on the corresponding entity. For example, if a user does not have Read privileges at any level on the invoice entity, they will not see invoices in SiteMap. However, SiteMap allows more explicit control over what privileges are required to display any link; this is done via the Privilege element.&lt;br /&gt;&lt;br /&gt;The following extract from the default SiteMap illustrates how this is used:&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family:courier new;font-size:85%;"&gt;&amp;lt;SubArea Id="nav_managekb" ResourceId="Homepage_KBManager" Icon="/_imgs/ico_18_126.gif" Url="/cs/home_managekb.aspx" Client="Web"&amp;gt; &amp;lt;Privilege Entity="kbarticle" Privilege="Read,Write,Create" /&amp;gt;&amp;lt;/SubArea&amp;gt;&lt;br /&gt;&lt;/span&gt;This specifies that the Knowledge Base link in the Services Area should only be displayed to users who have Read, Write and Create privileges on the kbarticle entity.&lt;br /&gt;&lt;br /&gt;Privilege elements are interpreted based on these rules:&lt;br /&gt;&lt;ul&gt;&lt;li&gt;In one Privilege element, the user must have all privileges listed in the Privilege attribute&lt;/li&gt;&lt;li&gt;The level of privilege doesn’t matter; user level is sufficient&lt;/li&gt;&lt;li&gt;Multiple Privilege elements can be specified for one SubArea; in this case the user needs to fulfil the permissions for every element&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;There is no requirement for the Privileges element(s) to be related to the entity (or external link) that is displayed. &lt;/p&gt;&lt;p&gt;&lt;strong&gt;Using the Privileges element&lt;/strong&gt;&lt;br /&gt;Given this, it is perfectly reasonable to create multiple SubArea elements in SiteMap that would show similar (but not identical) information, but only display one of them to any given user, based on their permissions. For example, you may have created custom portal pages, but the customer service staff should see a different page from that seen by marketing staff. Showing a different page for each set of users could be achieved with the following entries in SiteMap:&lt;/p&gt;&lt;p&gt;&lt;span style="font-family:courier new;font-size:85%;"&gt;&amp;lt;SubArea Id="nav_portalService" Title="Company Portal" Url="http://server/supportportal.htm" Icon="/_imgs/ico_18_home.gif"&amp;gt; &amp;lt;Privilege Entity=”incident” Privilege=”Create” /&amp;gt;&amp;lt;/SubArea&amp;gt;&amp;lt;SubArea Id="nav_portalService" Title="Company Portal" Url="http://server/marketingportal.htm" Icon="/_imgs/ico_18_home.gif"&amp;gt; &amp;lt;Privilege Entity=”campaign” Privilege=”Create” /&amp;gt;&amp;lt;/SubArea&amp;gt;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;This works providing that support users can create cases (schema name incident) but not campaigns, while the opposite applies to marketing users.&lt;br /&gt;&lt;br /&gt;This approach can work well assuming suitable privileges can be found to distinguish between different groups of users, but what if there aren’t any suitable permissions ?&lt;/p&gt;&lt;p&gt;&lt;strong&gt;Creating dummy entities for permissions&lt;/strong&gt;&lt;br /&gt;The Privileges element can refer to custom entities, and there is nothing to stop us creating one or more entities solely for the purposes of personalising SiteMap. For example, we could do the following:&lt;/p&gt;&lt;ul&gt;&lt;li&gt;Create an entity called dummy_security&lt;/li&gt;&lt;li&gt;Grant one role, ‘Support Role’, Write privilege on this entity&lt;/li&gt;&lt;li&gt;Grant another role, ‘Marketing Role’, Assign privilege on the entity&lt;/li&gt;&lt;li&gt;Ensure users are added to the appropriate role&lt;/li&gt;&lt;li&gt;Change the above snippet from SiteMap to the following:&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;&lt;span style="font-family:courier new;font-size:85%;"&gt;&amp;lt;SubArea Id="nav_portalService" Title="Company Portal" Url="http://server/supportportal.htm" Icon="/_imgs/ico_18_home.gif"&amp;gt; &amp;lt;Privilege Entity=”dummy_security” Privilege=”Write” /&amp;gt;&amp;lt;/SubArea&amp;gt;&amp;lt;SubArea Id="nav_portalService" Title="Company Portal" Url="http://server/marketingportal.htm" Icon="/_imgs/ico_18_home.gif"&amp;gt; &amp;lt;Privilege Entity=” dummy_security” Privilege=”Assign” /&amp;gt;&amp;lt;/SubArea&amp;gt;&lt;/span&gt; &lt;/p&gt;&lt;p&gt;This would give users the correct link, without relying on existing privileges that may change based on changing job roles, or changing business requirements.&lt;br /&gt;&lt;br /&gt;The one thing to watch for is to make sure you don’t grant Read or Create privilege on this new entity; this will ensure it will not appear to users anywhere in the normal CRM application. Note that members of the System Administrator role will necessarily see all the SubAreas, because they will automatically have full privileges on all entities.&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/199106851038957806-8143699192390413793?l=mscrmuk.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://mscrmuk.blogspot.com/feeds/8143699192390413793/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=199106851038957806&amp;postID=8143699192390413793' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/199106851038957806/posts/default/8143699192390413793'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/199106851038957806/posts/default/8143699192390413793'/><link rel='alternate' type='text/html' href='http://mscrmuk.blogspot.com/2007/11/using-permissions-to-personalise.html' title='Using permissions to personalise SiteMap'/><author><name>David Jennaway</name><uri>http://www.blogger.com/profile/09695858105618938443</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-199106851038957806.post-8981145097919205757</id><published>2007-11-15T22:46:00.001Z</published><updated>2007-11-15T23:02:14.707Z</updated><category scheme='http://www.blogger.com/atom/ns#' term='Callouts'/><category scheme='http://www.blogger.com/atom/ns#' term='CRM 3.0'/><title type='text'>Redeploying callouts by recycling the application pool, rather than IISRESET</title><content type='html'>When redeploying a callout on CRM 3.0, it is considered necessary to run IISRESET to unload the callout assembly from memory, and hence allow you to copy a new version of the dll. This can have several issues:&lt;br /&gt;&lt;ol&gt;&lt;li&gt;After an IISRESET, it takes long enough to reload / rerender CRM data to be annoying when frequently testing and redeploying versions of a callout assembly&lt;/li&gt;&lt;li&gt;If other users are using CRM, there will be an outage during the IISRESET&lt;/li&gt;&lt;li&gt;IISRESET affects all other web applications on the server&lt;/li&gt;&lt;/ol&gt;&lt;p&gt;To minimise the impact of 1) above, &lt;a href="http://www.stunnware.com/crm2/topic.aspx?id=LocalCalloutDebugging"&gt;Michael Höhne's local debugging mechanism &lt;/a&gt;is an excellent solution in a lot of environments. &lt;/p&gt;&lt;p&gt;However, there are still the occasions when the callout has to be redeployed on to the CRM server. There's not much that can be about 2), although the following suggestion helps a bit.&lt;/p&gt;&lt;p&gt;We can do something about 3). A callout is loaded into the process for the CRM application pool (CrmAppPool), and it is only this application pool that needs to be recycled, rather than the whole of IIS. An application pool can be recycled via the IIS management console, but there is an easy way to script this, as follows:&lt;/p&gt;&lt;ol&gt;&lt;li&gt;Open a command prompt&lt;/li&gt;&lt;li&gt;Change directory to %Windir%\system32&lt;/li&gt;&lt;li&gt;Run the following command:&lt;/li&gt;&lt;/ol&gt;&lt;p&gt;&lt;span style="font-family:courier new;"&gt;cscript iisapp.vbs /a CrmAppPool /r&lt;/span&gt;&lt;/p&gt;&lt;p&gt;This will just recycle the application pool, after which you can copy the new callout assembly&lt;/p&gt;&lt;p&gt; &lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/199106851038957806-8981145097919205757?l=mscrmuk.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://mscrmuk.blogspot.com/feeds/8981145097919205757/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=199106851038957806&amp;postID=8981145097919205757' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/199106851038957806/posts/default/8981145097919205757'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/199106851038957806/posts/default/8981145097919205757'/><link rel='alternate' type='text/html' href='http://mscrmuk.blogspot.com/2007/11/redeploying-callouts-by-recycling.html' title='Redeploying callouts by recycling the application pool, rather than IISRESET'/><author><name>David Jennaway</name><uri>http://www.blogger.com/profile/09695858105618938443</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-199106851038957806.post-1217708044958086435</id><published>2007-11-15T21:28:00.000Z</published><updated>2007-11-15T23:48:13.117Z</updated><category scheme='http://www.blogger.com/atom/ns#' term='Callouts'/><category scheme='http://www.blogger.com/atom/ns#' term='SQL Server'/><title type='text'>Syntax issues using SQL Execute As and Revert statements</title><content type='html'>SQL Server 2005 provides a means to switch user context via the EXECUTE AS statement. This can be very useful when querying CRM Filtered views, as they use the SQL user context to determine what data to return and if queried using the CRM service account they return no data. An example of how this can be used in CRM callouts can be found &lt;a href="http://www.invokesystems.com/cs/blogs/mscrm/archive/2007/05/21/348.aspx"&gt;here&lt;/a&gt;. I've also used a similar approach when running SSIS packages programmatically from a web application, as ASP .Net impersonation doesn't work properly in SSIS packages.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;However, when testing this further, and checking the behaviour of REVERT, I found this only works correctly if you separate your SQL statements with semi-colons. Take the following 2 examples:&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;Execute as user='crmdom\admin'&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;select * from filteredaccount&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;revert&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;declare @sql nvarchar(2000)&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;Execute as user='crmdom\admin'&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;set @sql = 'select * from filteredaccount'&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;exec (@sql)&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;revert&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;Of these 2, the former appears to work, but the REVERT statement doesn't get processed, and the latter gives an 'incorrect syntax' error. But, if you add a semi-colon after the statement before REVERT, then they work fine:&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;Execute as user='crmdom\admin'&lt;br /&gt;select * from filteredaccount;&lt;br /&gt;revert&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;declare @sql nvarchar(2000)&lt;br /&gt;Execute as user='crmdom\admin'&lt;br /&gt;set @sql = 'select * from filteredaccount'&lt;br /&gt;exec (@sql);&lt;br /&gt;revert&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;Now, that is not what I expected in SQL syntax. I always thought semi-colons were an optional statement separator, but apparently not -though I expect this is a bug rather than by design.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;Note, this behaviour happens on build 2047 of SQL 2005, whereas it works without semi-colons on build 1399, but that doesn't stop me using them as a matter of course with impersonation.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/199106851038957806-1217708044958086435?l=mscrmuk.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://mscrmuk.blogspot.com/feeds/1217708044958086435/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=199106851038957806&amp;postID=1217708044958086435' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/199106851038957806/posts/default/1217708044958086435'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/199106851038957806/posts/default/1217708044958086435'/><link rel='alternate' type='text/html' href='http://mscrmuk.blogspot.com/2007/11/syntax-issues-using-sql-execute-as-and.html' title='Syntax issues using SQL Execute As and Revert statements'/><author><name>David Jennaway</name><uri>http://www.blogger.com/profile/09695858105618938443</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-199106851038957806.post-2987945392344405166</id><published>2007-11-12T13:43:00.000Z</published><updated>2007-11-12T14:57:38.423Z</updated><category scheme='http://www.blogger.com/atom/ns#' term='Client Code'/><category scheme='http://www.blogger.com/atom/ns#' term='Customisation'/><category scheme='http://www.blogger.com/atom/ns#' term='CRM 4.0'/><title type='text'>Changes to client-side code for CRM 4.0</title><content type='html'>Following on from looking at server-side code changes for CRM 4.0, here's what I know so far about client-side code changes. Again, this is based on the CTP3 code so may soon become out-dated. Another caveat is that it is based on investigation of the CRM client files, and not on the SDK documentation (which at time of posting is incomplete); hence, some of what I cover may well be undocumented and hence unsupported.&lt;br /&gt;&lt;br /&gt;&lt;strong&gt;Calling CRM web services directly&lt;/strong&gt;&lt;br /&gt;This has never been a favourite approach of mine, as the creation of the SOAP data in client-code seems too fragile; I prefer to create server-side web pages or services to abstract the CRM web service. However, I know many people who make direct SOAP requests, and there is another consideration - if customising a deployment on Windows Live you will not be permitted to deploy server web code, so you will have to make direct requests.&lt;br /&gt;&lt;br /&gt;If you do make direct requests, you will need to pass the new CrmAuthenticationToken within the SOAP header. Rather than generating this yourself, there is a new global method for this:&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;GenerateAuthenticationHeader();&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;CRM 4.0 now provides a proper web service interface for offline use. This can be accessed from client-side code via the http://localhost:2525 location.&lt;br /&gt;&lt;br /&gt;&lt;strong&gt;New Global Variables&lt;/strong&gt;&lt;br /&gt;CRM 4.0 provides the following documented global variables related to the multi-language and multi-tenant features:&lt;br /&gt;&lt;ul&gt;&lt;li&gt;USER_LANGUAGE_CODE - Code (LCID) of the current user's language&lt;/li&gt;&lt;li&gt;ORG_LANGUAGE_CODE - Code (LCID) of the base language&lt;/li&gt;&lt;li&gt;ORG_UNIQUE_NAME - Current organisation name&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;&lt;strong&gt;New Object Properties and Methods&lt;/strong&gt;&lt;br /&gt;Note, everything in this section may be undocumented and hence unsupported. As you may know, the crmForm and field objects are implemented as HTML components (.htc files) in the /_forms/controls directory. A comparison between the CRM 3.0 and CRM 4.0 versions show the following changes:&lt;/p&gt;&lt;p&gt;All CRM 3.0 properties and methods seem intact, even the undocumented ones. I've not tested this exhaustively, but all current code works fine.&lt;/p&gt;&lt;p&gt;The crmForm object has the following new members:&lt;/p&gt;&lt;ul&gt;&lt;li&gt;fireSaveEvent&lt;/li&gt;&lt;li&gt;HideField - I hope this will become supported, as it will avoid direct DHTML manipulation&lt;/li&gt;&lt;li&gt;VerifyFieldIsSet&lt;/li&gt;&lt;li&gt;BypassValidation - a property to tell CRM not to validate fields&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;The Lookup control has more members, mostly to do with the new auto-resolve functionality:&lt;/p&gt;&lt;ul&gt;&lt;li&gt;AutoResolve and ResolveEmailAddress boolean properties&lt;/li&gt;&lt;li&gt;AreValuesDifferent method allows comparison between the lookup contents and a supplied array of values&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;The Picklist control exposes the underlying properties of the select HTML element, SelectedIndex and SelectedOption.&lt;/p&gt;&lt;p&gt;Across these, and the undocumented members from CRM 3.0, what I see as most significant is the extent to which they will be supported in CRM 4.0. We shall see.&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/199106851038957806-2987945392344405166?l=mscrmuk.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://mscrmuk.blogspot.com/feeds/2987945392344405166/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=199106851038957806&amp;postID=2987945392344405166' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/199106851038957806/posts/default/2987945392344405166'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/199106851038957806/posts/default/2987945392344405166'/><link rel='alternate' type='text/html' href='http://mscrmuk.blogspot.com/2007/11/changes-to-client-side-code-for-crm-40.html' title='Changes to client-side code for CRM 4.0'/><author><name>David Jennaway</name><uri>http://www.blogger.com/profile/09695858105618938443</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-199106851038957806.post-2699261525590145172</id><published>2007-11-09T17:02:00.001Z</published><updated>2007-11-09T18:53:24.469Z</updated><category scheme='http://www.blogger.com/atom/ns#' term='Server code'/><category scheme='http://www.blogger.com/atom/ns#' term='CRM 4.0'/><title type='text'>Changes to code to use CRM 4.0 web services</title><content type='html'>I've recently been rewriting some of our products for CRM 4.0, and here's a summary of the server-side code changes required when converting code from using the CRM 3.0 web services to the CRM 4.0 web services. Note that this is based on the CTP3 release of CRM 4.0, so may not be accurate for release code.&lt;br /&gt;&lt;br /&gt;&lt;strong&gt;Use of the CRM 3.0 web service&lt;/strong&gt;&lt;br /&gt;CRM 4.0 retains the CRM 3.0 web service, along with an implementation of the CRM 3.0 microsoft.crm.platform.callout.base.dll. This allows you, as far as I can tell, to retain code written for CRM 3.0 and have it work with CRM 4.0. So far I've found 2 limitations to this:&lt;br /&gt;&lt;ol&gt;&lt;li&gt;If you use the CRM 3.0 Web Service, you will access the default organisation, and will not be able to use multiple organisations. You will also have to use AD authentication&lt;/li&gt;&lt;li&gt;A few of the CRM 3.0 Web Service methods have been deprecated and won't work. The main class of these are those used to manage workflow&lt;/li&gt;&lt;/ol&gt;&lt;p&gt;If you look in the directory structure of CRM 4.0 you'll see the following:&lt;/p&gt;&lt;p&gt;mscrmservices\2006\CrmService.asmx (used for CRM 3.0 web service access)&lt;br /&gt;mscrmservices\2007\CrmService.asmx (used for CRM 4.0 web service access)&lt;/p&gt;&lt;p&gt;However this post is mostly about the changes you need to make if you are targetting the CRM 4.0 we service.&lt;/p&gt;&lt;p&gt;&lt;strong&gt;The CrmDiscoveryService service&lt;/strong&gt;&lt;br /&gt;The first major differences with respect to the web services with CRM 4.0 is that there is a third web service, the CrmDiscoveryService. This is primarily used to enumerate the organisations in use and provide the connection information for them. This service will be necessary in a multi-tenanted environment; whether you need to use it in a single-organisation on-premise implementation is open for debate (which deserves a separate post).&lt;/p&gt;&lt;p&gt;&lt;strong&gt;Setting up the CrmService service&lt;/strong&gt;&lt;br /&gt;The first key difference is the use of the CrmAuthenticationToken property. This became necessary to accommodate multi-tenancy and the new authentication type. It also replaces the CallerIdValue property. With the Enterprise edition of CRM 4.0 you have to set the OrganizationName; I don't know yet if it will be required in the Professional edition.&lt;/p&gt;&lt;p&gt;So, combining the 2 services above, you have 2 ways to setup your CrmService instance. Both assume the variable Org contains the organisation name. First, without using the CrmDiscoveryService:&lt;/p&gt;&lt;p&gt;&lt;span style="font-family:courier new;font-size:85%;"&gt;CrmService svc = new CrmService();&lt;br /&gt;svc.Url = Server + "/MSCRMServices/2007/CrmService.asmx";&lt;br /&gt;svc.Credentials = System.Net.CredentialCache.DefaultCredentials;&lt;br /&gt;CrmAuthenticationToken token = new CrmAuthenticationToken();&lt;br /&gt;token.AuthenticationType = 0;&lt;br /&gt;&lt;/span&gt;&lt;span style="font-family:courier new;font-size:85%;"&gt;token.OrganizationName = Org;&lt;br /&gt;svc.CrmAuthenticationTokenValue = token;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;Alternatively, you can use the CrmDiscoveryService to retrieve the data required for the CrmService instance:&lt;/p&gt;&lt;p&gt;&lt;span style="font-family:courier new;font-size:85%;"&gt;CrmDiscoveryService disco = new CrmDiscoveryService();&lt;br /&gt;disco.Url = Server + "/MSCRMServices/2007/AD/CrmDiscoveryService.asmx";&lt;br /&gt;disco.Credentials = CredentialCache.DefaultCredentials;&lt;br /&gt;RetrieveOrganizationsRequest orgRequest = new RetrieveOrganizationsRequest();&lt;br /&gt;RetrieveOrganizationsResponse orgResponse = (RetrieveOrganizationsResponse)disco.Execute(orgRequest);&lt;br /&gt;foreach (OrganizationDetail orgdetail in orgResponse.OrganizationDetails)&lt;br /&gt;{&lt;br /&gt;&amp;nbsp;if (orgdetail.OrganizationName == Org)&lt;br /&gt;&amp;nbsp;{&lt;br /&gt;&amp;nbsp;&amp;nbsp;CrmAuthenticationToken token = new CrmAuthenticationToken();&lt;br /&gt;&amp;nbsp;&amp;nbsp;token.AuthenticationType = 0;&lt;br /&gt;&amp;nbsp;&amp;nbsp;token.OrganizationName = Org;&lt;br /&gt;&amp;nbsp;&amp;nbsp;crmservice = new CrmService();&lt;br /&gt;&amp;nbsp;&amp;nbsp;crmservice.Credentials = CredentialCache.DefaultCredentials;&lt;br /&gt;&amp;nbsp;&amp;nbsp;crmservice.CrmAuthenticationTokenValue = token;&lt;br /&gt;&amp;nbsp;&amp;nbsp;crmservice.Url = orgdetail.CrmServiceUrl;&lt;br /&gt;&amp;nbsp;}&lt;br /&gt;}&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style="font-family:arial;"&gt;This code uses AD authentication. To use another authentication&lt;/span&gt; type, change the url to the CrmDiscoveryService, and change the AuthenticationType property of the CrmAuthenticationToken.&lt;/p&gt;&lt;p&gt;&lt;strong&gt;Using the CrmService service&lt;/strong&gt;&lt;br /&gt;The good news is, almost everything stays the same as before, and there is no need to rewrite code, other than to pass in an Organisation name. However, if you serialise and deserialise entities you'll have to pay attention to the Xml namespaces, as some classes retain the CRM 3.0 Xml namespaces, and some have a new Xml namespace. For example, from the generated proxy code:&lt;/p&gt;&lt;p&gt;&lt;span style="font-family:courier new;font-size:85%;"&gt;[System.Xml.Serialization.XmlTypeAttribute(Namespace="&lt;/span&gt;&lt;a href="http://schemas.microsoft.com/crm/2006/WebServices"&gt;&lt;span style="font-family:courier new;font-size:85%;"&gt;http://schemas.microsoft.com/crm/2006/WebServices&lt;/span&gt;&lt;/a&gt;&lt;span style="font-family:courier new;font-size:85%;"&gt;")]&lt;br /&gt;public partial class DynamicEntity : BusinessEntity &lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style="font-family:courier new;font-size:85%;"&gt;[System.Xml.Serialization.XmlTypeAttribute(Namespace="&lt;/span&gt;&lt;a href="http://schemas.microsoft.com/crm/2007/WebServices"&gt;&lt;span style="font-family:courier new;font-size:85%;"&gt;http://schemas.microsoft.com/crm/2007/WebServices&lt;/span&gt;&lt;/a&gt;&lt;span style="font-family:courier new;font-size:85%;"&gt;")]&lt;br /&gt;public partial class account : BusinessEntity &lt;/span&gt;&lt;/p&gt;&lt;p&gt;Fortunately for me, the DynamicEntity is only class that I regularly serialise, and the namespace hasn't changed.&lt;/p&gt;&lt;p&gt;&lt;strong&gt;Using the MetadataService service&lt;br /&gt;&lt;/strong&gt;Here, your code has to change, as this has moved over to the Request model with an Execute method. So, for example, the following CRM 3.0 code:&lt;/p&gt;&lt;p&gt;&lt;span style="font-family:courier new;font-size:85%;"&gt;EntityMetadata em = mdSvc.RetrieveEntityMetadata(EntityName.account.ToString(), EntityFlags.IncludeAttributes);&lt;/span&gt;&lt;/p&gt;&lt;p&gt;will need to be rewritten as:&lt;/p&gt;&lt;p&gt;&lt;span style="font-family:courier new;font-size:85%;"&gt;RetrieveEntityRequest req = new RetrieveEntityRequest();&lt;br /&gt;req.LogicalName = EntityName.account.ToString();&lt;br /&gt;req.RetrieveAsIfPublished = true;&lt;br /&gt;req.EntityItems = EntityItems.IncludeAttributes;&lt;br /&gt;RetrieveEntityResponse resp = (RetrieveEntityResponse) mdSvc.Execute(req);&lt;br /&gt;EntityMetadata em = resp.EntityMetadata;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style="font-family:arial;"&gt;Which is longer, but does illustrate one new feature, the ability to choose between the published and the unpublished information.&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style="font-family:Arial;"&gt;Another big difference relates to the way labels are used, which comes from the multi-language features. Again, some CRM 3.0 code:&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style="font-family:courier new;font-size:85%;"&gt;PicklistAttributeMetadata pam = mdSvc.RetrieveAttributeMetadata(EntityName.account.ToString(), "industrycode")&lt;br /&gt;foreach(Option o in pam.Options)&lt;br /&gt;&amp;nbsp;if (o.OptionValue == 1)&lt;br /&gt;&amp;nbsp;&amp;nbsp;Console.Writeline(o.Description);&lt;/span&gt;&lt;/p&gt;&lt;p&gt;Which becomes:&lt;/p&gt;&lt;p&gt;&lt;span style="font-family:courier new;font-size:85%;"&gt;RetrieveAttributeRequest req = new RetrieveAttributeRequest();&lt;br /&gt;req.EntityLogicalName = EntityName.account.ToString();&lt;br /&gt;req.LogicalName = "industrycode";&lt;br /&gt;req.RetrieveAsIfPublished = true;&lt;br /&gt;RetrieveAttrbiuteResponse resp = (RetrieveEntityResponse) mdSvc.Execute(req);&lt;br /&gt;PicklistAttributeMetadata pam = (PicklistAttributeMetadata) resp.AttributeMetadata;&lt;br /&gt;foreach (Option o in pam.Options)&lt;br /&gt;&amp;nbsp;if (o.Value.Value == 1)&lt;br /&gt;&amp;nbsp;&amp;nbsp;Console.Writeline(o.Label.UserLocLabel.Label);&lt;/span&gt;&lt;/p&gt;&lt;p&gt;The Option.Value property is now of type CrmNumber, and there is a Label property that allows access to all localised labels.&lt;/p&gt;&lt;p&gt;The MetadataService also now supports modification to be metadata, but as that's new functionality I'm not going to cover it here.&lt;/p&gt;&lt;p&gt;Using Microsoft assemblies&lt;br /&gt;With CRM 3.0, the only Microsoft CRM .Net assembly you were permitted to reference was microsoft.crm.platform.callout.base.dll. With CRM 4.0, there are 2 assemblies you can reference:&lt;/p&gt;&lt;ul&gt;&lt;li&gt;Microsoft.Crm.Sdk.dll&lt;/li&gt;&lt;li&gt;Microsoft.Crm.SdkTypeProxy.dll&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;At the moment I've not investigated them fully, as they are not well documented, and subject to change prior to release. The main new feature though is the implementation code for a PropertyBag, which is a collection class that allows, among others, easy manipulation of the properties of a DynamicEntity:&lt;/p&gt;&lt;p&gt;&lt;span style="font-family:courier new;font-size:85%;"&gt;Microsoft.Crm.Sdk.DynamicEntity de = new Microsoft.Crm.Sdk.DynamicEntity();&lt;br /&gt;de.Name = EntityName.account.ToString();&lt;br /&gt;de.Properties.Add(new StringProperty("name", "My Co"));&lt;br /&gt;if (de.Properties.Contains("name"))&lt;br /&gt;&amp;nbsp;Console.Writeline(de["name"].Value);&lt;/span&gt;&lt;/p&gt;&lt;p&gt;This uses a bit of helper code from the Sdk for a partial class for StringProperty with a constructor that takes 2 parameters.&lt;/p&gt;&lt;p&gt;&lt;strong&gt;Other changes&lt;/strong&gt;&lt;br /&gt;One minor annoyance is that both the CrmService and MetadataService classes have classes with the same name, e.g. AttributeType. This means you cannot be as indiscriminate with your use of using or imports statements as I like to be.&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/199106851038957806-2699261525590145172?l=mscrmuk.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://mscrmuk.blogspot.com/feeds/2699261525590145172/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=199106851038957806&amp;postID=2699261525590145172' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/199106851038957806/posts/default/2699261525590145172'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/199106851038957806/posts/default/2699261525590145172'/><link rel='alternate' type='text/html' href='http://mscrmuk.blogspot.com/2007/11/changes-to-code-to-use-crm-40-web.html' title='Changes to code to use CRM 4.0 web services'/><author><name>David Jennaway</name><uri>http://www.blogger.com/profile/09695858105618938443</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-199106851038957806.post-3261678811352225047</id><published>2007-11-09T12:21:00.000Z</published><updated>2007-11-09T13:03:44.437Z</updated><category scheme='http://www.blogger.com/atom/ns#' term='Customisation'/><category scheme='http://www.blogger.com/atom/ns#' term='Reports'/><title type='text'>Retrieving Billable time and activity time for cases</title><content type='html'>When a case is resolved in CRM, the user can specify the amount of Billable Time spent on the case, and they can also see the total activity time spent on the case:&lt;br /&gt;&lt;br /&gt;&lt;a href="http://3.bp.blogspot.com/_q3OlQztdu1Y/RzRSlk5emQI/AAAAAAAAAAU/WKNaqCOJGFA/s1600-h/resolvecase.JPG"&gt;&lt;img id="BLOGGER_PHOTO_ID_5130816680995232002" style="DISPLAY: block; MARGIN: 0px auto 10px; CURSOR: hand; TEXT-ALIGN: center" alt="" src="http://3.bp.blogspot.com/_q3OlQztdu1Y/RzRSlk5emQI/AAAAAAAAAAU/WKNaqCOJGFA/s320/resolvecase.JPG" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;Both sets of information can be useful, and are necessarily stored in the CRM database. However, how you retrieve these figures is not well documented.&lt;br /&gt;&lt;br /&gt;&lt;strong&gt;Where the data is stored&lt;/strong&gt;&lt;br /&gt;Data about the case is stored in 3 main entities (note that I'm using the schema name for the entities, and in the schema a case is called an incident):&lt;br /&gt;&lt;br /&gt;incident: This is the main case entity, which stores the information you see on the main form, but does not include and of the duration information listed above. The statecode field identifies whether a case is open, resolved or cancelled.&lt;br /&gt;&lt;br /&gt;incidentresolution: This is strictly a special type of activity, and stores the user entered data in the Case Resolution dialog. The 'Resolution Type' is stored in the statuscode field, and the user-entered 'Billable Time' is stored in the timespent field.&lt;br /&gt;&lt;br /&gt;activitypointer: All activities related to a case have an activitypointer record. The duration of each closed activity is stored in the actualdurationminutes field.&lt;br /&gt;&lt;br /&gt;There are a couple of additional complexities to the data storage:&lt;br /&gt;&lt;ol&gt;&lt;li&gt;It is possible for a case to have been resolved, then reactivated, and resolved again. This results in 2 incidentresolution records, so you need to identify the correct one. I always go by the most recent&lt;/li&gt;&lt;li&gt;The incidentresolution entity is a type of activity, hence has an associated activitypointer record. Fortunately, this record has no value for the actualdurationminutes, so doesn't affect any calculations of total activity time. However, you do have to be aware of this if you want a count of the number of activities&lt;/li&gt;&lt;/ol&gt;&lt;p&gt;&lt;strong&gt;Retrieving the data&lt;br /&gt;&lt;/strong&gt;Case data is normally retrieved via reports, and hence SQL queries. The following query shows how to extract the correct Billable Time and Total Activity Time:&lt;/p&gt;&lt;p&gt;&lt;span style="font-family:courier new;font-size:85%;"&gt;select i.incidentid, i.title, ir.actualend&lt;br /&gt;, max(timespent) as BillableTime&lt;br /&gt;, isnull(sum(a.actualdurationminutes), 0) as TotalActivityTime&lt;br /&gt;from filteredactivitypointer a&lt;br /&gt;join filteredincident i&lt;br /&gt;on a.regardingobjectid = i.incidentid&lt;br /&gt;left outer join filteredincidentresolution ir&lt;br /&gt;on i.incidentid = ir.incidentidand ir.statecode = 1 -- Resolved incident resolutions&lt;br /&gt;and ir.actualend = (select max(actualend) from filteredincidentresolution ir2 where ir2.incidentid = ir.incidentid and ir2.statecode = 1) -- Most recent ir activity&lt;br /&gt;where i.statecode = 1 -- Resolved cases&lt;br /&gt;group by i.incidentid, i.title, ir.actualend&lt;/span&gt;&lt;/p&gt;&lt;p&gt;A few comments on the query:&lt;/p&gt;&lt;ol&gt;&lt;li&gt;I'm only returning resolved cases in this example, but I've used an outer join to incident resolution to make it easy to change the i.statecode filter to include unresolved cases&lt;/li&gt;&lt;li&gt;I'm using isnull on the actualdurationminutes field to return 0 if there is no activity time&lt;/li&gt;&lt;li&gt;If you add any other fields from the case, or related entities (e.g. account), you'll need to add them to the group by clause as well as the select clause, or join to them in a separate query&lt;/li&gt;&lt;/ol&gt;&lt;p&gt;&lt;strong&gt;Displaying the data in CRM&lt;/strong&gt;&lt;br /&gt;As the billable time and activity time are not stored in the incident entity, they cannot be displayed directly on the case form or in any views. To display this information in the case form, my preferred approach is to create a report using the above SQL query, and display this in an IFrame on the case form, using the techniques described in &lt;a href="http://blogs.msdn.com/crm/archive/2007/10/04/writing-reports-to-display-in-iframes-and-from-isv-config.aspx"&gt;Writing Reports to display in IFrames&lt;/a&gt;&lt;/p&gt;&lt;p&gt;In CRM 3.0 there is no useful way to display this data in a view. In CRM 4.0 this should change, though it may not be as easy as you'd like; CRM 4.0 allows display of related data in a view, but it looks like this is only data from parent entities (e.g. the account to which a case belongs), not the summarised data from child entities that we're discussing here. However, the new PlugIn model allows intercepting of the view data, and should permit such display of child data with a bit of code. This is something I'll be posting on in the future, but it will have to wait till the CRM 4.0 SDK documentation is finalised.&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/199106851038957806-3261678811352225047?l=mscrmuk.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://mscrmuk.blogspot.com/feeds/3261678811352225047/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=199106851038957806&amp;postID=3261678811352225047' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/199106851038957806/posts/default/3261678811352225047'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/199106851038957806/posts/default/3261678811352225047'/><link rel='alternate' type='text/html' href='http://mscrmuk.blogspot.com/2007/11/retrieving-billable-time-and-activity.html' title='Retrieving Billable time and activity time for cases'/><author><name>David Jennaway</name><uri>http://www.blogger.com/profile/09695858105618938443</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://3.bp.blogspot.com/_q3OlQztdu1Y/RzRSlk5emQI/AAAAAAAAAAU/WKNaqCOJGFA/s72-c/resolvecase.JPG' height='72' width='72'/><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-199106851038957806.post-7230427548414930025</id><published>2007-11-08T13:24:00.000Z</published><updated>2007-11-09T18:48:05.501Z</updated><category scheme='http://www.blogger.com/atom/ns#' term='Server code'/><category scheme='http://www.blogger.com/atom/ns#' term='Workflow'/><category scheme='http://www.blogger.com/atom/ns#' term='CRM 3.0'/><title type='text'>Workflow problems on CRM 3.0 with .Net framework 2.0</title><content type='html'>If you have .Net framework 2.0 or higher it can adversely affect the Workflow engine. This can give one or more of the following problems:&lt;br /&gt;&lt;ol&gt;&lt;li&gt;Workflow rules do not run (errors can be found in the event log, pointing you at workflow monitor, but nothing useful can be found in workflow monitor) &lt;/li&gt;&lt;li&gt;Bulk import operations never go beyond pending, even though the workflow service is running &lt;/li&gt;&lt;li&gt;When starting Workflow Manager on the CRM server you get an error message 'Workflow Manager cannot start...configuration file is corrupted'&lt;/li&gt;&lt;li&gt;You cannot attach to the CrmWorkflowService to debug workflow assemblies with Visual Studio .Net 2003&lt;/li&gt;&lt;/ol&gt;&lt;p&gt;This can be because the Crm Workflow Service is running with the 'wrong' version of the .Net Framework. To correct this, create a text file with the following (case-sensitive) text:&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&amp;lt;configuration&amp;gt;&lt;br&gt;&amp;lt;startup&amp;gt;&lt;br&gt;&amp;lt;supportedRuntime version="v1.1.4322"/&amp;gt;&lt;br&gt;&amp;lt;/startup&amp;gt;&lt;br&gt;&amp;lt;/configuration&amp;gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;Save the file as CrmWorkflowService.exe.config in the &lt;program&gt;\Microsoft CRM\Server\bin directory. Then restart the CRM Workflow Service.&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/199106851038957806-7230427548414930025?l=mscrmuk.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://mscrmuk.blogspot.com/feeds/7230427548414930025/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=199106851038957806&amp;postID=7230427548414930025' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/199106851038957806/posts/default/7230427548414930025'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/199106851038957806/posts/default/7230427548414930025'/><link rel='alternate' type='text/html' href='http://mscrmuk.blogspot.com/2007/11/workflow-problems-on-crm-30-with-net.html' title='Workflow problems on CRM 3.0 with .Net framework 2.0'/><author><name>David Jennaway</name><uri>http://www.blogger.com/profile/09695858105618938443</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-199106851038957806.post-4383804015401461469</id><published>2007-11-08T13:04:00.001Z</published><updated>2010-10-02T12:37:11.760+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Customisation'/><category scheme='http://www.blogger.com/atom/ns#' term='Reports'/><title type='text'>Using reports in IFrames and from ISV.Config</title><content type='html'>&lt;span style="font-family:arial;"&gt;This blog is not the first one I've posted on; I've previously been invited to post on the Microsoft CRM Team blog, and I posted this article &lt;/span&gt;&lt;a href="http://blogs.msdn.com/b/crm/archive/2007/10/04/writing-reports-to-display-in-iframes-and-from-isv-config.aspx"&gt;&lt;span style="font-family:arial;"&gt;Writing Reports to display in IFrames and from ISV.Config&lt;/span&gt;&lt;/a&gt;&lt;br /&gt;&lt;span style="font-family:arial;"&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:arial;"&gt;It seems unnecessary to repeat the post here, so I won't. However I will soon be posting some additional reports that build on this technique.&lt;/span&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/199106851038957806-4383804015401461469?l=mscrmuk.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://mscrmuk.blogspot.com/feeds/4383804015401461469/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=199106851038957806&amp;postID=4383804015401461469' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/199106851038957806/posts/default/4383804015401461469'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/199106851038957806/posts/default/4383804015401461469'/><link rel='alternate' type='text/html' href='http://mscrmuk.blogspot.com/2007/11/using-reports-in-iframes-and-from.html' title='Using reports in IFrames and from ISV.Config'/><author><name>David Jennaway</name><uri>http://www.blogger.com/profile/09695858105618938443</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-199106851038957806.post-3533791843283427047</id><published>2007-11-08T12:54:00.000Z</published><updated>2007-11-08T13:04:29.458Z</updated><title type='text'>It has to start somewhere - an introduction</title><content type='html'>&lt;span style="font-family:arial;"&gt;It seems rude not to start with an introduction, so here goes. I've been working with MS CRM as my main technical focus for over 3 years, and became a Microsoft CRM MVP in April 2007. My main online involvement with the 'CRM community' thus far has been in the CRM newsgroups and forums, mostly helping with individual issues. This is the next step...&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:arial;"&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:arial;"&gt;There are several reasons for starting this blog, the main one is to give me more space to cover fuller solutions or ideas than can be covered in the forums. These will be biased towards MS CRM customisation and development, but will doubtless stray into related technologies - SQL, Reporting Services, SharePoint, SSIS and .Net development - as well as infrastructure issues as I find them.&lt;/span&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/199106851038957806-3533791843283427047?l=mscrmuk.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://mscrmuk.blogspot.com/feeds/3533791843283427047/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=199106851038957806&amp;postID=3533791843283427047' title='3 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/199106851038957806/posts/default/3533791843283427047'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/199106851038957806/posts/default/3533791843283427047'/><link rel='alternate' type='text/html' href='http://mscrmuk.blogspot.com/2007/11/it-has-to-start-somewhere-introduction.html' title='It has to start somewhere - an introduction'/><author><name>David Jennaway</name><uri>http://www.blogger.com/profile/09695858105618938443</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>3</thr:total></entry></feed>
