A Dynamics 365 Solution Architect’s View on Why Customers Chose Salesforce over Dynamics 365?

I have worked on several deals involving Salesforce and Dynamics 365 and based on my unscientific observation about 50% of the deals always get taken away by Salesforce. I have always wanted to know what was the reason for this? So I decided that I would go into the world of Salesforce so that I could see how Salesforce seemingly beats the crap out of Dynamics 365 about 50% of the time and here is what I found out.

1. Dynamics 365 is the wrong comparison for Salesforce. Dynamics 365 is Microsoft’s first-party implementation of xRM. By pitting it against Salesforce which has evolved from being just an xRM into a Platform it is like making the customer choose between a brand new engine (Dynamics 365) and a second-hand car (Salesforce). The first may be built with modern technologies in mind but a new engine cannot take you anywhere. A second-hand car, on the other hand, can take you where you need to go. Most of the customers who choose Salesforce over Dynamics 365 believe they are choosing a complete car over a brand new engine.

2. Don’t sell Dynamics 365, Common Data Services, Power BI, and Azure Services as separate components. Sell everything as Power Platform. Salesforce is always sold as a Platform and not by individual products. In my experience, Salesforce Solution Architects never say that Einstein is a separate product. Microsoft Dynamics Solution Architects on the other hand always sell Power BI and Azure AI Platform as separate products.

3. Don’t get bogged down by Microsoft’s overlapping and sometimes competing products. Salesforce Solution Architects never tell the customer that Salesforce Sales, Marketing, Service, Mulesoft, and Artificial Intelligence components are actually separated in the backend or that their Financial Services Cloud is a complication built on top of the Account entity. They always tell the customer that everything is Salesforce. Microsoft Dynamics Solution Architects on the other hand like to emphasize Common Data Services as the glue that binds different Microsoft and partner (e.g. Adobe & SAP) products together. This creates confusion with the customer who thinks it is more difficult to integrate Microsoft and partner products because they are different products and not one single solution.

4. Architect and Design from inside out. Salesforce Solution Architects usually “pressure” the customer to follow their so-called “Industry Standards” in order to reduce any custom effort down to configuration changes only. Microsoft Dynamics Solution Architects on the other hand, usually accede to customer demands which results in a lot of custom components. Many of these Architects still believe that “handyman” customization is a strength of Dynamics 365 products. Even if it is true that Microsoft Dynamics 365 is flexible enough the navigate any type of customization, the customer will always see customizations as additional costs. Also, one of the reasons why Salesforce Solution Architects “pressure” the customer to follow their so-called “Industry Standards” is to make it difficult for the customer to switch back to Dynamics 365. Microsoft Dynamics Solution Architects however will readily make their solution as easy to switch to Salesforce as possible.

5. Focus on the value proposition of Integration using Azure. One of the big weaknesses of Salesforce is Integration. Mulesoft is an overpriced mammoth. Power Platform (everything from Dynamics 365, Power Apps, Logic Apps, Power Automate & Azure Services) on the other hand has a robust set of integration tools such as Logic Apps, Power Automate, Azure Data Factory, Dynamics 365 Export Services that can be mixed and matched with supporting Azure Services such as Azure Service Bus, Azure Storage, Azure Event Hub, Azure App Services, Azure Batch, Azure Monitor, etc. From this list alone Salesforce is supposed to be a dead horse. The big mistake however of most Microsoft Dynamics Solution Architects is that they separate these components when proposing to the Customer which inadvertently promotes a perception of complexity vs Salesforce’s single marketing name — Mulesoft.

