Gustaf's Microsoft Dynamics Crm Blog

"Always start with where the error is, then what the error is" I am MVP, founder and CTO at CRM-Konsulterna AB a company specializing in only Microsoft Dynamics CRM.
  1. Time to move the blog.

    Almost 13 years has passed on blog spot and it is now time to move to my own domain and Wordpress.

    Hence you will now find my blog at https://powerplatform.se with the name #PPDBbG or long version being Power Platform and Dynamics Blog by Gustaf.

    I have moved all posts there too, so you will find the old ones there.


    Gustaf Westerlund
    MVP, Founder and Principal Consultant at CRM-konsulterna AB
    www.crmkonsulterna.se
  2. Working with a Flow to do some text analysis and sentiment analysis on Voice of the customer responses.

    The trick, as the payment model is per run, is to trigger it per Survey Response, and not Question Response. Hence the logic has to loop through all the question responses.

    The way you create a filter in Flow for the query is to use Odata filters. However, I found that these were a casing nightmare, which those of you who have worked with more, probably also have noticed.

    After troubleshooting a lot with different queries in the browser I finally found that the following actually worked. Note that you will have t change the guid to your own.

    https://dev-dtn.api.crm4.dynamics.com/api/data/v9.1/msdyn_questionresponses?$select=msdyn_name,msdyn_SurveyResponseId&$filter=msdyn_SurveyResponseId/msdyn_surveyresponseid%20eq%20460279E7-2AF2-E811-A97F-000D3AB0C08C

    The tricky part, as you can see, is that the first part of the lookup attribute, is defined in camel-case and the one in the related entity (Survey Response) in lower case.

    The part you need in the Flow is the last part, but it is useful to test it directly in the browser to make sure you get the syntax correct.
    Its the filter part of the query that you are to enter into the "Filter query" field, and make sure to make it dynamic. :)

    And this is how it looks in Dynamics 365 CE if you check out the fields. I like to look at them in the list view as I can see the schema name there, which isn't visible in the Form.

    msdyn_SurveyResponseId Lookup from the Question Response Entity. As you can see it seems to be using the Schema name above.

    This is the primary field Survey Response. Do note the subtle difference between the fields, that Id is spellt with a capital "I" in the Schema name. Based on the information above, it hence seems to be using "Name" to indicate the field.

    Hence based on the above, the supposition would be that the syntax is <Schemaname of the lookup>/<name of field in target entity>


    I then did a query to business Unit and I was very surprised to find that it was rather inconsistent and looked like this:

    https://dev-dtn.api.crm4.dynamics.com/api/data/v9.1/businessunits?$select=cntso_organizationbaseurl&$filter=parentbusinessunitid/businessunitid%20eq%20null

    with just the query that would be

    parentbusinessunitid/businessunitid eq null 

    Let's have a look at the fields in Dynamics:


    The Parent Business Unit Lookup in Business Unit (Self Referential). Note that the Schema name is Pascal Case.

    key field, businessunitid in Business Unit


    And as you can see, if we were to follow the syntax set by the example above, this should be:

    ParentBusinessUnitId/businessuniti

    However, that didn't seem to work, and as a pragmatist, I have to conclude, somewhat sad, that this doesn't seem to be very consistent.

    My recommendation is hence when working with this:

    • Do not take any casing for granted
    • <Schemaname of the lookup>/<name of field in target entity> is probably correct for most custom fields/entities.
    • Many older entities and fields, like the businessunit shown above, has been there since CRM 1.0 or at least 3.0, if I remember correctly and hence the syntax might be different.
    • Test your queries directly in the browser like I have shown above.

    Good luck with your Flows.

    And if you know Swedish, make sure you check out my colleague Martin Burmans article on Flow as well. Not sure how well it turns out in translation. https://www.crmkonsulterna.se/flow-i-medvind/

    Gustaf Westerlund
    MVP, Founder and Principal Consultant at CRM-konsulterna AB
    www.crmkonsulterna.se
  3. Tonight Microsoft rolled out an update to Dynamics 365 that seemed to have had a few issues. Most noteably if you have any Lookup-fields in a quickfind views "Find"-columns, it will break. Most of the time, not always. Microsoft knows about this, there are angry threads talking about this, like this one:  https://community.dynamics.com/crm/f/117/t/301925?pi61802=3#responses

    and you can of course create your own support ticket with Microsoft at https://admin.powerplatform.microsoft.com/

    The temporary solution to get this working, or the essential parts for your system, is to remove the Lookup fields from your find columns for the entities that are breaking. This will of course have the effect that no searching can be done in this entity, but you can switch it on again later.

    We have also done some preliminary tests and it seems like the UCI (Unified Interface) is not affected by this. So making a quick UCI App could also be a good, fast fix, especially for the most critical user groups.

    Note also, that some lookups may break as they use the quickfind logic to search the related entity when you are inputing data. Hence if this happens, you might have to do an interim fix there too.

    The error is a "SQL Error" and if you download the logfile, there are two different error messages that I have seen/heard of: (I changed the fieldname to "contactidName")

    Unhandled Exception: System.ServiceModel.FaultException`1[[Microsoft.Xrm.Sdk.OrganizationServiceFault, Microsoft.Xrm.Sdk, Version=9.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35]]: System.Xml.XmlException: Microsoft.Crm.CrmException: Sql error: 'Invalid column name 'contactidName'.'
       at Microsoft.Crm.Application.Platform.ServiceCommands.PlatformCommand.XrmExecuteInternal()
       at Microsoft.Crm.Application.Platform.ServiceCommands.RetrieveMultipleCommand.Execute()
       at Microsoft.Crm.ApplicationQuery.RetrieveMultipleCommand.RetrieveData()
       at Microsoft.Crm.ApplicationQuery.ExecuteQuery()
       at Microsoft.Crm.Application.Platform.Grid.GridDataProviderQueryBuilder.GetData(QueryBuilder queryBuilder)
       at Microsoft.Crm.Application.Platform.Grid.GridDataProviderQueryBuilder.LoadQueryData()
       at Microsoft.Crm.Application.Platform.Grid.GridDataProviderQueryBuilder.LoadData()
       at Microsoft.Crm.Application.Platform.Grid.GridDataProviderBase.PrepareGridData()
       at Microsoft.Crm.Application.Platform.Grid.GridDataProviderBase.PrepareData()
       at Microsoft.Crm.Application.Controls.GridUIProvider.Render(HtmlTextWriter output)
       at Microsoft.Crm.Application.Components.UI.Grid.DataGrid.RenderInnerHtml(HtmlTextWriter output)
       at Microsoft.Crm.Core.Application.WebServices.AppGridWebServiceHandler.GetResetResponseHtml(AppGrid appGrid, StringBuilder sbHtml)
       at Microsoft.Crm.Core.Application.WebServices.AppGridWebServiceHandler.Reset(String gridXml, String id, StringBuilder sbXml, StringBuilder sbHtml)
       at Microsoft.Crm.Core.Application.WebServices.AppGridWebServiceHandler.ProcessRequestInternal(HttpContext context) ---> Microsoft.Crm.CrmException: Sql error: 'Invalid column name 'kuoni_BookingIdName'.'
       at Microsoft.Crm.Application.Platform.ServiceCommands.PlatformCommand.XrmExecuteInternal()
       at Microsoft.Crm.Application.Platform.ServiceCommands.RetrieveMultipleCommand.Execute()
       at Microsoft.Crm.ApplicationQuery.RetrieveMultipleCommand.RetrieveData()
       at Microsoft.Crm.ApplicationQuery.ExecuteQuery()
       at Microsoft.Crm.Application.Platform.Grid.GridDataProviderQueryBuilder.GetData(QueryBuilder queryBuilder)
       at Microsoft.Crm.Application.Platform.Grid.GridDataProviderQueryBuilder.LoadQueryData()
       at Microsoft.Crm.Application.Platform.Grid.GridDataProviderQueryBuilder.LoadData()
       at Microsoft.Crm.Application.Platform.Grid.GridDataProviderBase.PrepareGridData()
       at Microsoft.Crm.Application.Platform.Grid.GridDataProviderBase.PrepareData()
       at Microsoft.Crm.Application.Controls.GridUIProvider.Render(HtmlTextWriter output)
       at Microsoft.Crm.Application.Components.UI.Grid.DataGrid.RenderInnerHtml(HtmlTextWriter output)
       at Microsoft.Crm.Core.Application.WebServices.AppGridWebServiceHandler.GetResetResponseHtml(AppGrid appGrid, StringBuilder sbHtml)
       at Microsoft.Crm.Core.Application.WebServices.AppGridWebServiceHandler.Reset(String gridXml, String id, StringBuilder sbXml, StringBuilder sbHtml)
       at Microsoft.Crm.Core.Application.WebServices.AppGridWebServiceHandler.ProcessRequestInternal(HttpContext context)
       --- End of inner exception stack trace ---
       at Microsoft.Crm.Core.Application.WebServices.AppGridWebServiceHandler.ProcessRequestInternal(HttpContext context)
       at System.Web.HttpApplication.CallHandlerExecutionStep.System.Web.HttpApplication.IExecutionStep.Execute()
       at System.Web.HttpApplication.ExecuteStepImpl(IExecutionStep step)
       at System.Web.HttpApplication.ExecuteStep(IExecutionStep step, Boolean& completedSynchronously): Microsoft Dynamics CRM has experienced an error. Reference number for administrators or support: #BDDD78E5Detail: 
    <OrganizationServiceFault xmlns:i="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://schemas.microsoft.com/xrm/2011/Contracts">
      <ActivityId>64efc536-e25e-4e36-a163-dbe707b07302</ActivityId>
      <ErrorCode>-2147220970</ErrorCode>
      <ErrorDetails xmlns:d2p1="http://schemas.datacontract.org/2004/07/System.Collections.Generic" />
      <Message>System.Xml.XmlException: Microsoft.Crm.CrmException: Sql error: 'Invalid column name 'contactidName'.'
       at Microsoft.Crm.Application.Platform.ServiceCommands.PlatformCommand.XrmExecuteInternal()
       at Microsoft.Crm.Application.Platform.ServiceCommands.RetrieveMultipleCommand.Execute()
       at Microsoft.Crm.ApplicationQuery.RetrieveMultipleCommand.RetrieveData()
       at Microsoft.Crm.ApplicationQuery.ExecuteQuery()
       at Microsoft.Crm.Application.Platform.Grid.GridDataProviderQueryBuilder.GetData(QueryBuilder queryBuilder)
       at Microsoft.Crm.Application.Platform.Grid.GridDataProviderQueryBuilder.LoadQueryData()
       at Microsoft.Crm.Application.Platform.Grid.GridDataProviderQueryBuilder.LoadData()
       at Microsoft.Crm.Application.Platform.Grid.GridDataProviderBase.PrepareGridData()
       at Microsoft.Crm.Application.Platform.Grid.GridDataProviderBase.PrepareData()
       at Microsoft.Crm.Application.Controls.GridUIProvider.Render(HtmlTextWriter output)
       at Microsoft.Crm.Application.Components.UI.Grid.DataGrid.RenderInnerHtml(HtmlTextWriter output)
       at Microsoft.Crm.Core.Application.WebServices.AppGridWebServiceHandler.GetResetResponseHtml(AppGrid appGrid, StringBuilder sbHtml)
       at Microsoft.Crm.Core.Application.WebServices.AppGridWebServiceHandler.Reset(String gridXml, String id, StringBuilder sbXml, StringBuilder sbHtml)
       at Microsoft.Crm.Core.Application.WebServices.AppGridWebServiceHandler.ProcessRequestInternal(HttpContext context) ---&gt; Microsoft.Crm.CrmException: Sql error: 'Invalid column name 'contactidName'.'
       at Microsoft.Crm.Application.Platform.ServiceCommands.PlatformCommand.XrmExecuteInternal()
       at Microsoft.Crm.Application.Platform.ServiceCommands.RetrieveMultipleCommand.Execute()
       at Microsoft.Crm.ApplicationQuery.RetrieveMultipleCommand.RetrieveData()
       at Microsoft.Crm.ApplicationQuery.ExecuteQuery()
       at Microsoft.Crm.Application.Platform.Grid.GridDataProviderQueryBuilder.GetData(QueryBuilder queryBuilder)
       at Microsoft.Crm.Application.Platform.Grid.GridDataProviderQueryBuilder.LoadQueryData()
       at Microsoft.Crm.Application.Platform.Grid.GridDataProviderQueryBuilder.LoadData()
       at Microsoft.Crm.Application.Platform.Grid.GridDataProviderBase.PrepareGridData()
       at Microsoft.Crm.Application.Platform.Grid.GridDataProviderBase.PrepareData()
       at Microsoft.Crm.Application.Controls.GridUIProvider.Render(HtmlTextWriter output)
       at Microsoft.Crm.Application.Components.UI.Grid.DataGrid.RenderInnerHtml(HtmlTextWriter output)
       at Microsoft.Crm.Core.Application.WebServices.AppGridWebServiceHandler.GetResetResponseHtml(AppGrid appGrid, StringBuilder sbHtml)
       at Microsoft.Crm.Core.Application.WebServices.AppGridWebServiceHandler.Reset(String gridXml, String id, StringBuilder sbXml, StringBuilder sbHtml)
       at Microsoft.Crm.Core.Application.WebServices.AppGridWebServiceHandler.ProcessRequestInternal(HttpContext context)
       --- End of inner exception stack trace ---
       at Microsoft.Crm.Core.Application.WebServices.AppGridWebServiceHandler.ProcessRequestInternal(HttpContext context)
       at System.Web.HttpApplication.CallHandlerExecutionStep.System.Web.HttpApplication.IExecutionStep.Execute()
       at System.Web.HttpApplication.ExecuteStepImpl(IExecutionStep step)
       at System.Web.HttpApplication.ExecuteStep(IExecutionStep step, Boolean&amp; completedSynchronously): Microsoft Dynamics CRM has experienced an error. Reference number for administrators or support: #BDDD78E5</Message>
      <Timestamp>2018-11-21T09:41:26.798591Z</Timestamp>
      <ExceptionRetriable>false</ExceptionRetriable>
      <ExceptionSource i:nil="true" />
      <InnerFault>
        <ActivityId>64efc536-e25e-4e36-a163-dbe707b07302</ActivityId>
        <ErrorCode>-2147204784</ErrorCode>
        <ErrorDetails xmlns:d3p1="http://schemas.datacontract.org/2004/07/System.Collections.Generic" />
        <Message>Sql error: 'Invalid column name 'contactidName'.'</Message>
        <Timestamp>2018-11-21T09:41:26.798591Z</Timestamp>
        <ExceptionRetriable>false</ExceptionRetriable>
        <ExceptionSource i:nil="true" />
        <InnerFault i:nil="true" />
        <OriginalException i:nil="true" />
        <TraceText i:nil="true" />
      </InnerFault>
      <OriginalException i:nil="true" />
      <TraceText i:nil="true" />
    </OrganizationServiceFault>

    Second error:

    Unhandled Exception: System.ServiceModel.FaultException`1[[Microsoft.Xrm.Sdk.OrganizationServiceFault, Microsoft.Xrm.Sdk, Version=9.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35]]: System.Xml.XmlException: Microsoft.Crm.CrmException: A quick find filter cannot have any child filters
       at Microsoft.Crm.Application.Platform.ServiceCommands.PlatformCommand.XrmExecuteInternal()
       at Microsoft.Crm.Application.Platform.ServiceCommands.RetrieveMultipleCommand.Execute()
       at Microsoft.Crm.ApplicationQuery.RetrieveMultipleCommand.RetrieveData()
       at Microsoft.Crm.ApplicationQuery.ExecuteQuery()
       at Microsoft.Crm.Application.Platform.Grid.GridDataProviderQueryBuilder.GetData(QueryBuilder queryBuilder)
       at Microsoft.Crm.Application.Platform.Grid.GridDataProviderQueryBuilder.LoadQueryData()
       at Microsoft.Crm.Application.Platform.Grid.GridDataProviderQueryBuilder.LoadData()
       at Microsoft.Crm.Application.Platform.Grid.GridDataProviderBase.PrepareGridData()
       at Microsoft.Crm.Application.Platform.Grid.GridDataProviderBase.PrepareData()
       at Microsoft.Crm.Application.Controls.GridUIProvider.Render(HtmlTextWriter output)
       at Microsoft.Crm.Core.Application.WebServices.AppGridWebServiceHandler.GetRefreshResponseHtml(IGridUIProvider uiProvider, StringBuilder sbTemp)
       at Microsoft.Crm.Core.Application.WebServices.AppGridWebServiceHandler.Refresh(String gridXml, StringBuilder sbXml, StringBuilder sbHtml, Boolean returnJsonData)
       at Microsoft.Crm.Core.Application.WebServices.AppGridWebServiceHandler.ProcessRequestInternal(HttpContext context) ---> Microsoft.Crm.CrmException: A quick find filter cannot have any child filters
       at Microsoft.Crm.Application.Platform.ServiceCommands.PlatformCommand.XrmExecuteInternal()
       at Microsoft.Crm.Application.Platform.ServiceCommands.RetrieveMultipleCommand.Execute()
       at Microsoft.Crm.ApplicationQuery.RetrieveMultipleCommand.RetrieveData()
       at Microsoft.Crm.ApplicationQuery.ExecuteQuery()
       at Microsoft.Crm.Application.Platform.Grid.GridDataProviderQueryBuilder.GetData(QueryBuilder queryBuilder)
       at Microsoft.Crm.Application.Platform.Grid.GridDataProviderQueryBuilder.LoadQueryData()
       at Microsoft.Crm.Application.Platform.Grid.GridDataProviderQueryBuilder.LoadData()
       at Microsoft.Crm.Application.Platform.Grid.GridDataProviderBase.PrepareGridData()
       at Microsoft.Crm.Application.Platform.Grid.GridDataProviderBase.PrepareData()
       at Microsoft.Crm.Application.Controls.GridUIProvider.Render(HtmlTextWriter output)
       at Microsoft.Crm.Core.Application.WebServices.AppGridWebServiceHandler.GetRefreshResponseHtml(IGridUIProvider uiProvider, StringBuilder sbTemp)
       at Microsoft.Crm.Core.Application.WebServices.AppGridWebServiceHandler.Refresh(String gridXml, StringBuilder sbXml, StringBuilder sbHtml, Boolean returnJsonData)
       at Microsoft.Crm.Core.Application.WebServices.AppGridWebServiceHandler.ProcessRequestInternal(HttpContext context)
       --- End of inner exception stack trace ---
       at Microsoft.Crm.Core.Application.WebServices.AppGridWebServiceHandler.ProcessRequestInternal(HttpContext context)
       at System.Web.HttpApplication.CallHandlerExecutionStep.System.Web.HttpApplication.IExecutionStep.Execute()
       at System.Web.HttpApplication.ExecuteStepImpl(IExecutionStep step)
       at System.Web.HttpApplication.ExecuteStep(IExecutionStep step, Boolean& completedSynchronously): Microsoft Dynamics CRM has experienced an error. Reference number for administrators or support: #48A7E659Detail: 
    <OrganizationServiceFault xmlns:i="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://schemas.microsoft.com/xrm/2011/Contracts">
      <ActivityId>fa29912a-47b8-42cf-8e7b-fe3e0c13aecc</ActivityId>
      <ErrorCode>-2147220970</ErrorCode>
      <ErrorDetails xmlns:d2p1="http://schemas.datacontract.org/2004/07/System.Collections.Generic" />
      <Message>System.Xml.XmlException: Microsoft.Crm.CrmException: A quick find filter cannot have any child filters
       at Microsoft.Crm.Application.Platform.ServiceCommands.PlatformCommand.XrmExecuteInternal()
       at Microsoft.Crm.Application.Platform.ServiceCommands.RetrieveMultipleCommand.Execute()
       at Microsoft.Crm.ApplicationQuery.RetrieveMultipleCommand.RetrieveData()
       at Microsoft.Crm.ApplicationQuery.ExecuteQuery()
       at Microsoft.Crm.Application.Platform.Grid.GridDataProviderQueryBuilder.GetData(QueryBuilder queryBuilder)
       at Microsoft.Crm.Application.Platform.Grid.GridDataProviderQueryBuilder.LoadQueryData()
       at Microsoft.Crm.Application.Platform.Grid.GridDataProviderQueryBuilder.LoadData()
       at Microsoft.Crm.Application.Platform.Grid.GridDataProviderBase.PrepareGridData()
       at Microsoft.Crm.Application.Platform.Grid.GridDataProviderBase.PrepareData()
       at Microsoft.Crm.Application.Controls.GridUIProvider.Render(HtmlTextWriter output)
       at Microsoft.Crm.Core.Application.WebServices.AppGridWebServiceHandler.GetRefreshResponseHtml(IGridUIProvider uiProvider, StringBuilder sbTemp)
       at Microsoft.Crm.Core.Application.WebServices.AppGridWebServiceHandler.Refresh(String gridXml, StringBuilder sbXml, StringBuilder sbHtml, Boolean returnJsonData)
       at Microsoft.Crm.Core.Application.WebServices.AppGridWebServiceHandler.ProcessRequestInternal(HttpContext context) ---&gt; Microsoft.Crm.CrmException: A quick find filter cannot have any child filters
       at Microsoft.Crm.Application.Platform.ServiceCommands.PlatformCommand.XrmExecuteInternal()
       at Microsoft.Crm.Application.Platform.ServiceCommands.RetrieveMultipleCommand.Execute()
       at Microsoft.Crm.ApplicationQuery.RetrieveMultipleCommand.RetrieveData()
       at Microsoft.Crm.ApplicationQuery.ExecuteQuery()
       at Microsoft.Crm.Application.Platform.Grid.GridDataProviderQueryBuilder.GetData(QueryBuilder queryBuilder)
       at Microsoft.Crm.Application.Platform.Grid.GridDataProviderQueryBuilder.LoadQueryData()
       at Microsoft.Crm.Application.Platform.Grid.GridDataProviderQueryBuilder.LoadData()
       at Microsoft.Crm.Application.Platform.Grid.GridDataProviderBase.PrepareGridData()
       at Microsoft.Crm.Application.Platform.Grid.GridDataProviderBase.PrepareData()
       at Microsoft.Crm.Application.Controls.GridUIProvider.Render(HtmlTextWriter output)
       at Microsoft.Crm.Core.Application.WebServices.AppGridWebServiceHandler.GetRefreshResponseHtml(IGridUIProvider uiProvider, StringBuilder sbTemp)
       at Microsoft.Crm.Core.Application.WebServices.AppGridWebServiceHandler.Refresh(String gridXml, StringBuilder sbXml, StringBuilder sbHtml, Boolean returnJsonData)
       at Microsoft.Crm.Core.Application.WebServices.AppGridWebServiceHandler.ProcessRequestInternal(HttpContext context)
       --- End of inner exception stack trace ---
       at Microsoft.Crm.Core.Application.WebServices.AppGridWebServiceHandler.ProcessRequestInternal(HttpContext context)
       at System.Web.HttpApplication.CallHandlerExecutionStep.System.Web.HttpApplication.IExecutionStep.Execute()
       at System.Web.HttpApplication.ExecuteStepImpl(IExecutionStep step)
       at System.Web.HttpApplication.ExecuteStep(IExecutionStep step, Boolean&amp; completedSynchronously): Microsoft Dynamics CRM has experienced an error. Reference number for administrators or support: #48A7E659</Message>
      <Timestamp>2018-11-21T10:28:58.4053402Z</Timestamp>
      <ExceptionRetriable>false</ExceptionRetriable>
      <ExceptionSource i:nil="true" />
      <InnerFault>
        <ActivityId>fa29912a-47b8-42cf-8e7b-fe3e0c13aecc</ActivityId>
        <ErrorCode>-2147217118</ErrorCode>
        <ErrorDetails xmlns:d3p1="http://schemas.datacontract.org/2004/07/System.Collections.Generic" />
        <Message>A quick find filter cannot have any child filters</Message>
        <Timestamp>2018-11-21T10:28:58.4053402Z</Timestamp>
        <ExceptionRetriable>false</ExceptionRetriable>
        <ExceptionSource i:nil="true" />
        <InnerFault i:nil="true" />
        <OriginalException i:nil="true" />
        <TraceText i:nil="true" />
      </InnerFault>
      <OriginalException i:nil="true" />
      <TraceText i:nil="true" />
    </OrganizationServiceFault>



    Gustaf Westerlund
    MVP, Founder and Principal Consultant at CRM-konsulterna AB
    www.crmkonsulterna.se
  4. For the first time ever 9 Business Solutions MVP:s will converge on Stockholm to share their knowledge! In the amazing Dynamics 365 Saturday event which will be held on the 10:th of November 2018 at the Microsoft Office in Kista, just outside Stockholm. As usual, the Dynamics 365 Saturdays are free.

    As the main organizer, me, my company CRM-Konsulterna and the MVP Jonas Rapp, will also help out it is of course very satisfying to have so many talented people sign up to speak. A lot is happening, and version 9.1 was just rolled out today in EMEA if you didn't notice. Hence there is a lot to talk about.

    There will be three tracks:

    • Application - sessions on configuration and usage of Dynamics 365
    • Development - sessions on development and configuration that could be viewed as programming like Flow, LogicApps, PowerApps/CanvasApps etc.
    • Business/Project Management - sessions on how to best run projects, businesses, your career and other softer issues but all related to Dynamics 365.
    As the host, I really hope you are able to secure a seat, we are limiting the amount to 150 and we are getting signups by the hour, so be sure to book your seat now.

    Read more and sign up here: http://365saturday.com/dynamics/stockholm-2018/ 


    Gustaf Westerlund
    MVP, Founder and Principal Consultant at CRM-konsulterna AB
    www.crmkonsulterna.se
  5. The server side sync is a technology for connecting Dynamics 365 CE to an Exchange server. When connecting an Online Dynamics 365 to an onprem Exchange there are some requirement that need to be met. These can be found here: https://technet.microsoft.com/sv-se/library/mt622059.aspx

    Piping data to and from Exchange and Dynamics
    By Quartl [CC BY-SA 3.0], from Wikimedia Commons
    However, I just had a meeting with Microsoft and based on the version shown 2018-09-05, they have now added some new features that they haven't had time to get into the documentation yet.

    Some of the most interesting parts of the integration is that the it requires Basic Authentication for EWS (Exchange Web Service). Of the three types of authentication available Kerberos, NTLM and Basic, Basic Authentication is, as the name might hint, the least secure. Hence it is also not very well liked by many Exchange admins and may be a blocker for enabling Server Side Sync in Dynamics 365.

    In the meeting I just had with Microsoft, they mentioned that they now support NTLM as well! That is great news as that will enable more organizations to enable Server Side Sync.

    There is still a requirement on using a user with Application Impersonation rights which might be an issue as that can be viewed as having too high rights within the Exchange server. For this there is currently no good alternative solution. I guess making sure that the Dynamics Admins are trustworthy and knowing that the password is encrypted in Dynamics might ease some of that. But if the impersonation user is compromised, then a haxxor with the right tool or dev skills could compromise the entire Exchange server.

    Microsoft also mentioned another common issue that can arise with the Outlook App when using SSS and hybrid connection to an Exchange 2013 onprem. It will show a quick alert saying "Can't connect to Exchange" but it will be able to load the entire Dynamics parts.

    This might be caused by the fact, according to Microsoft, that Exchange 2013, doesn't automatically create a self-signed certificate that it can use for communication. Hence this has to be done.

    This can be fixed by first creating a self signed certificate and then modify the authorization configuration using instruction found here . Lastly publish the certificate. It can also be a good idea to check that the certificate is still valid and hasn't expired.

    I will see if I can create a more detailed instruction on this later.

    Gustaf Westerlund
    MVP, Founder and Principal Consultant at CRM-konsulterna AB
    www.crmkonsulterna.se
  6. PowerApps or as the new name for it is, Canvas driven Apps, is a very fast low/no-code way of creating applications that can fill in the blanks where Dynamics 365 CE sometimes fit. Can for instance be when there is a mapping entity, a complex calendar functionality or even integrations with a camera or other applications directly. These things can be done, some are even supported within the new UI/UCI if you are running it through the tablet/mobile client. However, there is currently no easy way that I have found to just add a PowerApp/Canvas Drive App (I will just call it PowerApp below to make things easier) to Dynamics. But after a chat with my friend, ex MVP and now Microsoft Global Black Belt Carsten Groth (isn't that a cool name for a team by the way?) he told me that it is possible to embed PowerApps. So I googled a bit a found that no one seemed to have blogged about this (if you have, please tell me in the comments) except for other it concerning other applications like SharePoint. I tried it out and found that it wasn't that hard at all to embedd a PowerApp into Dynamics 365.

    The first thing we have to start with is to create our PowerApp. You can get to this place by browsing to https://web.powerapps.com or clicking the waffle in Office365 and then selecting PowerApps. In my case, I used the Dynamics 365 template and pointed to the Case Entity and did more or less pressed Next-next-finnish. I did replace the field that was shown in the first screen from the Guid of the case to the field "title" as that makes a little bit more sense looking at.


    So what I was looking for when creating the PowerApp was the AppId, in this case:
    "904e3ac1-1e26-4b4b-a384-971485f6709c"

    What we then need is the embedding syntax for PowerApps which is:
    <iframe src="https://web.powerapps.com/webplayer/iframeapp?source=iframe&screenColor=rgba(104,101,171,1)&appId=/providers/Microsoft.PowerApps/apps/[AppId]" />

    You need to replace the [AppId] with your AppId. Also, if you do not specify it, the iframe it will typically render rather small so I would recommend either setting the size of it directly with width and height attributes or using css, the latter being more kosher.

    I tried setting an Iframe directly with this in Dynamics 365, but that didn't seem to work. All I got was a spinner like this:
    Spinner which never stops when tried to add PowerApp directly
    Not sure why this is.

    So, I circumvented it and created a very small html-page like this:

    <html>
    <body>
    <iframe width="1024px" height="768px" src="https://web.powerapps.com/webplayer/iframeapp?source=iframe&screenColor=rgba(104,101,171,1)&appId=/providers/Microsoft.PowerApps/apps/904e3ac1-1e26-4b4b-a384-971485f6709c" />
    </body>
    </html>

    This time, when trying the TestPowerApp.html-page from my local drive, the spinner was quickly replaced by this and then by the App

    Then I uploaded this file as a webresource to Dynamics.

    Create a webresource with the simple html-page pointing to the PowerApp

    After uploading it, in the WebResource screen, you can test the page by clicking on the URL. It should show a webpage with the PowerApp.

    The PowerApp running as a webresource in Dynamicws 365
    Now you can use this web resource wherever you want. Like directly in a sitemap:

    Added PowerApp webresource to the Marketing Area as a Subarea called "Power App Cases"

    It should be possible to send parameters to the PowerApp as well making them context aware so that we can create PowerApps that for instance show up within a case and show specific data on that case after you have selected it in Dynamics 365. However, if you look at the iframe syntax you will see that the AppId and stuff is already a parameter and I need to research this a bit more to be able to figure it out. I think that the html web resource probably has to shuffle the query string parameters from Dynamics to PowerApps. I will leave this hanging and hope that someone else in the community catches this ball! Otherwise I will try to figure it out later.

    As CDS (common data service) and Modular Driven Apps are the same thing as Dynamics 365, just with less sugar on top, this technique can be used there as well. 

    If you find anything unclear or have any questions, please leave a comment (moderated).

    Gustaf Westerlund
    MVP, Founder and Principal Consultant at CRM-konsulterna AB
    www.crmkonsulterna.se
  7. Setting up Dynamics 365 Data Export Service requires a Azure KeyVault to be set up which is typically done using a PowerShell script which can be found in the Data Export Service setup wizard. However, if you run into issues setting this up, it might be easier to do this directly in Azure by minimizing the steps of the scripts. This was a tip that my friend and Business Solution MVP Scott Durow recommended. He mentions this in his very instructive video, but doesn't actually show how, so I thought I'd just detail how I made it work.

    First some background. The reason why I even started investigating how to do this manually was that when I tried running the PowerShell script supplied by Microsoft in the wizard.
    Press the "i" icon to get a window containing the PowerShell Script that Microsoft recommends for setting up the Key Vault.
    When running the PowerShell script both as myself (not a global admin) and asking a global admin to do it, it failed in the latter parts. The key vault was created by some of the access policies seemed to be missing and it just didn't work. My users rights in Azure was Contributor in the Resource Group, and it was a bit interesting cause the global admin and I got different error messages, but when I finally managed to create the key vault manually, I could do it all with my user, so it didn't seem I was missing any rights to do it.

    First step is to make sure you have all your data straight. The power shell script is good for this. Check out Scott clip if you want to know how to find the different strings. He shows it very clearly.

     Just copied from the PS-Script:
    $subscriptionId = '<subscription ID>'
    $keyvaultName = 'MyVault'
    $secretName ='MySecretName'
    $location = 'North Europe'
    $connectionString = 'Server=tcp:<db-name>,1433;
    Initial Catalog=<catalog>;
    Persist Security Info=False;
    User ID={your_username};
    Password={your_password};
    MultipleActiveResultSets=False;
    Encrypt=True;TrustServerCertificate=False;Connection Timeout=30;'
    $organizationIdList = '<DYN365GUID>
    $tenantId = '<AZURE TENANT ID>' 

    The highlighted parts have to be replaced by your settings. I will use these variables to have something to reference to further in this article.

    Search for Key Vault and add the "Key vault", the top one in this picture

    Then we have to set it up. Not so tricky if you have worked with Azure before. Consider if you want to work in an existing Resourcegroup or if you want to create a new one. Typically you need to have Azure SQL services running as well so it might be good to keep them all together to be able to see the costs and control who has access why a resource group might be a good idea. But that should hence already exist. If not, you can create it. I would recommend keeping Azure SQL and Key vault in the same, not sure if it actually works in different resource groups, probably does, but I haven't tested.

    Creating the key vault - in this case I am creating a new resource group, normally it would already exist
    Azure will add you as the default principal with access to the key vault. We will add Data Export Service to this later. For now, just create it.

    Now we need to open the Key vault and select the "Secrets" section in the menu on the left hand side and press the button:

    "+ Generate/Import" 

    Then you have to enter you Secret name ($secretName) and the connection string ($connectionString) into the value.
    Creating a secret - $secretname in Name and $connectionstring in Value

    Press "Create".

    You should now return to the previous screen and see a row for your secret.
    Select it.

    It should open the settings panel for the Secret, press the "Tags" part which is located in the middle and add a tag which has $OrgIdList ($organizationIdList) as the key and Tennant ($tenantId) as value. I have blurred them out below as they are rather private.

    Adding a tag with OrgIdList and tenantId to a Secret

    You then need to go back to the Key Vault and click on the "Access Policies" menu item, you should then see yourself as the principal as this was set when we created the key vault. We now need to add Data Export Service as a valid Principal with read access rights.

    So click "Add", click "Select Principal" and search for "b861dbcc-a7ef-4219-a005-0e4de4ea7dcf" which is the ID for Data Export Service. It should show up like this:

    It needs to have "Secret Management Operations - GET" permissions and nothing else.

    Now, go back to the Secret and copy the URI to the Secret.

    Getting the URI for the Key Vault Secret
    Paste it into the Data Export Service Wizard field for Key Vault.

    Fill in the other information and press validate. Hopefully it will work out well!

    Some issues

    Being too cheap with the Azure SQL level
    If you don't go for a Azure SQL P1 and choose a lower tier, you might get this warning:
    We tried an S0 for our Dev environment and tried to sync a couple of million records and that just didn't work, we got tons of errors. We upgraded the ASQL to S2 and then at least we didn't get any errors. We are planning for P1s in UAT and production.

    Might have to set activation date on secret
    Seems that you might have to set an activation date on the secret. Not sure why this is, the PS-script doesn't seem to do this. But not very hard.
    Added activation date on the Secret from June 4.th

    Using Database schema that is not created
    The default database schema is "dbo" in the Data Export Service Wizard. If you change this to something else like "crm" and you haven't created this in the database, you will get an error. It is simple to fix, you just have to go into the database and create the schema. To create the schema "crm" open a query and run:
    CREATE SCHEMA crm

    For more information on how to create schemas, check this site: https://docs.microsoft.com/en-us/sql/t-sql/statements/create-schema-transact-sql?view=sql-server-2017

    Once the schema has been created, there should be no problem using it, as long as the user has permissions using it.


    I hope this works for you. If you have any questions, don't hesitate to leave a comment.

    Gustaf Westerlund
    MVP, Founder and Principal Consultant at CRM-konsulterna AB
    www.crmkonsulterna.se
  8. On the eve of GDPR what could be more fitting than a post on GDPR. I think everyone is probably deadly tired of all the consent emails and I think that they will probably even have reached our friends in the US and Asia by now.

    This article relates to legal matters on GDPR and are based on my personal interpretations and are not to be viewed as legal advice.

    One interesting thing that has to be considered in relation to GDPR is how to handle personal information in non-production environments/instances. Microsoft have made it painfully easy with the instance manager to be able to copy the production instance but do you really have the right to use your customers personal information in a development, UAT or staging environment? Do you have legal support for that? I think that would be a very hard argument to make? Have you gotten your customers explicit consent for using their personal data for that purpose? Probably not. Hence, if you are planning on keeping the instance/environment for more than 30 days, you will need to remove all personal information from to stay within the boundaries of GDPR. I have found that using SSIS with Kingswaysoft and the Anonymization component in the productivity toolkit is very useful. I will in this rather lenghty article describe how I have used it to set up an anoymization script.

    First of all you need to download SSDT and Kingswaysoft Dynamics 365 and Productivity Packs

    Then start a new Business Intelligence -> Integrations Services project.


    Then start by right clicking in the empty field at the bottom where it says "Connection managers" and choose "New connection..."


    In the dialog that shows up choose "DynamicsCRM"

    You should now see a dialog showing the connection settings to Dynamics.

    Connection settings for your instance
    Choose the right settings for your instance. Test your connection at the bottom when you are done to make sure it works. Make extra sure you are not connecting to your production environment, wouldn't want to anonymize that!

    When this is done, it is time to make your first Data Flow Task. Work in SSIS is divided into two parts, Control Flow and Data Flow. The control flow is the orchestration, which tells SSIS in which order everything is to be run. If you want thing to run in parallel, just have to boxes next to each other, if you want one Data Flow to run before the other, drag the arrow from the first to the second. It is also possible to have entire "Sequence containers" which can hold several components and make sure they execute before moving to the next stage.

    Let's start by dragging one new Data Flow from the Toolbox on the left hand side to the Control Flow work pane. Then double click it. This will open it up.

    You will now see that the tab at the top has changed to "Data Flow" from the previous "Control Flow". In the "Data Flow" view you will also have a different set of toolbox components available.

    In the "Data Flow" you will control a single data flow. For instance the anonymization of Contact.

    Start by dragging the Dynamics CRM Source from the toolbox (on the left) to the workspace (the big pane in the middle. Then double click it. - Before looking at the details of the source component, I like using FetchXML when building queries and of course the best way to build queries with FetchXML is using FetchXMLBuilderin XrmToolBox(thanks Jonas Rapp and Tanguy Touzard for all your work!) but if that is too much heavy lifting (it really isn't), the easiest way to get a FetchXML query is to make an advance find query and export it with the "Download FetchXML" button in the top right hand side of the ribbon of the Advanced Find query builder. So let's say we have decided the following fields in Contact are personal information and need to be anonymized:

    The column editor in advaced find - don't use composite fields like "fullname" or Address1
    Downloading the FetchXml, and setting the Source component in SSDT (Visual Studio) will make it look like this:

    I have set the "Connection Manager" to "Target" as we are using the same source and target (reading and writing to the same system.

    I am leaving batch size as 2000. Seems to work well. Don't reduce it too much, remember the API limit of 60 000 calls per 5 min period.

    If you would like to try it a bit, you can set the "Max rows returned" to for instance "10" and then try it out a bit to see that it isn't going crazy.

    Source type I like as FetchXML - remember that you can have FetchXMLs with data from several entities which can make queries a lot easier than trying to match the data with lookups in SSIS.

    I always try to read all data in UTC and write it in UTC which in most cases makes it correct. But make sure you understand how timezones work if you need to fiddle with this.

    Also, don't include more columns than you need. It will just make your script slow. After adding the FetchXML or changing it, it will try to parse it and read the meta data from Dyn365/CRM. Hence there might be a slight delay. You can check what data you will output from this component by clicking on "Columns" on the left hand side.

    When done, press "OK" to go back to the "Data Flow" pane.

    Now add a "Data anonymization" component and drag the arrow from the Source component to the Anonymizer. Then double click the anoymizer.

    You should see something like this, where I have set anonymization settings for the different columns. By default it will say "Ignore" on all columns.


    Try out the different anonymization types. Some are more generic than others. When done, click Ok and go back the data flow pane. Add a Dynamics CRM Destination and drag the blue arrow from the anonymizer (blue arrows are the normal data output, red arrows are error output) to the Dynamics CRM Destination component. Then double click it. The view in the data flow should look something like the picture below.

    Dyn365 Soruce -> anoymizer -> writing to Dyn365
    Dyn365 destination component - set values where the arrows are

    When setting up the destination component, there are a few things to consider:

    • In this case we are always doing updates - hence set the action to update. It is faster than upsert.
    • You have to set the Destination Entity.
    • If you write data to Dyn365 with high latency, no batching and no threads you will be able to update at about 2-3 records per second. With low latency, correct batch setting and multi threading, I have been able to get up to 300 records per second. Very dependant on entity. Hold the mouse of the blue "i" just after the "Enable Multithread Writing" for some deep end tips from the scholars at Kingswaysoft.
    • Error handling is recommended to be directed at a file or some other output where you can monitor it. If you do nothing about it, and you get an error, it will break the flow and stop. You can control error handling of the destination component by clicking on the "Error handling" tab on the left hand side. Remember that all types of exceptions thrown by Dyn365 you will get here as well, like missing rights, disabled records etc.
    A normal problem that needs to be handled is that records are deactivated and deactivated records cannot be changed, they have to be opened first, then changed, then re-closed.

    This is an example of a dataflow handling this:
    Data flow which splits the deactivated records to the left, adds two special columns to reactivate them, writes an update with only the statecode & statusreason to the record and then merges the two data streams and writes the original values, which recloses the ones that were closed from the beginning


    This is how the conditional split is defined - if statecode is 0, send them to the output called "open" otherwise send them to the output called closed

    Then you can test run your data flow, by right clicking the data flow pane, and pressing "Execute Task"
    And when you have assemble an larger control flow - like for instance this:
    A control flow with several dataflow being disabled - all in sequence.
    you can execute the entire flow by clicking the green plus sign in the ribbon.



    Gustaf Westerlund
    MVP, Founder and Principal Consultant at CRM-konsulterna AB
    www.crmkonsulterna.se
  9. In case you haven't seen it, the Dynamics 365 Admin Portal it is a great place to create and manage you Dynamics 365 tickets.

    You get to it using this URL: https://admin.dynamics.com/



    I haven't found a link to the admin portal from the instance manger or any other place in O365 or Dyn365 yet so I have just created a bookmark for it, so I suggest you do the same.

    Also, as I am a frequent Microsoft Support user, and often have customers with many instances, I have tried to consolidate many instances into one ticket. They don't want that. Better to create one ticket for each instance. (probably gets someone a higher salary too :)) However, I did notice that there seems to be some duplicate detection going on, so try to avoid using the same "Issue Summary" for several tickets - as that will just make the later ones disappear without any error message (hint Microsoft, please fix this! - at least give a decent error message).

    In order to create tickets, you need to be either O365 Global Admin or Dynamics 365 Service Administrator. There might be some other admin as well that has the right to create tickets, but I don't think so.

    Gustaf Westerlund
    MVP, Founder and Principal Consultant at CRM-konsulterna AB
    www.crmkonsulterna.se
  10. Photo by Vidar Nordli-Mathisen on Unsplash
    Related to my last post, on working with the API quickly, Microsoft have now released official
    documentation that they will, effectivly March the 19:th start limiting the number of API-calls per instance that is allowed to stop what is called "noisy neighbour" problems.

    First of all, read the full article here: https://docs.microsoft.com/en-us/dynamics365/customer-engagement/developer/api-limits 

    Let's break this down a bit, 60 000 calls per 5 minutes, translates to about 200 calls per second. If you break this, you will start getting exceptions, until the 5 minute period has ended. You are expected to back off, and essentialy handle this. That is the short version. Read the full article for more details.

    Update: George Doubinski, a friend of mine and one of the brains of CRM Tip of the Day made me aware of the fact that the limit is per user. I will update the article below on what this means.

    What does this mean? Is this a problem?

    For most organizations, no, at least that I work with, I not even close to breaking this. If they are using some integration tools like Kingswaysoft or other tools which enable multithreaded integrations, but generally do not need that kind of data throughput then you might temporarily be shut down, but it should self heal after some time, as after each 5 minute time span, you will get another 60 000 requests. That could probably quite easily be fixed by checking the settings of the integration tool. Update: Also, if you integrate each system using a separate accont, you do not risk one system temporarily blocking many other systems from integrating to Dynamics 365. If you are using normal users, this will of course entail a certain license cost, why I generally recommend using app users for integrations, if possible. And after this, you should have one app user for each integrating system.

    However, there are some organizations where I forsee issues, and these are organizations which have combinations of any of the following criteria:

    1. Third party products which, like Marketing Automation, (ClickDimensions, FreshRelevance, SalesForce Marketing Cloud) which have not had time, or got this in their scope yet, and have large amounts of data that they integrate into Dynamics 365. Update: Especially if the user they are using to integrate, the service user, is a normal user, either used by a normal user, or shared with integrations with other systems.
    2. Legacy Code that has been upgrade to new SDK but uses inefficient architecture - can for example have issues with using ExecuteMultiple which in the article above is described as the recommended best practice. Typically for the reason that the architecure of the code, would require major rewriting to allow for ExecuteMultiple. Update: In this case I strongly recommend looking at using a dedicated user for this specific integration, to isolate any limiations set on that user.
    3. Organizations with multiple heavy integrations to Dynamics 365. Will be hard to control that the sum total does not exceed 60k per second, and handle back-off in a controlled way. The only reasonable way would probably be to rewrite the integrations to use a proxy or queue instead like Azure Service Bus Queues to integrate and have a single integration interface. Probably a lot easier to write in a blog article than to do in real life. Update: This was an incorrection deduction from my part, as it is not based on the sum total, but on the sum per user, this is not a risk unless many integrations use the same user for integration which I do not recommend.
    4. Organizations with complex heavy integrations with thousands of lines of integration code that need to be redesigned, rewritten, tested and deployed before March 19:th. And there is no way to test it as there is no TAP/Beta program for this "Feature". Update: This is still very relevant. Even such a small change as changing the integrating user for an external system should be thoroughly tested and for larger implementations that can be hard to do before March 19.

    Example

    I see is a typical B2C organization running Dynamics 365 with a marketing automation addon with email tracking and webtracking. They also have a very time critical integration of orders to be able to handle any incidents. Even if the order integration in itself does not reach the limits, it is not unforseeable that a mailblast, especially a good mail blast, to which many customers read the emails click the links, go their site, check their offers and start ordering, would cause a surge of traffic on the Marketing Automation integration - Dynamics 365 API. This of course depends on the settings of this, but perhaps it is critical that all events be tracked to Dynamics. With a mailblast to let's say 1 Million recipients, quickly hitting the 60 k/5 min limit would happen. When this happens, this would also block all orders from going to Dynamics, causing an effective stop for working with any new incidents in the system.
    Update: This is, of course, only relevant if both systems are integrating using the same user. Don't. However, the marketing automation system above, would hit the limit fast anyway and if the supplier of this system didn't have time to update their product/service then it would handle this incorrectly. I recommend checking integrating systems and try to turn down the verbosity of what they are writing to Dynamics 365. Then after March 18 when we see how this falls out in detail, you can test a more verbose setting in a test environment, and then see how that falls out.

    Summary

    For small and medium companies with low complexity working mainly with B2B. I don't see that much of a problem. Larger companies with complex integrations, large databases, integrations to webtracking, email tracking which often will be B2C companies which have higher levels of automation and larger databases of customers, will probably have larger problems with this and need to start think about this right now.

    We need to come back to this subject post March 19, to see how this will really work. But I think the real problem will be for the larger orgs with many and heavy integrations.

    I would be really glad to hear your views on this like I got Georges'.


    Gustaf Westerlund
    MVP, Founder and Principal Consultant at CRM-konsulterna AB
    www.crmkonsulterna.se
  11. A quick one today...

    Needed to delete a couple of million records for a customer and the natural thing was to use the Bulk Deletion service, well, I turned it on and it was extremely slow. Only got about 10 records/s which would cause the entire delete to take over a week. I have checked with Microsoft and this is not a bug, but it is working as designed and is not designed to be super fast. According to Microsoft bulk deletion jobs are put on the async queue on low priority to allow other more important jobs higher prio.

    And a favorite quote of mine from Purvin Patel of Microsoft "Does a dump truck need to outrace a Ferrari?" - and I think that the answer to that question is: it depends. Sometimes it does.  

    Personally I would sometimes like it to be as fast as possible when removing a lot of records.

    I also checked to see how fast the deletion would be with SSIS and Kingswaysoft. Used the following settings:

    • VM about 5 ms from the Dynamics 365 instance (important that it not be too far, use an Azure VM for this)
    • Used 64 threads
    • Used Execute Multiple batching with 10 (cannot use more that 10 if you are using a lot of threads, ie more than 2)
    • VM has 8 virtual cores and 32 GB memory
    • Loading in batches of 2000. Only loading the id-column, as that is all that is needed.

    With this setup, I got somewhere around 345 records deleted per second. Which is a tad more than 34x faster than the bulk delete.

    So, want to delete a lot of stuff, maybe Bulk Delete is not the way to go. Not yet anyway, let's hope Microsoft makes it faster!

    (this post was updated on Feb the 9:th 2018)

    Gustaf Westerlund
    MVP, Founder and Principal Consultant at CRM-konsulterna AB
    www.crmkonsulterna.se
  12. One of my most popular posts is a collation on which browsers are actually supported for Dynamics 365 CE. This is not strange since it is a common issue, we often have customers call our support complaining that Dynamics doesn't work well, and as described in the original article, the cause is usually that they are using an unsupported browser.

    Also the Micrsoft Technet article for this: https://docs.microsoft.com/en-us/dynamics365/customer-engagement/admin/supported-web-browsers-and-mobile-devices
    and the detailed version: https://technet.microsoft.com/en-us/library/hh699710.aspx mainly focuses on Edge and Internet Explorer compatibility for the different windows versions. And despite Microsoft's hopes, the rest of the world have not totally turned to all of their programs, yet.

    There are currently some issues with version 9.0 as well, why I thought it might be a good idea to write a new article on which browsers are the supported one in a easily overviewable grid.

    A brief explanation to the different abbreviations used in the picture:

    • SW - Supported and Working.
    • SW* - Supported and Working on OS X as designed but with somewhat limited functionality. If you compare Dynamics on OS X running Safari with it running Edge on a Win 10 you will notice that there are more options.
    • SW** - The app is not the same thing as the browser at the moment. The Unified Interface will make them almost the same. There will still be differences, in that the app will have better integrations to the device's hardware, like camera, etc. Especially for the earlier versions, the app was very limited. It is more powerful know. For field service there is also a special Field Service App which is not as HTML/JS based (it is based on Resco).
    • SW*** - I have not had the chance to test if version 9.0 works on a Nexus 10 running Chrome but the official documentation says it should work. However, as v.9.0 does not work with Chrome at the moment, (this will probably be fixed very soon) I would actually be surprised if it worked for Chrome on Nexus 10.
    • NS - Not supported. This does not mean, however, that you cannot get it to work. I have heard of people that mange to get Chrome on OS X to go into some "PC" mode which tricks Dynamics. This still doesn't make it supported, but it might work for you. The problem might be if you have any issues, that Microsoft Support could leave you hanging.
    • SNW - Supported but Not Working - As for Chrome on Windows, the general story is that Microsoft only support the latest version of it. However, despite version 9.0 official supporting Chrome on Windows, it doesn't seem to actually work. I would presume that they will fix this soon. The problem is that Dynamics 365 won't actually load.
    The support matrix for the browsers is generally a tricky question. The matrix above is also simplified a bit as I have not included the parameter of the different versions of Operating systems. It can probably be presumed that Microsoft will make greater efforts into making sure that the latest and possibly even some versions before that, that they know customers are using for Edge and Internet Explorer, work well with Dynamics 365. I know some of you will probably think I am crazy for even mentioning Internet Explorer, but I have several customers who still have IE as the company standard browser, and it is not due to Dynamics 365.

    As for Firefox, Chrome and Safari, these browsers might be very popular, but from a Microsoft perspective I can see a very tricky situation, and that is that they roll out changes without notifying anyone. This was, for instance, done by Google a couple of years ago when they changed their handling of modal dialogs. This caused many dialog handling features of Dynamics CRM (at that time) to break. It took some time for Microsoft to identify the change, fix it, make sure there were no regression errors, roll it through all testing scenarios and deployment stages and controlls they do until they were able to get a fix out. It did come out quite fast, but there were some people nagging at Microsoft for having a bad product, which I personally find a bit unfair.

    The essence of the two paragraphs above is; feel free to use Chrome, Safari or Firefox but I would suggest always having Edge and/or IE as a backup option in the case that an update comes to the main browser that severely affects the usage of Dynamics 365.

    And I hope that Microsoft soon fixes the error that stops us from using Chrome with ver. 9.0. Any day now!


    Gustaf Westerlund
    MVP, Founder and Principal Consultant at CRM-konsulterna AB
    www.crmkonsulterna.se
  13. If you are using Dynamics 365 Online, Dynamics 365 Support is your IT-department for your Dynamics system and you need to know or start learning how to working with them in a good way. There are several things you should consider.

    Registering a support ticket
    First of all, registering a support ticket is of course important. This might not be as trivial as it seems, as it depends on which type of license you have. If you have bought your licenses using CSP (Cloud Service Provider) or Select/Volume Licensing then you will most probably be directed to your CSP/Select partner for any support issues. You can of course buy premier support from Microsoft but that might not always be an option for smaller companies. There are some tricks as well if you are stuck with CSP/Select or similar, and will be happy to tell you about these in person if I meet you, but I won't write about them, as I am afraid it will be "fixed" which would be sad.

    If you have bought your licenses directly through the O365 portal, you can also create a ticket using the portal. You need to be a Global Admin or a Dynamics 365 Service Admin to place a ticket. Currently you cannot indicate that the ticket is for Dynamics so you simply write so in the text and the O365 support team will create a new Dynamics 365 ticket for you. I was amazed at how fast the Office 365 support called me after registering a ticket, I think it took less than 1 minute. So I would suggest you choose the option "call me".

    If you have a partner, I strongly suggest that you register them in the Office 365 portal for the Dynamics 365 subscription as Partner of Record (PoR). This will make your company show up in their Microsoft partner portal where they can register a support ticket for you.

    Checklist
    When registering the ticket with Microsoft, there are some things you have to note:

    1. Be polite. Even if your system is slower than sirup in January (a Swedish saying) or nobody can log in, you will not be getting any help faster by screaming or being rude. I like to quote my grandfather who had a good saying: "Better to be strong in argument and withheld in words, than the other way round." I have actually gotten written compliments for being nice by the support people, do you think they will go the extra mile for me?
    2. Be very exact with what is you think is wrong. The best way is to formulate it like this: "I did X and expected Y but I got Z". Also be clear on when you define the case as closed. This is particularly important, and hard when you have performance issues or intermittent errors. But try to be as exact as you can. For example: "When users run Chrome open a Contact (after the contact form already has been loaded for another record) it takes 10 seconds. We expect it to take no more than 2 seconds."
    3. Only have one issue per ticket. Better to have many tickets open. I have had 4 tickets open for one single customer at the same point in time.
    4. If you think the issue is important, describe it in business impact terms. For example "The bug X affects all sales people in the organization effectivly stopping them from using Dynamics 365. It severly risks our entire Dynamics 365 investment as users look at other solutions and the user adoption drops dramatically and the trust in the system is drastically lowered for every hour this bug is not fixed. We have 4354 sales people in our global sales organization spread out over 34 countries. It also affects managements abilities to manage the company as no pipleline and forecast numbers are produced which could potentially cause sever business damages that cannot easily be fixed within the coming 4-5 years." - This was just made up :) but it is important to not hold back when doing this, especially if you are Swedish or from other cultures which value humbleness.
    5. Be clear on limits of the error. 
      1. Which Operating system?
      2. Which browsers?
      3. What times? Can you see any clear patterns on when it happens?
      4. Geos?
      5. Security roles?
      6. Types of users affected, AD users federated to O365 or Cloud users?
      7. How long?
      8. Which versions of Dynamics 365 are you running?
      9. Which instances have the issue (the url:s)?
    Types of tickets
    What types of tickets can be registered? Should you only register a ticket when you want help with something?

    Well, no, you can and should register a ticket for many different reasons. As I mentioned at the top of the article it is important to think about Microsoft Support as your Dynamics 365 IT-department. They will help you with a lot of things that your IT-department would have helped you with had they hosted your Dynamics system. The main difference is probably that they do nothing else than host Dynamics 365, every day, year after year... not many IT-departments that can compare with that.

    Typical issues they can help out with are:
    • Something seems to have stopped working that used to work, and you didn't change anything. Like you cannot create an Application User anymore.
    • Something clearly is a bug in Dynamics 365 and you want Microsoft to know about it (they might not know) and you want to let them know how important it is for you (they will surely not know this).
    • You need some information from the Server, like the "Top 10 table Usage"  report from the SQL database.
    • You have performance issues.
    • You need to change the planned upgrades because your team won't make the set time.
    • You want to set some non-clustered indexes on the database.
    • You are doing a migration of large amounts of data and you will be a bad neighbour for a few days and if possible you would like a little more than the 2 allocated threads in the API.
    • You want a database copy prepared for installation into an on-prem equivalent.
    • You need some detailed information on how the service is managed, like
      • How backups are stored
      • How to restore backups from the 90 day tape backup
      • Where an instance is hosted
    • You would like to move an instance to another datacenter
    • You need to remove a managed solution but it has dependencies that shouldn't be there...
    • You need to do some task with an instance that you cannot do yourself with the instance manager.
    In other words, they will be your superfriend when working with Dynamics 365 and you want to be really nice to your super friend!


    Gustaf Westerlund
    MVP, Founder and Principal Consultant at CRM-konsulterna AB
    www.crmkonsulterna.se
  14. Recently I have been trying to fix some Server Side Sync issues with an on-prem Dyn CRM 2016 and this got me to dig into the nitty gritty of settings for the system.

    Before going berserk and chaning a lot of these settings, be aware that you can cause severe problems with your system if you are not careful so I would strongly recommend that you test any settings and also export any settings so that you know what they are.

    Finetuning your onprem installation is something that you can do with an onprem that is a lot harder with online.

    By logging in on your CRM-server, and opening Powershell and entering the following command, you can start working with some settings that are otherwise hard or impossible to reach:

    Add-PSSnapin Microsoft.Crm.PowerShell

    For instance, if you want to check out some of the ServerSideSync Settings, enter:

    Get-CrmSetting -SettingType ServerSideSyncQueueSettings

    If you are using the Windows Power Shell ISE, after loading the Microsoft.Crm.PowerShell, you will get intellisense that will help you see which different settings are available. So if you write:

    Get-CrmSetting -SettingType

    And then enter a space after this, you will see the different options:


    For some more details into Server side sync and how to configure this in detail, look here:
    https://download.microsoft.com/download/7/1/D/71D44C6E-CB78-4573-BDFF-77A6E137BA5C/serversidesyncwithDynamicsCRM.pdf

    And here is an example of how to set data.

    $set = Get-CrmSetting -SettingType ServerSideSyncQueueSettings 

    $set.MailboxQueueItemsInMemoryHigh = "500" 
    $set.MailboxQueueItemsInMemoryLow = "200" 

    Set-CrmSetting -Setting $set

    Just add more $set - statements to set more values.

    If you want to write some settings to a file, just pipe the output to a file, for example:

    Get-CrmSetting -SettingType ServerSideSyncQueueSettings > ServerSideSyncSettingsOrg.txt

    But as I mentioned above, be careful with these settings.

    Gustaf Westerlund
    MVP, Founder and Principal Consultant at CRM-konsulterna AB
    www.crmkonsulterna.se
  15. GDPR and October Update of Dynamics 365, that is what has been the main take away from today for me at CRM UG Summit, (UG is User Group for those who do not know.)

    I have discussed GDPR a lot with a lot of different people here, some more in tune with what it is about than others and some not even realizing that it will affect all companies in the US having EU Citizens in their systems.

    And of course the new release of Dynamice 365, called October Update or version 9.0 for those of us who like to be clear about what we are talking about.

    I will come back to some of the details, for now I will leave you with some recordings I made.





    Gustaf Westerlund
    MVP, Founder and Principal Consultant at CRM-konsulterna AB
    www.crmkonsulterna.se
  16. As many of you probably have noticed version 9.0 has just been released. If you havn't, spin up a trial by clicking here: New Trial

    It has a very nice and shiny UI which I really think you should try and some very other very nice new features. However, you should be a bit wary of using it in production environments just yet as there seems to be a bit too many serious bugs as described in this document:

    https://docs.microsoft.com/en-us/dynamics365/customer-engagement/admin/readme-9

    I am working with a customer and we have a specific non-production instance we call "sandbox" which we use to test apps and features outside of the ALM (application lifecycle management) process, so we installed v9 or July Update as it is called and tried it out.

    What I found when trying to deploy our unmanaged customization with all the entities which we have changed in the project, was that I got the weirdest error, it complained that it was missing an internal Microsoft Web Resource with the name of:
      "CampaignActivity_main_system_library.js"

    So, I opened up the customization.xml (yes, all you oldtimers from CRM 3.0 time remember it as the true export file) and searched for the guid and the web resource name in the file. I found that it was actually used on the main form of Compaign Activitiy, and if you look at the read-me document I have linked above, it mentions that the Campaign Activity is one of the entities which does not work.Hence, there is probably some old code in there that Microsoft have decided to remove, and havn't had time to replace.

    So, the temporary fix to get our solution to work in Dynamics 365 v9.0 (July Release), go into the customization.xml and then manually remove all <Event> tags which include that webresource, and if the <Events> tag was empty, remove that too. Then put the customization.xml file back into the solution file and reimport it.

    The campaign activity still won't work but at least our solution imported. Perhaps there are similar issues with other entities.

    I will expect this issue to go away very soon.

    And on the issue of if it is ok and supported to manually edit (hack) the customization.xml file I am under the impression that it is as long as it actually import into a system without any forceful shoehorning as it is up to Dyn365 to validate it.

    On monday, I will be heading to CRM UG Summit in Nashville which is sure to be a great trip. I am planning to try to make some video there which I will post here and on my Youtube, and don't miss my session on if it is really is a fair fight to compare Online with Onprem? Guess what I will say?



    Gustaf Westerlund
    MVP, Founder and Principal Consultant at CRM-konsulterna AB
    www.crmkonsulterna.se
  17. When authenticating to Dyn 365 with S2S the following is a simple program using the S2S authentication which core I think I got originally got from my pal George Doubinski. I like to use it to test S2S. Very clean and easy to build on.

    string organizationUrl = "<org url>";string clientId = "<client id in Azure>";string appKey = "<secret for the clientid>";string aadInstance = "https://login.microsoftonline.com/";string tenantID = "<contoso or whateveryouhave>.onmicrosoft.com";

    ClientCredential clientcred = new ClientCredential(clientId, appKey);AuthenticationContext authenticationContext = new AuthenticationContext(aadInstance + tenantID);AuthenticationResult authenticationResult = authenticationContext.AcquireToken(organizationUrl, clientcred);var requestedToken = authenticationResult.AccessToken;

    using (OrganizationWebProxyClient sdkService = new OrganizationWebProxyClient(GetServiceUrl(organizationUrl), false)){sdkService.HeaderToken = requestedToken;OrganizationRequest request = new OrganizationRequest();
    WhoAmIResponse response = sdkService.Execute(new WhoAmIRequest()) as WhoAmIResponse;

    Console.WriteLine($"UserID:{response.UserId}");Console.WriteLine("Press any key to continue...");Console.ReadKey();

    }

    However, the line:
    AuthenticationResult authenticationResult = authenticationContext.AcquireToken(organizationUrl, clientcred);

    Cloud computing - isn't it great?
    Requires ADAL version 2.x and the method AquireToken has been removed in the later version of that library.

    If you look around the net, many advocate staying on 2.x version of the library but I didn't have that option as I was integrating with Dyn 365 Operations and that was using the ver 3.x.

    So, to make this work in version 3.x you just have to make a simple fix:

    AuthenticationResult authenticationResult = authenticationContext.AcquireTokenAsync(ClientConfig.CRMOrgUrl, clientcred).Result;



    Gustaf Westerlund
    MVP, Founder and CTO at CRM-konsulterna AB
    www.crmkonsulterna.se
  18. Have been trying to install Voice of the customer for one of my customers. As with larger customers,
    and of course, many of the smaller ones too, I am not allowed to (and I don't really want to) be the global admin in their Office 365. I am however a Dynamics 365 Service Admin, which I think is fair.

    So I was trying to provision Voice of the Customer (VoC) but it failed and after many weird loops and dances with support, of which I will not mention here, I finally got hold of Microsoft support and they were able to tell me that not only did I need to get hold of one of the global admins (you know, one of the scary pale guys who they lock in a safe somewhere cause god knows what would happen if they stepped in front of a car...) but the user also needs to have a full plan 1 Dynamics 365 license.

    Said and done, we allocated it, and restarted the installation - do remember that you have to install VoC from the "Applications" tab, and not only as a Solution.

    So, quick recap:
    To install VoC, you need:
    - Dynamics 365 online instance
    - User with Dynamics 365 Plan 1 license
    - Same user with Global Admin rights



    Gustaf Westerlund
    MVP, Founder and CTO at CRM-konsulterna AB
    www.crmkonsulterna.se
  19. I just ran into one of the weirdest errors I have seen in my Dynamics CRM/365 carreer, and I have seen a few.

    The problem we had was that the case entity had stopped working more or less totally. When trying to open any type of case form either as a normal user or in the form editor, I got a more or less anonymous error message. After a lot of banging my head against the wall and loosing some of my few strands of hair, I finally with the help of Deepesh excellent blog article:
    https://dynamicsofdynamicscrm.com/2015/09/22/error-resolutionthe-case-of-the-form-which-stopped-loading-in-dynamics-crm/
    it got me on the right track. I did some URL-hacking to try to access the form editor directly and accidentaly got to a mixed form editor. Very weird, but it showed that the form itself wasn't broken, hence there was something wrong further down... probably the fields, just as Deepesh's error. And after removing all custom fields, I got it working. Then tediously going back and removing them one by one, I found the culprit, a custom Lookup to the Product.

    To give you some more background:

    When trying to edit any case form, I got the following error:


    When trying to create a new case, I got the following error:

    And if I downloaded the file, the contents was: (I have hightlighted the part which has some, but only slight relevance)

    Unhandled Exception: System.ServiceModel.FaultException`1[[Microsoft.Xrm.Sdk.OrganizationServiceFault, Microsoft.Xrm.Sdk, Version=8.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35]]: System.Web.HttpUnhandledException: Microsoft Dynamics CRM has experienced an error. Reference number for administrators or support: #D856E3CEDetail: 
    <OrganizationServiceFault xmlns:i="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://schemas.microsoft.com/xrm/2011/Contracts">
      <ActivityId>a3831d4c-6557-4f8a-b558-ba8c01b97e21</ActivityId>
      <ErrorCode>-2147220970</ErrorCode>
      <ErrorDetails xmlns:d2p1="http://schemas.datacontract.org/2004/07/System.Collections.Generic" />
      <Message>System.Web.HttpUnhandledException: Microsoft Dynamics CRM has experienced an error. Reference number for administrators or support: #D856E3CE</Message>
      <Timestamp>2017-06-29T13:12:03.5384906Z</Timestamp>
      <ExceptionRetriable>false</ExceptionRetriable>
      <ExceptionSource i:nil="true" />
      <InnerFault>
        <ActivityId>a3831d4c-6557-4f8a-b558-ba8c01b97e21</ActivityId>
        <ErrorCode>-2147220970</ErrorCode>
        <ErrorDetails xmlns:d3p1="http://schemas.datacontract.org/2004/07/System.Collections.Generic" />
        <Message>System.NullReferenceException: Microsoft Dynamics CRM has experienced an error. Reference number for administrators or support: #5CCC57F6</Message>
        <Timestamp>2017-06-29T13:12:03.5384906Z</Timestamp>
        <ExceptionRetriable>false</ExceptionRetriable>
        <ExceptionSource i:nil="true" />
        <InnerFault i:nil="true" />
        <OriginalException i:nil="true" />
        <TraceText i:nil="true" />
      </InnerFault>
      <OriginalException i:nil="true" />
      <TraceText i:nil="true" />
    </OrganizationServiceFault>


    Here are some facts:


    • We had installed a solution that is an upgraded solution, originally from CRM 4 via CRM 2011 and 2013. Not sure if the field definition from the earlier versions are causing this. Probably not.
    • I tried switching off all plugin steps. But it didn't help at all. This is usually what Microsoft support will ask you to do when you have issues why I tried it myself. Always good to try and send this to Microsoft support when registering a support ticket.
    • I have tried spinning up a clean 8.2 Dyn 365 with no customizations, creating a solution with just the case entity and importing that. It did not work. Not very strange, as the problem was a field that is causing the problem. Adding solutions does not remove anything unless you are using managed solutions with patches etc.
    • I tried exporting a small solution with just the case forms and removed all custom fields from the customization file manually and reimported it. It did not work, which is not strange either, as the error was not on the form.
    • I tried creating cases via the API. That did work. I did not use the lookup field that I later found out was the culprit. Perhaps writing something to all fields in the case entity would have generated an error. The reason for doing this was that I wanted to see if I could get an exception in my code that contained more information than what I was getting in the UI. Hence I wasn't at all happy that it did work.
    • I tried retrieving cases via the API. That did work. Again, not happy at all.
    • I tried to manufacture the URL to the form ( https://contoso.crm4.dynamics.com/main.aspx?appSolutionId=%7b<solutionguid>%7d&etc=<entityobjectid, 112 for case>&extraqs=formtype%3dmain%26formId%3d<Guid for the ofrm>%26action%3d-1&pagetype=formeditor) That did not work. No form URL with etc=112 works.
    • I tried to retrieve the form via the API, that works. Again, not happy, but at least it showed that there probably wasn't any problem with the form.
    • I tried to manufacture a weird URL, with the correct form id with the incorrect EntityObjectID. That showed the form, but with the information that the form is for the “other” entity. Weird, but showed that there is actually nothing wrong with the form itself. I could even edit the caseform this way, move fields, remove fields, but not add new stuff. Totally unsupported way of editing a form, but when in love, war and when Dyn365 buggs out, anything is allowed.See below. This proved to be a very useful, as the form seemed for some very strange reason to be involved in this. The way I proved this was that I had an "original", instance where the error showed and one where I had got it to work, after removing some fields, and removing all unnecessary fields from the main form. After this I created a solution which only imported the form from the non-functioning instance for the case entity and imported it into the working instance. I had not expected the result, but it actually stopped working. With the error described above. So for some reason the form was part of the problem.
      A weird Form Editor - the Case form loaded with the Account Entity (EntityTypeCode=1). Be careful when using this, and use at your own risk!
    • I got the same error as above when I try to open the case form in the normal UI.
    • When I try to create a new case, I get the error shown in the file "AnErrorHasOccuredWithTimeStampAndLog.png"
    • As for what happened with the system just before/during/when this error occurred, we were doing customizations on the case form from a spotty internet Connection, and the case for did work before.
    • In the field-section of the Case entity, I selected "Custom" fields, and I have a notion that most of these errors are probably caused by code which mix up custom lookup fields with built in ones. So I would start by looking at lookup fields based on system entities with custom relationships to case like:
      • case 1:N case
      • product 1:N case
      • account 1:N case
      • contact 1:N case
      • pricelevel 1:N case
    • However you might have several fields that are causing errors (I did), and that might make it very tricky to find what is wrong. Cause once you managed to remove the last field causing the error, and then restore the solution and then remove it again, you will find that you are back to a non-functioning entity, and you will have to work your way through each of the fields, with all their dependencies again, until you find the next one. Hence the methodology becomes
      1. Export solution
      2. Remove fields until you get the entity to work. Document exactly which fields you try and in which order. Always work in the same order. Remove a field, try to open the case, remove the next field, try to open case form, and so on. All the time documenting, which fields and in which order.
      3. When you get the case form to work, import the solution again.
      4. Remove the the field(s) that you know are causing the problems.
      5. If, after this, it still does not work, go to 2.
    • After I removed the fields, and cleaned the form, I recreated the fields with the exact same schema-names and that worked perfectly. Not sure though how it will work when I export it, I am still not sure what is causing this. Probably some erroneous code in the case logic.
    • I was able to replicate this error on other instances. So the problem is certainly connected to the solution itself. 

    So to sum it up. This is most obviously a bug in the Dynamics 365 platform as it should never be able to go into this state. In my case entity the problem was two lookups AND the main "Case" form. After removing the fields and removing all non-necessary stuff from the form by using a URL hack described above, I managed to get it working.

    If you run into this, I hope you manage to fix it. It isn't easy and it will take some time. Hopefully I have given you some pointers.




    Gustaf Westerlund
    MVP, Founder and CTO at CRM-konsulterna AB
    www.crmkonsulterna.se
  20. Version 9.0 is soon here and it is set to be the largest release ever from Microsoft. The biggest news on my horizon is the relase of the all new Business Edition of Dynamics 365 (BE). This will be an interesting new product and I'd thought I'd write a few lines about it just to clear some things up based on my understanding of the product.

    Note that these are my thoughts, they are based on what I have heard and what information I believe is in the public domain (non-NDA). If you know that anything is wrong or have something to add, please leave a comment and I will try to fix it as soon as possible. Due to the high level of spamming I have to use moderation on all comments.

    Is it xRM?
    Yes, it is going to be based on the xRM platform but it will be using the all new and shiny "Unified Experience" UI which is probably going to be great in many aspects, looks great and everything but also will probably have a glitch or two as it is just coming out the factory doors.

    Ok, so can I customize it?
    Yes, to some extent you will be able to. It will have specific limits that set it distinctly appart from Enterprise Edition (EE). As of now Microsoft have not been very specific on the details but they have said that the limits will be on:

    • The amount of users in the system
    • Number of custom entities
    • Max amount of GB of usage on disk
    I am an ISV developer. Will my ISV 3:rd party addon work with BE?
    As far as I understood Microsoft, they will limit ISV addons to only be able to work with the OOB entities in BE. As creating entities in the "normal" CRM/EE has almost no cost, almost all ISV solutions I have seen have at least one custom entity, if not to contain customizations. So, my answer would not be a blanket "no" but a probable, "no". If your addon isn't too advanced, you could probably rewrite it to make it work, but with larger addons like for instance ClickDimensions or Resco, I don't see how that would be possible.

    Can I use a sandbox with BE?
    No. No non-production instance will be included in the price and as far as I understood, you won't even be able to buy a non-production or even production instance of BE.

    Can I upgrade from BE to EE?
    Yes. As it is based on the same xRM framework this will totally be doable on a theoretical plane. However, I don't know how this will work on a short term basis if, for instance, you start with a BE in Nov 2017 and in Dec 2017 decide that it was too limiting too you and you want to upgrade to EE. The reason for my hesitation in this is that BE will be based on Unified Experience and EE will not at the time of release of 9.0. I would, however, expect 9.0 to catch up further on the line and after it has been upgraded to Unified Experience, then an upgrade of an instance from BE to EE should be no problem.

    I bought the interim EE offer for BE pricing level, will I be able to downgrade to BE?
    This is a tricky one. First of all Microsoft has not made any public statement on this that I am aware of in either one or the other direction. However, I do think that the key here lies in the level of customizations that you have done to you system. If your EE system falls with the limits of # of users, # of entities and # of GB that is set by MSFT, and also not having any ISV addons not allowed according to BE and any other limitations that Microsoft might come to set before the General Availability (GA) of BE then I think you have a very good chance of being able to downgrade. However, just as I mentioned above in the ISV section, the limitations might be too limiting and creating a lot of entities and adding ISV addons both free and purchased might make it hard to move to BE.

    Can I use the Marketing App of BE in EE?
    This is a really interesting case, as this is an area where the BE will have a featureset that exceeds EE, at least at the time when it is delivered. In the big overview of all Dynamics 365 Apps (for example the one above) - the Marketing Automation slot is filled by Adobe Marketing. However, for the BE there is a Marketing App which has been created from the bottom up by Microsoft on the xRM platform. Do note that for those of you who were unfortunate to have chosen Microsoft Dynamics Marketing, that product has been discontinued, so that is as of the General Availability of Dynamics 365 (dec 2016) you should really start thinking of moving away from it.

    However, the new and shiny Marketing App for BE is strickly speaking only for BE for the time being. I think that the feature set it has is perceived to be too small for the Enterprise segment, although I can perceive many customers using the Enterprise edition that would probably be more than happy with it.

    As for the future for the Marketing App in EE only Microsoft knows what they have planned and if I knew I couldn't have written anything here either. What we know is that they have invested quite a lot of money in building some Marketing Automation features for the BE which is only aimed at the lower end of the customer segment. I would find it noteworthy if they did not leverage that investment in some way in the Enterprise segment as well. However, building a Marketing Automation solution that can match other Enterprise Marketing Automation systems is not something that even Microsoft can do at the flick of the hand, so I would not expect this to show up for at least a year or two. And it might of course be that they will slowly evolve the BE Marketing App until it is fit to grow into the larger Enterprise segment by just turning some switches, but I guess only the future will show.

    As of now, Adobe is the preferred partner for Marketing, something I personally would like to see more detail to. What does it acutally mean? Seems there is some integration engine but no availble whitepapers to dowload that describes what it does. http://www.adobe.com/enterprise/microsoft-partnership/digital-foundation-azure.html 

    If Microsoft are investing in building their own EE Marketing Automation App, which does not seem very far fetched althought it might take some time, you might need to take this into consideration if you are considering investing in a new Marketing Automation system for your organization and you are already running Dynamics 365.

    If you have any other questions on Dynamice 365 Business Edition, please ask them in the comment. Not sure I can answer, but I can try!

    By the way, my blog was awarded the 78:th best CRM blog of all in the world in all CRM categories. Hence the new shiny logo to the right. That was worth some celebration!



    Gustaf Westerlund
    MVP, Founder and CTO at CRM-konsulterna AB
    www.crmkonsulterna.se
  21. When blogging on this blog I try to keep content king why I would rather not blog than blog about
    something that I don't think brings value to you as readers. I have the greatest respect for you as readers of this blog and I hence try to keep the content focused on what typically developers, architects and application experts might be interested in.

    Content is King
    However, there are a lot of other topics that are relevant as well and we have started blogging about those as well at CRM-Konsulterna. You can find it at http://crmpaketet.se/blogg/ where we discuss matters which are of more interest to salespeople. It is in Swedish as this is our primary market and it is also part of our new digitalization strategy which we are implementing with inbound content marketing (the blogging and articles) and technically driven by ClickDimensions as the Marketing Automation tool. This is a great new way of doing business but requires all the techy parts to really work so there is a lot of room for us tech-weenies to get our hands dirty. But the tricky part is getting the business end people on track, they are usually a bit slow (not dumb) when it comes to changes and hence it takes some time for them to accept these new ideas of digitalization.

    Gustaf Westerlund
    MVP, Founder and CTO at CRM-konsulterna AB
    www.crmkonsulterna.se
  22. Typically you are not allowed to remove components from the system layer in Dynamics 365/CRM
    Is this dashboard more pig than horse?
    but for some reason this does not apply to dashboards in some earlier versions of Dynamics CRM. It seems this bug has recently been fixed but if you have a version of CRM where this was possible or have been upgraded from this version, you might be missing it. I just tried this in the Online version
    8.2.0.798 and in this version it is not possible to delete dashboards but I have managed to in earlier versions.

    My friend Jerry Weinstock has blogged about this as well.

    One particular dashboard that the system is in dire need of for its mobile features is the "Sales Dashboard" as this is the default dashboard for the mobile and tablet clients. This cannot be changed although the default dashboard can be changed within the mobile client by the user after it has been started. See MSDN for more info in this.

    In case you do manage to delete it or it has been deleted, Power Objects blog have described how to restore dashboards from instance with this dashboard in it. In short, create an unmanaged solution in that other instance containing the "Sales Dashboard" and then export and import the solution into the instance missing it.

    Before closing the window showing the results, open the log of the import and get the guid of the dashboard and then use the url of another dashboard to insert the GUID into the url to get to the "Sales Dashboard" and change it's name and/or the label of the the tab to what it typically is in case it doesn't show up directly.

    In case you do not have one, here is a link to an unmanaged solution file (version 8.0) containing just the sales dashboard. SalesDashboard_1_0_0_0_target_CRM_8.0.zip


    Gustaf Westerlund
    MVP, Founder and CTO at CRM-konsulterna AB
    www.crmkonsulterna.se
  23. Wrote an article a few days ago on the BPF new architecture and effects that it might have.

    I spoke with Roger Gilchrist, a Principal Program Manager with the Product team during the eXtreme365 conference and he mentioned that using the "Process Stage" fields are actually not supported if you read the SDK very closely. This document is a very long document and it is not very clear in the UI and there is no other very obvious way of solving triggering on stage changes than the triggering on Process Stage changes, with which he did agree.

    The important lesson from that, I think is that not everything you see in the UI is actually supported for use.

    Gustaf Westerlund
    MVP, Founder and CTO at CRM-konsulterna AB
    www.crmkonsulterna.se
  24. Seems like that Dynamics 365/CRM doesn't catch all dependencies for managed solutions. This is how you can find and remove one of the tricky ones I got when uninstalling a managed solution which was:

    Unhandled Exception: System.ServiceModel.FaultException`1[[Microsoft.Xrm.Sdk.OrganizationServiceFault, Microsoft.Xrm.Sdk, Version=8.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35]]: During Solution Uninstall of Solution Id [solution-guid], cannot find any instances of the component with Component Id c97cd9d7-a0fa-4ed5-b360-3c2ad998a620 and Component Type 2.Detail: 
    <OrganizationServiceFault xmlns:i="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://schemas.microsoft.com/xrm/2011/Contracts">
      <ErrorCode>-2147220970</ErrorCode>
      <ErrorDetails xmlns:d2p1="http://schemas.datacontract.org/2004/07/System.Collections.Generic" />
      <Message>During Solution Uninstall of Solution Id [solution-guid], cannot find any instances of the component with Component Id c97cd9d7-a0fa-4ed5-b360-3c2ad998a620 and Component Type 2.</Message>
      <Timestamp>2017-03-06T13:06:54.6280227Z</Timestamp>
      <ExceptionSource i:nil="true" />
      <InnerFault i:nil="true" />
      <OriginalException i:nil="true" />
      <TraceText i:nil="true" />
    </OrganizationServiceFault>

    After some thinking I figured that this was probably a reference to an attribute (Component type = 2) with the Guid = c97cd9d7-a0fa-4ed5-b360-3c2ad998a620 so I opened another attribute and then cut-n-pasted the url. And it seemed that you didn't have to worry about the entity guid:


    https://<onlineorgname>.<globalcrmcenter>.dynamics.com/tools/systemcustomization/attributes/manageAttribute.aspx?appSolutionId=%7bFD140AAF-4DF4-11DD-BD17-0019B9312238%7d&attributeId=%7bc97cd9d7-a0fa-4ed5-b360-3c2ad998a620%7d&entityId=%7b70816501-edb9-4740-a16c-6a5efbc05d84%7d

    Change <onlineorgname> to your org, and <globalcrmcenter> to the crm-subdomain you are using, which for EMEA is crm4.



    You will then see the field editor, and can then show the dependencies of the field and remove all of them manually to make sure they are not bothering the Solution uninstall. After that "publish all" and retry removing the solution.


    Gustaf Westerlund
    MVP, Founder and CTO at CRM-konsulterna AB
    www.crmkonsulterna.se
  25. The new Dynamics 365 release of CRM or as I like to call it 8.2, as that makes it a bit simpler. Dynamics 365 is a bit ambigious, it can mean AX and NAV as well and at the same time I want to discuss the platform and not just an app... so it becomes trick. I hope Microsoft figures some decent naming for the xRM part of the platform so we all have something to call it. (hint... xRM is a decent word)

    Well, one of the cool new features of the 8.2 release is the revamp of the Business Process Flows (BPF) which now have gotten a couple of different facelifts, of which some are:

    • A new editor which looks identical to the Business rules editor. However, the Workflow editor is still very old-style... I wonder if this might be next. :)
    • BPF:s final stage can now be closed/or you actually close the entire BPF. This was not the case previously where the last stage simply sat there.
    • If you have multiple BPF:s and you switch between them, D365 will remember where you are in each of the BPF:s. This was not the case in earlier versions when it always restarted when you changed.

    In order to handle the last point, the underlying architecture of the BPFs have been changed. Previously when you had an entity that was BPF enabled by a lookup called "Process stage" and when this changed you knew that the record had changed stage in the workflow.

    Alas, in comes 8.2 on its white horse, and "Process stage" lookup falls dead to the ground like knight before a modern day tank. In other words, it simply isn't triggered.

    The new BPF architecture is based on the principle that a new shadow entity is created for each BPF that you create. And yes, they are removed when you remove your BPF.

    So, when is this typically a problem? The most common uses for triggering on stage changes in BPF is using a Workflow to trigger on changes in an Opportunity to set the probability. This is then later used in calculated fields like Weighted Estimated Revenue (not a standard field) and similar fields.

    The effect upgrading to 8.2, which is just a minor upgrade from an upgrade perspective, is hence that these customizations that you might have done to set the probability, stop working and the opportunities get the wrong, 0 or no probability making any calculation based on this number incorrect.

    So, how are you supposed to fix this? There is a new WF triggering mechanism built in to the BPF designer. You simply create a workflow that can be manually triggered, and drag a workflow compontent into the appropriate step in the BPF designer.

    Do note that you can choose if you want it to trigger when the stage is started or completed.
    BPF Editor with a workflow added with the Stage Entry trigger selected as highlighted

    And this is how the workflows needs to look
    This is the workflow that was selected in the BPF Editor above. Note the highlighted checkbox. This needs to be checked in order for the workflow to show up in the BPF editor lookup


    A final comment. Even though the BPFs can now be completed, that does not mean that the final stage's Stage Exit is triggered. As far as I have understood it, it is still inthis phase even though the BPF in it self is considered closed. I would call semanticson that. I hope Microsoft fixes that bug or enhances that lack of feature if they rather call it that.

    Was this original workflow supported? Was it ignorant of your partner, you might ask, to create a workflow that triggered as described in the old manner and this has now stopped working and you
    are faced with additional costs for fixing this? Shouln't they have known? Well, frankly no, your partner, if they followed what I described above, did make what are called "supported customizations" which according to the documentation from Microsoft is supposed to be upgradable. At least one major version, often 2 or 3 major versions This time it was not even a minor, from 8.1 to 8.2. Hence it is a regrettable situation but if you want to complain somewhere, I do suggest you complain to Microsoft.

    Gustaf Westerlund
    MVP, Founder and Principal Consultant at CRM-konsulterna AB
    www.crmkonsulterna.se
KRIEGO KG
Ahorngasse 5
2435 Ebergassing  (Nähe Wien)
Österreich
 
Tel: +43 (680) 1333114
E-Mail: Diese E-Mail-Adresse ist vor Spambots geschützt! Zur Anzeige muss JavaScript eingeschaltet sein.