MIM 2016/FIM 2010 R2 ECMA2 Dynamics CRM 2016 Webservice Connector

Overview Dynamics CRM 2016 for Developers

There are two APIs available, the REST and the SOAP. The REST API is targeted towards the Web UI developers so it does not have user administration functions, it has functions that will enable you do things within a user account like creating entities, linking documents and much more. It is suited for custom UI development. The REST API is a recent addition, hopefully it will be expanded to include user administration operations. The SOAP API has been around for a while and it is good for user administration like create new accounts, enable/disable an account, add a role to an account and also some of the internal account operations that the REST API does.

For this blog post I will show how to retrieve users from Dynamics CRM using SOAP API. There are many other things that you can do with the ECMA2 Dynamics CRM connector. Take a look at the CRM SDK samples.

ECMA2 Requirements for CRM connection

  1. The Target framework for your VStudio must be Dotnet 4.5.2
  2. Download the Dynamics CRM SDK here. Make sure you chose the Dynamics 365 SDK. The exe package will produce some files which you will reference.
  3. The following references should be added to your project.

  1. The following file should also be added to your project MyOrganizationCrmSdkTypes.cs
  2. After you compile the following files (highlighted in blue) will be added to your extensions folder

Creating the ECMA2 Dll file

  1. In the Synchronization Manager, at the top, select Management Agents.
  2. At the top, select Actions, select Create Extension Projects, and choose Extensible Connectivity 2.0 Extension. This will open a Create Extension Project dialog box.
  3. In the Create Extension Project dialog box, next to Programming Language: select Visual C#
  4. In the Create Extension Project dialog box, next to Visual Studio Version: select Visual Studio 2010.
  5. In the Create Extension Project dialog box, next to Project Name: enter CRM_ECMA2.
  6. Click OK. This will launch Visual Studio 2010.
  7. On the right, at the top, under the Solutions Explorer, double-click CRM_ECMA2. This will open the file with code that has already been written.
  8. Copy and paste this code (overwrite what is there)

using System;

using System.Data;

using System.IO;

using System.Xml;

using System.Text;

using System.Collections.Specialized;

using Microsoft.MetadirectoryServices;

using System.Collections.ObjectModel;

using System.Collections.Generic;

using System.Net;

using Microsoft.Xrm.Sdk;

using Microsoft.Xrm.Sdk.Client;

using System.ServiceModel;

using System.ServiceModel.Description;

using Microsoft.Xrm.Sdk.Query;

namespace FimSync_Ezma

