Simple connection example with the new Microsoft.Xrm.Tooling.Connector

So there is a new DLL that allows us to connect to CRM from 8.2 version forward (Dynamics 365).
To use this in the code you can use the EarlyBounds that you can generate using the SDK and then add it to your project. Afterwards you just need to insert the code and and references missing to your project:

using Microsoft.Xrm.Sdk;
using Microsoft.Xrm.Sdk.Query;
using Microsoft.Xrm.Tooling.Connector;

namespace ConsoleApplication1
public static class Program
private static IOrganizationService _serviceProxy;

static void Main(string[] args)
string connectionString = GetServiceConfiguration();

CrmServiceClient conn = new CrmServiceClient(connectionString);
_serviceProxy = (IOrganizationService)conn.OrganizationWebProxyClient != null ? (IOrganizationService)conn.OrganizationWebProxyClient : (IOrganizationService)conn.OrganizationServiceProxy;

string fetchXml = @”<fetch version=’1.0′ output-format=’xml-platform’ mapping=’logical’ distinct=’false’>
<entity name=’systemuser’>
<all-attributes />
<order attribute=’systemuserid’ descending=’false’ />

EntityCollection result = _serviceProxy.RetrieveMultiple(new FetchExpression(fetchXml));

catch (Exception ex)


private static String GetServiceConfiguration()
// Get available connection strings from app.config.
int count = ConfigurationManager.ConnectionStrings.Count;

// Create a filter list of connection strings so that we have a list of valid
// connection strings for Microsoft Dynamics CRM only.
List<KeyValuePair<String, String>> filteredConnectionStrings =
new List<KeyValuePair<String, String>>();