6. Focus on Microsoft’s Hybrid Cloud advantage. Salesforce was never built with the Hybrid Cloud or environment in mind. That is why they created Heroku Cloud and bought Mulesoft to fill in the gap. Compared however to the broad scope covered by Azure which involves Enterprise grade IaaS, PaaS, and other XaaS components, Mulesoft is just an overpriced mule, and using it with Heroku to bridge the Hybrid Cloud gap will drive up the price of Salesforce implementations. From a security perspective, Salesforce, Mulesoft, and Heroku don’t have secure environments like Azure Service Environment or Integrated Service Environment which can be used to form the Hybrid Cloud. Salesforce and Mulesoft also don’t have secure and fast private connections like Azure ExpressRoute. They are always dependent on third-parties to provide these services for them. For Salesforce, everything is public. In other words, Hybrid implementations using Salesforce are a round peg in a square hole and Mulesoft is the glue that covers these gaps. One example is the fact that the “best practice” for doing integration calls to get data outside of Salesforce, makes use of a separate session with a fixed integration user. This is in stark contrast to how Power Platform can leverage Common Data Services or Service Endpoint / Service Bus and even use Data Export Service seamlessly from within both the Azure Public and Hybrid Cloud and which can be further secured through the use of Single Sign-On and Managed Identities.6. Don’t price components independently. No one likes to buy a car where there’s a price tag on every part like the wheels, chair, steering wheel, engine, body, etc. Even if the total price would come out cheaper, most people would prefer to buy a car with a single price. Microsoft tends to price Power Platform components and Azure components separately. I believe it is the job of the Solution Architect to consolidate everything into a single priced solution when talking to the customer. This single priced model will reduce confusion and will present a better overall picture of the real cost of a solution.

7. Lastly, go one step further by selling Power Platform and Azure Cloud as a pair or as a single solution. Avoid complications of selling individual products like Dynamics 365, Power Apps, Logic Apps, Power Automate, Dynamics 365 Export Services, Power BI, Common Data Services, Azure Data Factory, Azure Functions, Azure Service Bus, Azure Storage, Azure Event Hubs, Azure IoT Hub, Azure App Services, Azure Batch, Azure Monitor, etc. because this will not only confuse the customer but will provide a perception that your solution is incomplete because it needs different products. The reality is, Microsoft has provided seamless integration and doesn’t view these as separate products but rather as cohesive services and platforms under the Azure family.

Create a Common Data Service starter portal

With the capability to build a portal in Power Apps, you can create a website for external and internal users enabling them to interact with data stored in Common Data Service.

These are some benefits of creating a portal:

  • Because the data is stored in Common Data Service, you don’t need to create a connection from Power Apps as you do with data sources such as SharePoint, model-driven apps in Dynamics 365, or Salesforce. You need only to specify the entities that you want to show or manage in the portal.
  • You can design the portal through the WYSIWYG Power Apps portals Studio by adding and configuring components on the webpages.

To create a portal:

  1. Sign in to Power Apps.
  2. Under Make your own app, select Portal from blank.
  3. If the selected environment does not contain portal pre-requisites, a message is displayed in the Portal from blank window suggesting you select another environment or create a new one.create new environment message
  4. If you choose to proceed with the current environment, enter the required information in the window as mentioned in the following steps. If you choose to create a new environment, see Create new environment.
  5. In the Portal from blank window, enter a name for the portal and address for the website, and select a language from the drop-down list. When you’re done, select Create. TipTo create a portal using a different language, you must first enable the language in the environment so that it becomes available in the language drop-down list.create new portal

After you select Create, the portal will begin provisioning and the provisioning status is displayed through notifications.

If you have created your portal in the environment that doesn’t have portal pre-requisites installed, the provisioning status is also displayed in the grid:

Grid notification

After the portal is provisioned successfully, the status is updated and the portal is displayed in the grid:

Portal provisioned

To edit the portal in Power Apps portals Studio, see Edit a portal.


  • There can be only one portal of each type and for a language created in an environment.
  • If you don’t have sufficient privileges to provision a portal, an error is displayed. You must have the System Administrator role in Common Data Service to create a portal. You must also have the Access Mode set to Read-Write under Client Access License (CAL) Information in the user record.
  • If you have purchased an older portal add-on, and want to provision a portal using the add-on, you must go to the Dynamics 365 Administration Center page. More information: Provision a portal using the older portal add-on
  • If you have provisioned a portal using the older portal add-on, you can still customize and manage it from make.powerapps.com.
  • Provisioning portals from make.powerapps.com does not consume the older portal add-ons. Also, these portals are not listed under the Applications tab on the Dynamics 365 Administration Center page.
  • A Common Data Service starter portal cannot be created from the Dynamics 365 Administration Center page.
  • Power Apps portals is not available in the France region.