{


public
class EzmaExtension :


//IMAExtensible2CallExport,

IMAExtensible2CallImport,


//IMAExtensible2FileImport,


//IMAExtensible2FileExport,


//IMAExtensible2GetHierarchy,

IMAExtensible2GetSchema,

IMAExtensible2GetCapabilities,

IMAExtensible2GetParameters


//IMAExtensible2GetPartitions

{
private
int m_importDefaultPageSize =
1200;


private
int m_importMaxPageSize =
1500;

public
string Password;

public
string Username;

public
string Domain;

public
string CRMOrgPath;

public
string myFirst;

public
string myLast;

public
string myFull;

public
string myAccount;

static IOrganizationService _service;

//
// Constructor
//
public EzmaExtension()


{


//


// TODO: Add constructor logic here


//


}


public MACapabilities Capabilities


{

get


{

MACapabilities myCapabilities =
new MACapabilities();

myCapabilities.ConcurrentOperation =
true;

myCapabilities.ObjectRename =
false;

myCapabilities.DeleteAddAsReplace =
true;

myCapabilities.DeltaImport =
true;

myCapabilities.DistinguishedNameStyle = MADistinguishedNameStyle.None;

myCapabilities.ExportType = MAExportType.AttributeUpdate;

myCapabilities.NoReferenceValuesInFirstExport =
false;

myCapabilities.Normalizations = MANormalizations.None;


return myCapabilities;


}


}


public
int ImportDefaultPageSize


{

get


{


return m_importDefaultPageSize;


}


}


public
int ImportMaxPageSize


{

get


{


return m_importMaxPageSize;


}


}


public CloseImportConnectionResults CloseImportConnection(CloseImportConnectionRunStep importRunStep)


{


return
new CloseImportConnectionResults();


}


public IList<ConfigParameterDefinition> GetConfigParameters(KeyedCollection<string, ConfigParameter> configParameters, ConfigParameterPage page)


{

List<ConfigParameterDefinition> configParametersDefinitions =
new List<ConfigParameterDefinition>();


switch
(page)


{


case ConfigParameterPage.Connectivity:

configParametersDefinitions.Add(ConfigParameterDefinition.CreateStringParameter(“CRMOrgPath”,
“”));

configParametersDefinitions.Add(ConfigParameterDefinition.CreateStringParameter(“Username”,
“”));

configParametersDefinitions.Add(ConfigParameterDefinition.CreateStringParameter(“Password”,
“”));

configParametersDefinitions.Add(ConfigParameterDefinition.CreateStringParameter(“Domain”,
“”));


break;


//case ConfigParameterPage.Global:


// break;


//case ConfigParameterPage.Partition:


// break;


//case ConfigParameterPage.RunStep:


// break;


}


return configParametersDefinitions;


}


public GetImportEntriesResults GetImportEntries(GetImportEntriesRunStep importRunStep)


{

List<CSEntryChange> csentries =
new List<CSEntryChange>();

GetImportEntriesResults importReturnInfo;


// Connect to the CRM server

ConnectToMSCRM(this.Username,
this.Password,
this.Domain,
this.CRMOrgPath);


// Retrieve all the system users.

QueryExpression Allusersquery =
new QueryExpression


{

EntityName = SystemUser.EntityLogicalName,

ColumnSet =
new ColumnSet(“firstname”,
“lastname”,
“fullname”,
“domainname”)


};

EntityCollection ec = _service.RetrieveMultiple(Allusersquery);

Console.WriteLine(“Retrieved {0} entities”, ec.Entities.Count);


foreach
(Entity act in ec.Entities)


{

myFirst = act[“firstname”].ToString();

myLast = act[“lastname”].ToString();

myFull = act[“fullname”].ToString();

myAccount = act[“domainname”].ToString();

CSEntryChange csentry1 = CSEntryChange.Create();

csentry1.ObjectModificationType = ObjectModificationType.Add;

csentry1.ObjectType =
“Person”;

csentry1.AttributeChanges.Add(AttributeChange.CreateAttributeAdd(“Firstname”, myFirst));

csentry1.AttributeChanges.Add(AttributeChange.CreateAttributeAdd(“Lastname”, myLast));

csentry1.AttributeChanges.Add(AttributeChange.CreateAttributeAdd(“Fullname”, myFull));

csentry1.AttributeChanges.Add(AttributeChange.CreateAttributeAdd(“AccountName”, myAccount));

csentries.Add(csentry1);


}

importReturnInfo =
new GetImportEntriesResults();

importReturnInfo.MoreToImport =
false;

importReturnInfo.CSEntries = csentries;


return importReturnInfo;


}


public Schema GetSchema(KeyedCollection<string, ConfigParameter> configParameters)


{

Microsoft.MetadirectoryServices.SchemaType personType = Microsoft.MetadirectoryServices.SchemaType.Create(“Person”,
false);


//myname = configParameters[“myname”].Value;


string myattribute =
“Firstname”;


string myattribute2 =
“Lastname”;


string myattribute3 =
“AccountName”;


string myattribute5 =
“Fullname”;


if
(myattribute ==
“Firstname”)


{

personType.Attributes.Add(SchemaAttribute.CreateAnchorAttribute(myattribute, AttributeType.String));


}


if
(myattribute2 ==
“Lastname”)


{

personType.Attributes.Add(SchemaAttribute.CreateAnchorAttribute(myattribute2, AttributeType.String));


}


if
(myattribute3 ==
“AccountName”)


{

personType.Attributes.Add(SchemaAttribute.CreateAnchorAttribute(myattribute3, AttributeType.String));


}


if
(myattribute5 ==
“Fullname”)


{

personType.Attributes.Add(SchemaAttribute.CreateAnchorAttribute(myattribute5, AttributeType.String));


}

Schema schema = Schema.Create();

schema.Types.Add(personType);


return schema;


}


public OpenImportConnectionResults OpenImportConnection(KeyedCollection<string, ConfigParameter> configParameters, Schema types, OpenImportConnectionRunStep importRunStep)


{


this.CRMOrgPath = configParameters[“CRMOrgPath”].Value;


this.Username = configParameters[“Username”].Value;


this.Password = configParameters[“Password”].Value;


this.Domain = configParameters[“Domain”].Value;


return
new OpenImportConnectionResults();


}


public ParameterValidationResult ValidateConfigParameters(KeyedCollection<string, ConfigParameter> configParameters, ConfigParameterPage page)


{

ParameterValidationResult myResults =
new ParameterValidationResult();


return myResults;


}


public
static
void ConnectToMSCRM(string UserName,
string Password,
string Domain,
string SoapOrgServiceUri)


{


try


{

ClientCredentials credentials =
new ClientCredentials();

credentials.Windows.ClientCredential =
new System.Net.NetworkCredential(UserName, Password, Domain);

credentials.UserName.UserName = UserName;

credentials.UserName.Password = Password;

Uri serviceUri =
new Uri(SoapOrgServiceUri);

OrganizationServiceProxy proxy =
new OrganizationServiceProxy(serviceUri,
null, credentials,
null);

proxy.EnableProxyTypes();

_service =
(IOrganizationService)proxy;


}


catch
(Exception ex)


{

Console.WriteLine(“Error while connecting to CRM “
+ ex.Message);

Console.ReadKey();


}


}


};

}