for (int a = 0; a < count; a++)
if (isValidConnectionString(ConfigurationManager.ConnectionStrings[a].ConnectionString))
(new KeyValuePair<string, string>

// No valid connections strings found. Write out and error message.
if (filteredConnectionStrings.Count == 0)
Console.WriteLine(“An app.config file containing at least one valid Microsoft Dynamics CRM ” +
“connection string configuration must exist in the run-time folder.”);
Console.WriteLine(“\nThere are several commented out example connection strings in ” +
“the provided app.config file. Uncomment one of them and modify the string according ” +
“to your Microsoft Dynamics CRM installation. Then re-run the sample.”);
return null;

// If one valid connection string is found, use that.
if (filteredConnectionStrings.Count == 1)
return filteredConnectionStrings[0].Value;

// If more than one valid connection string is found, let the user decide which to use.
if (filteredConnectionStrings.Count > 1)
Console.WriteLine(“The following connections are available:”);

for (int i = 0; i < filteredConnectionStrings.Count; i++)
Console.Write(“\n({0}) {1}\t”,
i + 1, filteredConnectionStrings[i].Key);


Console.Write(“\nType the number of the connection to use (1-{0}) [{0}] : “,
String input = Console.ReadLine();
int configNumber;
if (input == String.Empty) input = filteredConnectionStrings.Count.ToString();
if (!Int32.TryParse(input, out configNumber) || configNumber > count ||
configNumber == 0)
Console.WriteLine(“Option not valid.”);
return null;

return filteredConnectionStrings[configNumber – 1].Value;

return null;


private static Boolean isValidConnectionString(String connectionString)
// At a minimum, a connection string must contain one of these arguments.
if (connectionString.Contains(“Url=”) ||
connectionString.Contains(“Server=”) ||
return true;

return false;


<!– Online using Office 365 –>
<add name=”Server=CRM Online, organization=contoso, user=someone”
connectionString=”Url=https://<ORG>; Username=<USERNAME>@<ORG>; Password=<PASSWORD>; authtype=Office365″/>

<!– On-premises with provided user credentials –>
<!– <add name=”Server=myserver, organization=AdventureWorksCycle, user=administrator”
connectionString=”Url=http://myserver/AdventureWorksCycle; Domain=mydomain; Username=administrator; Password=password; authtype=AD”/> –>

<!– On-premises using Windows integrated security –>
<!– <add name=”Server=myserver, organization=AdventureWorksCycle”
connectionString=”Url=http://myserver/AdventureWorksCycle; authtype=AD”/> –>

<!– On-Premises (IFD) with claims –>
<!–<add name=”, organization=contoso,”
connectionString=”Url=;; Password=password; authtype=IFD”/>–>
<supportedRuntime version=”v4.0″ sku=”.NETFramework,Version=v4.5.2″ />


Use Workflow to fill a field with the stage name

As you might know, in the Opportunity entity there was a field that saves the text of each stage, but if you want that for other entities that field might not be available.
There was a way that worked until the version 8.2, where you build a workflow to run in the entity that you have the BPF and then save the Process Stage Name to the field that you created.
In the new version that isn’t working very well, from my tests it is only saving the previous stage name (the stage that was before the active).
Now to have the actual stage I had to do like this:

-With the next BPF from 8.2, this isn’t working well since it is only putting in the field the previous stage.
-To achieve the what you want, you need to create a workflow that is running in the BPF entity of the process, for example, Phone to Case Process.
-Create a custom field to save the text.
-You put the workflow in sync, then select to run when “Process is applied” and “Process changes” then you select the field “Active Stage Id”
-Then you insert the step Update Record, change it to “Incident Id (Case)” in the workflow and in the properties you add to the field that you want to save the text of the process. On the right options Look for: Active Stage Id (Process Stage) and then the field Process Stage.

It should look like this:

CRM Audit info dissapeared

Some of the New Value data might disappear (have the broken icon instead of the value) when you import a solution that disables the Audit of the entity or if the Audit is already disabled and then you enable Audit.
It is a known issue and if you are working on online you will need to create a Service Request to the Support.
If you are OnPrem you will need to run the following SQL script to check and then clean the records:

Select * from AuditBase WHERE action = 104 OR action = 102
Action = 104 | Any Auditing Changes that are made at Organization level would get captured with code 104.

Action = 102 | Any Auditing Changes that are made at Entity level would get captured with code 102.

In order to retrieve the Audit value from the DB, we would need to run the following command:

DELETE from AuditBase WHERE action = 104 AND CreatedOn > ‘<date>’ || Action = 104 or 102, depending on the results we get the above SELECT query

After this, the values will show again.

Invalid User Authorization

When you get an error like this, when you try to open a Workflow that is in Draft mode, check first if you are using Custom Workflow Activities in that workflow and if the Custom Workflow is update with the most recent dll’s for the version of your Dynamics CRM instance.

I had a issue like that and updating the dll’s solved the problem.

Moving between BPF stages programmatically

This is a simple code example that you can use to do move stages of a Business Process Flow (it can be improved, for example, to not have the stages id in the code). Also, I was using early bound class for this example. The field TraversedPath needs to be updated accordingly the stage that you are moving, so if you are going forward you need to add the stages, if you are going backward you need to remove the stages.

I have 3 Opportunities in the system:

  • Opp1 -> Stage1
  • Opp2 -> Stage2
  • Opp3 -> Stage3

And want to change the stages to:

  • Opp1 -> Stage3
  • Opp2 -> Stage1
  • Opp3 -> Stage2
   string connectionString = GetServiceConfiguration();

   CrmServiceClient conn = new CrmServiceClient(connectionString);
   _serviceProxy = (IOrganizationService)conn.OrganizationWebProxyClient != null ? (IOrganizationService)conn.OrganizationWebProxyClient : (IOrganizationService)conn.OrganizationServiceProxy;

   string fetchXml = @"";

   EntityCollection result = _serviceProxy.RetrieveMultiple(new FetchExpression(fetchXml));
   string processid = "3E8EBEE6-A2BC-4451-9C5F-B146B085413A";
   string stage1 = "6b9ce798-221a-4260-90b2-2a95ed51a5bc";
   string stage2 = "650e06b4-789b-46c1-822b-0da76bedb1ed";
   string stage3 = "d3ca8878-8d7b-47b9-852d-fcd838790cfd";
   foreach (Opportunity opp in result.Entities)
      string id = opp.Id.ToString();

      Entity op = new Entity("opportunity");
      op.Id = opp.Id;

      if (opp.StageId.Value.ToString().ToUpper() == stage1.ToUpper())
         op["processid"] = new Guid(processid);
         op["stageid"] = new Guid(stage3);
         op["traversedpath"] = new Guid(stage1.ToLower()) + "," + new Guid(stage2.ToLower()) + "," + new Guid(stage3.ToLower()).ToString();
      if (opp.StageId.Value.ToString().ToUpper() == stage2.ToUpper())
         op["processid"] = new Guid(processid);
         op["stageid"] = new Guid(stage1);
         op["traversedpath"] = new Guid(stage1.ToLower()).ToString();
      if (opp.StageId.Value.ToString().ToUpper() == stage3.ToUpper())
         op["processid"] = new Guid(processid);
         op["stageid"] = new Guid(stage2);
         op["traversedpath"] = new Guid(stage1.ToLower()) + "," + new Guid(stage2.ToLower()).ToString();

catch (Exception ex)


Changed sitemap and can’t access to the instance

There are a couple of issues when you drag or change the sitemap in the SiteMap editor in Dynamics 365.
If you get this problem and can’t access the instance anymore, try to use the XrmToolbox, there is a plugin called SiteMap Editor that try to load your sitemap from there.
If it loads, you just need to correct the faulty subarea or group and then Update the sitemap again to the instance.
If when you try to load you get a parse error message where it should show the sitemap, then it is corrupted and you can reset the sitemap to the default (going to More Actions in the tool submenu), or if you have a backup of you sitemap, just create an new file.xml, click on open sitemap, select the file and then upload sitemap.
This should solve your issue.
You can also find the structure of the Sitemap in the SDK.