The same article can be found in Microsoft’s documentation https://docs.microsoft.com/en-us/powerapps/maker/portals/create-portal

Server-side logic in Common Data Service for Apps

Common Data Service for Apps has been launched and this is what XRM developers have been waiting for since xRM 2011.  With these new capabilities, PowerApps (v2) and the Common Data Service for Apps now power Dynamics 365 for Sales, Marketing, Customer Service and Talent. PowerApps P2 officially becomes the new platform SKUand will be called Canvas Apps, moving away from being a admin and maker focused plan to becoming THE plan for users of stand-alone model driven apps.

If you’re already a Dynamics 365 user, this means as soon as your Dynamics 365 apps are upgraded to 9.0, your data will be available in Common Data Service for Apps. Existing Dynamics 365 environments will show up in PowerApps, assuming you have the right access permissions. Dynamics 365 customizers will start using PowerApps to customize Dynamics 365 (no worries: Solution Explorer and other familiar editors remain available), and if you already know how to customize Dynamics 365 then you already know how to build model-driven apps!

By using the concept of XRM of 2011, this makes Common Data Service for Apps instantly Enterprise Ready — server-side logic and here are several types that are supported:

Declarative logic, that does not require writing any code. In this category Common Data Service for Apps provides:

  1. Business Process Flows – BPFs are a way to describe business processes as a sequence of stages with specific steps in each stage. Use a business process flow when you want users to move through the same stages and follow the same steps to interact with a customer for example. BPF allows modelling of sophisticated processes through capabilities like enforcing certain conditions are met before advancing to the next stage, or dynamically switching stages depending on input from prior stages.
  2. Workflows – CDS for Apps support synchronous (“real-time”) and asynchronous workflows. Custom workflows can be triggered on a wide range of events such as creation of a new record, BPFchanges to a record, deletion, etc. The workflow itself can then take one or multiple actions like modifying fields, creating new records or even preventing the operation that triggered the workflow from completing.
  3. Business rules – Ensuring accurate data, regardless of the app that created or edit it is important to maintain data consistency, and ensure apps and analytics continue to operate as expected. Business Rules provide a nice graphical UI for defining these rules and actions that will be executed sychronously when a record is created/updated.
  4. Calculated and roll up fields – entities can now include calculations and roll ups of related records to allow you to create Excel like formulas on both number and text-based fields. This enables calculations to be defined once, ensuring a consistent value is used across all your apps.

In addition to the graphical, declarative editors, CDS for Apps now also supports pro-dev extensibility:

  1. Code plugins – Plugins define custom business logic through .NET that can be triggered by a wide range of events in the platform. They provide the ultimate in fine-grain extensibility for pro-devs.
  2. Custom Workflow activities – Similar to plugins, these can be written in C# and allow definition of custom activities that can be triggered as part of a workflow to execute custom business logic not easily expressed declaratively.

What do these changes mean for your existing canvas apps (Power Apps v1) and any new canvas apps (Power Apps v1) that you can build on the Common Data Service for Apps?

New canvas apps (Power Apps v1) will continue to be able to use the Common Data Business Rule Designer.pngService for Apps as a data source and will also gain some new and much requested capabilities. The most exciting being the ability to use the above mentioned server-side logic in your canvas apps. Business Process Flows are not yet supported in Canvas apps (Power Apps v1), but all the other types of entity scoped server side logic can be used with Canvas apps (Power Apps v1).

For existing canvas apps (Power Apps v1) currently using the Common Data Service there will be some manual upgrade work required to enable the new functionality for those instances, you will begin receiving notifications starting in April with details. No worries, your existing CDS instances will continue to work, new CDS for Apps instances will already have all the new capabilities enabled.BPF

How to Get the List of Users Inside an Access Team

Many of you have probably tried to use the Access Teams feature of Dynamics 365 Customer Engagement (D365CE) to provide special access for specific records but one of the rather odd requirements that was asked of our project recently was to query the list of Access Team users on an Account Record and Pre-Filter the Owner field to limit the Lookup only to the specific users in the Access Team list.  Pre-Filtering is nothing new in D365CE so I went ahead and added a Pre-Filter that would probably look like something like this:

var filter = Some Fetch XML Filter
Ownercontrol.addPreSearch(function () {

I went ahead and opened Advanced Find and to my surprise I didn’t find any Entity named Access Team or some name that was connected to Access Team. I opened the Users Entity to search and to my dismay I didn’t find a single field that pointed to Access Team or Account where the Access Team was enabled. So I went and searched the fields in Account and saw a field named preferredsystemuserid. I thought, this is it! But when I tried to query a value using XrmToolBox’s FetchXML Builder by Jonas Rapp of Innofactor Sweden, I was disappointed to find out that the field wasn’t even displayed on the results view.

So I tried so search until I noticed a reference to some entity called the principalobjectaccess and found that this entity is quite useful in help us out of our problem.

The results of this Fetch XML statement will return a list of System User Guids which I can now use to populate my Pre-Filter query.  I passed this Fetch XML query through D365CI’s Web API and got the results. If you want to know how to pass Fetch XML using the Web API you can read about it HERE or you can use Jason Lattimer’s CRM Rest Builder to do the heavy lifting for you. After you have retrieved the results you can pass the results to the data parameter and create the Pre-Filter as follows:

filter = "";
filter += "";
var index = 0;
for (index = 0; index < data.value.length; index++) {
    filter += "" + data.value[index].user_x002e_systemuserid + "";
filter += "";
Ownercontrol.addPreSearch(function () {


How to Do Complicated Queries in Dynamics 365 Customer Engagement REST Web API using Fetch XML

There are two ways to do this the first one is to use the fetchXml keyword as shown below or use Jason Lattimer’s CRM Query Builder.

var fetchXML = "<fetch>";
fetchXML += " <entity name="account">";
fetchXML += " <filter>";
fetchXML += " <condition attribute="accountid" operator="eq" value="f7b4ef42-250c-4a53-a8c5-6adfce984c93" />";
fetchXML += " </filter>";
fetchXML += " <link-entity name="principalobjectaccess" from="objectid" to="accountid" link-type="inner" alias="poa">";
fetchXML += " <attribute name="objectid" alias="objectid" />";
fetchXML += " <link-entity name="team" from="teamid" to="principalid" link-type="inner" >";
fetchXML += " <link-entity name="teammembership" from="teamid" to="teamid" link-type="inner" intersect="true" >";
fetchXML += " <link-entity name="systemuser" from="systemuserid" to="systemuserid" link-type="inner" alias="user" >";
fetchXML += " <attribute name="systemuserid" />";
fetchXML += " </link-entity>";
fetchXML += " </link-entity>";
fetchXML += " </link-entity>";
fetchXML += " </link-entity>";
fetchXML += " </entity>";
fetchXML += "</fetch>";
 var encodedFetch = encodeURI(fetchXML); //encode fetchXML
 var req = new XMLHttpRequest();
 req.open("GET", Xrm.Page.context.getClientUrl() + "/api/data.8.2/accounts?fetchXml=" + encodedFetch, true);
 req.setRequestHeader("Accept", "application/json");
 req.setRequestHeader("Content-Type", "application/json; charset=utf-8");
 req.setRequestHeader("OData-MaxVersion", "4.0");
 req.setRequestHeader("OData-Version", "4.0");
 req.setRequestHeader("Prefer", "odata.include-annotations=\"*\"");
 req.onreadystatechange = function () {
 if (this.readyState == 4 /* complete */) {
     req.onreadystatechange = null;
     if (this.status == 200) {
       var data = JSON.parse(this.response)
     else {

Customer Engagement Hubs

If you have tried out the NEW Dynamics 365 Customer Engagement v9, you will notice that they have added “Hubs” to the existing Apps. Currently, we have the Sales Hub, Customer Service Hub, Project Resource Hub, and Field Resource Hub.


If you actually click on one of the Hubs it will bring up the Dynamics 365 App which is similar to its none-Hub counterpart except for one subtle change — you can now see a side menu which looks and behaves like the Windows 10 Creators Update side menu.


I think Microsoft did a good job of bringing in some of the positive UI Elements of Windows 10 into Dynamics 365 Customer Engagement v9. Having similar UI Elements will make users adopt quickly when they shift from using Windows 10 to Office 365 to Dynamics 365.

What do you think?