Create the ECMA2 Dynamics CRM Connector

  1. In the Synchronization Manager, click Management Agents
  2. In the Synchronization Service, at the top, select Management Agents and over on the right, under Actions, select Create. This will open a Create Management Agent wizard.
  3. On the Create Management Agent screen, next to Management Agent for: select Extensible Connectivity 2
  4. On the Create Management Agent screen, next to Name: enter CRM_ECMA2

  1. Remove the check from Run this management agent in a separate process. This will allow for debugging should the need arise.
  2. Click Next.
  3. On the Select Extension DLL screen, click Browse and select CRM_ECMA2.dll. Click OK.
  4. On the Select Extension DLL screen, click Refresh interfaces. This will populate the box below. It should support Import

  1. Click Next.
  2. On the Connectivity screen, next to path enter: the Dynamics CRM Webservice url you have already received from the Dynamics Admin. It could be found in settings\customizations\Developer resources, the SOAP address is under Organization Service.
  3. On the Connectivity screen, next to username enter: the id that you tested with
  4. On the Connectivity screen, next to password enter: password
  5. Enter the domain

  1. Click Next.
  2. On the Select Object Types screen, select Person.

  1. Click Next.
  2. On the Select Attributes screen, select all four.

  1. Click Next.
  2. On the Configure Anchors screen, click Specify Anchor. This will open a Set Anchor dialog box.
  3. On the Set Anchor dialog box, you may see several attributes there, click specify anchor and remove all attributes except Accountname and click Add>. Click OK.

  1. Click Next.
  2. On the Configure Connector Filter screen, click Next.

  1. Click Next.
  2. On the Configure Connector Join and Projection, click Next.

Click Next

Click Next

Click finish

  1. Configure Full Import run profile
  2. Run the Import, it should be successful and you can test sync via the preview screen to see that the person is provisioned to the MV.

Advertisements

One thought on “MIM 2016/FIM 2010 R2 ECMA2 Dynamics CRM 2016 Webservice Connector

  1. Pingback: C# Find out status of a Dynamics CRM SystemUser Entity object and set to disabled | tlktechidentitythoughts

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s