Helper 程式碼:SystemUserProvider 類別
發行︰ 2017年1月
適用於: Dynamics 365 (online)、Dynamics 365 (on-premises)、Dynamics CRM 2016、Dynamics CRM Online
下載 Microsoft Dynamics CRM SDK 套件。 您可以在下列的下載套件位置找到此範本:
SDK\SampleCode\CS\HelperCode\SystemUserProvider.cs
SDK\SampleCode\VB\HelperCode\SystemUserProvider.vb
需求
登入的系統使用者必須具備此範本程式碼的系統管理員權限來建立新的使用者帳戶。如需執行此 SDK 所提供範例程式碼的需求資訊,請參閱使用範例和 Helper 程式碼。
示範
SystemUserProvider 類別示範如何以程式的方式在 Active Directory 和 Microsoft Dynamics 365 中建立其他使用者。
多個 SDK 範本需要其他 (虛擬) 在 Microsoft Dynamics 365 (線上和內部部署) 的系統使用者,而非登入的使用者,針對此範本執行應執行的工作。 這些範例使用 SystemUserProvider 類別方法建立這些其他必要的使用者。 既然目前不可能使用程式的方式建立新的 Microsoft 帳號 使用者,在 Microsoft Dynamics 365 (線上) 伺服器上執行時,程式碼會列出必要的使用者資訊至主控台。 必要時可以手動增加和邀請使用者。
範例
using System;
using System.Collections.Generic;
using System.DirectoryServices;
using System.Threading;
// These namespaces are found in the Microsoft.Xrm.Sdk.dll assembly
// located in the SDK\bin folder of the SDK download.
using Microsoft.Xrm.Sdk;
using Microsoft.Xrm.Sdk.Query;
using Microsoft.Xrm.Sdk.Client;
using Microsoft.Xrm.Sdk.Messages;
// This namespace is found in the Microsoft.Crm.Sdk.Proxy.dll assembly
// located in the SDK\bin folder of the SDK download.
using Microsoft.Crm.Sdk.Messages;
namespace Microsoft.Crm.Sdk.Samples
{
/// <summary>
/// This class contains methods which retrieve the IDs of several fictitious Microsoft Dynamics
/// CRM system users. Several SDK samples require these additional user accounts in order to run.
/// </summary>
/// <remarks>For On-premises and IFD deployments, if these users do not exist they are created in
/// Active Directory. This assumes that the system user account under which the application runs has
/// system administrator privileges. Since it is not possible to programmatically create user accounts
/// in Microsoft account, when running this code against a Microsoft Dynamics CRM Online server, you will have
/// to manually add these users.</remarks>
public class SystemUserProvider
{
public static Guid RetrieveSalesManager(OrganizationServiceProxy proxy)
{
String ldapPath = String.Empty;
return RetrieveSystemUser("kcook", "Kevin", "Cook", "Sales Manager", proxy, ref ldapPath);
}
public static Guid RetrieveSalesManager(OrganizationServiceProxy proxy, ref String ldapPath)
{
return RetrieveSystemUser("kcook", "Kevin", "Cook", "Sales Manager", proxy, ref ldapPath);
}
public static List<Guid> RetrieveSalespersons(OrganizationServiceProxy proxy, ref String ldapPath)
{
List<Guid> reps = new List<Guid>();
reps.Add(RetrieveSystemUser("nanderson", "Nancy", "Anderson", "Salesperson", proxy, ref ldapPath));
reps.Add(RetrieveSystemUser("dbristol", "David", "Bristol", "Salesperson", proxy, ref ldapPath));
return reps;
}
public static List<Guid> RetrieveDelegates(OrganizationServiceProxy proxy,
ref String ldapPath)
{
List<Guid> delegates = new List<Guid>();
delegates.Add(RetrieveSystemUser("dwilson", "Dan", "Wilson", "Delegate", proxy, ref ldapPath));
delegates.Add(RetrieveSystemUser("canderson", "Christen", "Anderson", "Delegate", proxy, ref ldapPath));
return delegates;
}
public static Guid RetrieveVPSales(OrganizationServiceProxy proxy, ref String ldapPath)
{
return RetrieveSystemUser("mtucker", "Michael", "Tucker", "Vice President of Sales", proxy, ref ldapPath);
}
public static Guid RetrieveMarketingManager(OrganizationServiceProxy proxy)
{
String ldapPath = String.Empty;
return RetrieveMarketingManager(proxy, ref ldapPath);
}
public static Guid RetrieveMarketingManager(OrganizationServiceProxy proxy, ref String ldapPath)
{
return RetrieveSystemUser("ssmith", "Samantha", "Smith", "Marketing Manager", proxy, ref ldapPath);
}
public static Guid RetrieveAUserWithoutAnyRoleAssigned(OrganizationServiceProxy proxy)
{
String ldapPath = String.Empty;
return RetrieveSystemUser("dpark", "Dan", "Park", "", proxy, ref ldapPath);
}
/// <summary>
/// Retrieves the requested SystemUser record. If the record does not exist, a new
/// Microsoft Dynamics CRM SystemUser record is created and an associated Active
/// Directory account is created, if it doesn't currently exist.
/// </summary>
/// <param name="userName">The username field as set in Microsoft Dynamics CRM</param>
/// <param name="firstName">The first name of the system user to be retrieved</param>
/// <param name="lastName">The last name of the system user to be retrieved</param>
/// <param name="roleStr">The string representing the Microsoft Dynamics CRM security
/// role for the user</param>
/// <param name="serviceProxy">The OrganizationServiceProxy object to your Microsoft
/// Dynamics CRM environment</param>
/// <param name="ldapPath">The LDAP path for your network - you can either call
/// ConsolePromptForLDAPPath() to prompt the user or provide a value in code</param>
/// <returns></returns>
public static Guid RetrieveSystemUser(String userName, String firstName,
String lastName, String roleStr, OrganizationServiceProxy serviceProxy,
ref String ldapPath)
{
String domain;
Guid userId = Guid.Empty;
if (serviceProxy == null)
throw new ArgumentNullException("serviceProxy");
if (String.IsNullOrWhiteSpace(userName))
throw new ArgumentNullException("UserName");
if (String.IsNullOrWhiteSpace(firstName))
throw new ArgumentNullException("FirstName");
if (String.IsNullOrWhiteSpace(lastName))
throw new ArgumentNullException("LastName");
// Obtain the current user's information.
WhoAmIRequest who = new WhoAmIRequest();
WhoAmIResponse whoResp = (WhoAmIResponse)serviceProxy.Execute(who);
Guid currentUserId = whoResp.UserId;
SystemUser currentUser =
serviceProxy.Retrieve(SystemUser.EntityLogicalName, currentUserId, new ColumnSet("domainname")).ToEntity<SystemUser>();
// Extract the domain and create the LDAP object.
String[] userPath = currentUser.DomainName.Split(new char[] { '\\' });
if (userPath.Length > 1)
domain = userPath[0] + "\\";
else
domain = String.Empty;
SystemUser existingUser = GetUserIdIfExist(serviceProxy, domain, userName, firstName, lastName);
if (existingUser != null)
{
userId = existingUser.SystemUserId.Value;
if (!String.IsNullOrWhiteSpace(roleStr))
{
// Check to make sure the user is assigned the correct role.
Role role = RetrieveRoleByName(serviceProxy, roleStr);
// Associate the user with the role when needed.
if (!UserInRole(serviceProxy, userId, role.Id))
{
AssociateRequest associate = new AssociateRequest()
{
Target = new EntityReference(SystemUser.EntityLogicalName, userId),
RelatedEntities = new EntityReferenceCollection()
{
new EntityReference(Role.EntityLogicalName, role.Id)
},
Relationship = new Relationship("systemuserroles_association")
};
serviceProxy.Execute(associate);
}
}
}
else
{
// Create the system user in Microsoft Dynamics CRM if the user doesn't
// already exist.
userId = CreateSystemUser(userName, firstName, lastName, domain,
roleStr, serviceProxy, ref ldapPath);
}
return userId;
}
/// <summary>
/// Helper method to check if system user already exist with either given username or first and last name.
/// </summary>
/// <param name="serviceProxy">The OrganizationServiceProxy object to your Microsoft
/// Dynamics CRM environment</param>
/// <param name="domainName">Current domain name of the account.</param>
/// <param name="userName">The username field as set in Microsoft Dynamics CRM</param>
/// <param name="firstName">The first name of the system user to be retrieved</param>
/// <param name="lastName">The last name of the system user to be retrieved</param>
/// <returns></returns>
public static SystemUser GetUserIdIfExist(OrganizationServiceProxy serviceProxy,
String domainName, String userName, String firstName, String lastName)
{
QueryExpression userQuery = new QueryExpression
{
EntityName = SystemUser.EntityLogicalName,
ColumnSet = new ColumnSet("systemuserid"),
Criteria =
{
FilterOperator = LogicalOperator.Or,
Filters =
{
new FilterExpression
{
FilterOperator = LogicalOperator.And,
Conditions =
{
new ConditionExpression("domainname", ConditionOperator.Equal, domainName + userName)
}
},
new FilterExpression
{
FilterOperator = LogicalOperator.And,
Conditions =
{
new ConditionExpression("firstname", ConditionOperator.Equal, firstName),
new ConditionExpression("lastname", ConditionOperator.Equal, lastName)
}
}
}
}
};
DataCollection<Entity> existingUsers = (DataCollection<Entity>)serviceProxy.RetrieveMultiple(userQuery).Entities;
if (existingUsers.Count > 0)
return existingUsers[0].ToEntity<SystemUser>();
return null;
}
private static Guid CreateSystemUser(String userName, String firstName,
String lastName, String domain, String roleStr,
OrganizationServiceProxy serviceProxy, ref String ldapPath)
{
CreateADAccount(userName, firstName, lastName, serviceProxy, ref ldapPath);
// Retrieve the default business unit needed to create the user.
QueryExpression businessUnitQuery = new QueryExpression
{
EntityName = BusinessUnit.EntityLogicalName,
ColumnSet = new ColumnSet("businessunitid"),
Criteria =
{
Conditions =
{
new ConditionExpression("parentbusinessunitid",
ConditionOperator.Null)
}
}
};
BusinessUnit defaultBusinessUnit = serviceProxy.RetrieveMultiple(
businessUnitQuery).Entities[0].ToEntity<BusinessUnit>();
//Create a new system user.
SystemUser user = new SystemUser
{
DomainName = domain + userName,
FirstName = firstName,
LastName = lastName,
BusinessUnitId = new EntityReference
{
LogicalName = BusinessUnit.EntityLogicalName,
Name = BusinessUnit.EntityLogicalName,
Id = defaultBusinessUnit.Id
}
};
Guid userId = serviceProxy.Create(user);
if (!String.IsNullOrWhiteSpace(roleStr))
{
// Retrieve the specified security role.
Role role = RetrieveRoleByName(serviceProxy, roleStr);
// Assign the security role to the newly created Microsoft Dynamics CRM user.
AssociateRequest associate = new AssociateRequest()
{
Target = new EntityReference(SystemUser.EntityLogicalName, userId),
RelatedEntities = new EntityReferenceCollection()
{
new EntityReference(Role.EntityLogicalName, role.Id),
},
Relationship = new Relationship("systemuserroles_association")
};
serviceProxy.Execute(associate);
}
return userId;
}
/// <summary>
/// Helper method to create an active directory account
/// </summary>
/// <param name="userName">The username field as set in Microsoft Dynamics CRM</param>
/// <param name="firstName">The first name of the system user to be retrieved</param>
/// <param name="lastName">The last name of the system user to be retrieved</param>
/// <param name="serviceProxy">The OrganizationServiceProxy object to your Microsoft
/// Dynamics CRM environment</param>
/// <param name="ldapPath">The LDAP path for your network - you can either call
/// ConsolePromptForLDAPPath() to prompt the user or provide a value in code</param>
/// <returns>Return true if new account is created or return false if account already exist.</returns>
public static Boolean CreateADAccount(String userName,
String firstName,
String lastName,
OrganizationServiceProxy serviceProxy,
ref String ldapPath)
{
// Check to make sure this is not Microsoft Dynamics CRM Online.
if (serviceProxy.ServiceConfiguration.AuthenticationType == AuthenticationProviderType.LiveId ||
serviceProxy.ServiceConfiguration.AuthenticationType == AuthenticationProviderType.OnlineFederation)
throw new Exception(String.Format("To run this sample, {0} {1} must be an active system user " +
"\nin your Microsoft Dynamics CRM Online organization.", firstName, lastName));
if (String.IsNullOrEmpty(ldapPath))
ldapPath = SystemUserProvider.ConsolePromptForLDAPPath();
// Create an Active Directory user account if it doesn't exist already.
if (String.IsNullOrEmpty(ldapPath))
throw new ArgumentException("Required argument ldapPath was not provided.");
DirectoryEntry directoryEntry;
if (serviceProxy.ClientCredentials.Windows != null)
{
string LUser = serviceProxy.ClientCredentials.Windows.ClientCredential.UserName;
string LPwd = serviceProxy.ClientCredentials.Windows.ClientCredential.Password;
directoryEntry = new DirectoryEntry(ldapPath, LUser, LPwd);
}
else
{
directoryEntry = new DirectoryEntry(ldapPath);
}
DirectoryEntry userADAccount = null;
// Search AD to see if the user already exists.
DirectorySearcher search = new DirectorySearcher(directoryEntry);
search.Filter = String.Format("(sAMAccountName={0})", userName);
search.PropertiesToLoad.Add("samaccountname");
search.PropertiesToLoad.Add("givenname");
search.PropertiesToLoad.Add("sn");
search.PropertiesToLoad.Add("cn");
SearchResult result = search.FindOne();
Boolean accountCreated = false;
if (result == null)
{
// Create the Active Directory account.
userADAccount = directoryEntry.Children.Add("CN= " + userName, "user");
userADAccount.Properties["samAccountName"].Value = userName;
userADAccount.Properties["givenName"].Value = firstName;
userADAccount.Properties["sn"].Value = lastName;
userADAccount.CommitChanges();
accountCreated = true;
}
else
{
// Use the existing AD account.
userADAccount = result.GetDirectoryEntry();
accountCreated = false;
}
// Set the password for the account.
String password = "pass@word1";
userADAccount.Invoke("SetPassword", new object[] { password });
userADAccount.CommitChanges();
directoryEntry.Close();
userADAccount.Close();
// Enable the newly created Active Directory account.
userADAccount.Properties["userAccountControl"].Value =
(int)userADAccount.Properties["userAccountControl"].Value & ~0x2;
userADAccount.CommitChanges();
// Wait 10 seconds for the AD account to propagate.
Thread.Sleep(10000);
return accountCreated;
}
/// <summary>
/// Helper method to prompt the user for the LDAP path for the network
/// </summary>
/// <returns>The LDAP path for your network</returns>
public static String ConsolePromptForLDAPPath()
{
// Prompt for the LDAP path.
Console.WriteLine("An Active Directory connection is required. Please enter an");
Console.WriteLine("LDAP path for your network in the format 'LDAP://server/DC=subdomain,DC=domain,DC=com': ");
String ldapPath = Console.ReadLine();
return ldapPath;
}
private static bool UserInRole(OrganizationServiceProxy serviceProxy,
Guid userId, Guid roleId)
{
// Establish a SystemUser link for a query.
LinkEntity systemUserLink = new LinkEntity()
{
LinkFromEntityName = SystemUserRoles.EntityLogicalName,
LinkFromAttributeName = "systemuserid",
LinkToEntityName = SystemUser.EntityLogicalName,
LinkToAttributeName = "systemuserid",
LinkCriteria =
{
Conditions =
{
new ConditionExpression(
"systemuserid", ConditionOperator.Equal, userId)
}
}
};
// Build the query.
QueryExpression query = new QueryExpression()
{
EntityName = Role.EntityLogicalName,
ColumnSet = new ColumnSet("roleid"),
LinkEntities =
{
new LinkEntity()
{
LinkFromEntityName = Role.EntityLogicalName,
LinkFromAttributeName = "roleid",
LinkToEntityName = SystemUserRoles.EntityLogicalName,
LinkToAttributeName = "roleid",
LinkEntities = {systemUserLink}
}
},
Criteria =
{
Conditions =
{
new ConditionExpression("roleid", ConditionOperator.Equal, roleId)
}
}
};
// Retrieve matching roles.
EntityCollection ec = serviceProxy.RetrieveMultiple(query);
if (ec.Entities.Count > 0)
return true;
return false;
}
private static Role RetrieveRoleByName(OrganizationServiceProxy serviceProxy,
String roleStr)
{
QueryExpression roleQuery = new QueryExpression
{
EntityName = Role.EntityLogicalName,
ColumnSet = new ColumnSet("roleid"),
Criteria =
{
Conditions =
{
new ConditionExpression("name", ConditionOperator.Equal, roleStr)
}
}
};
return serviceProxy.RetrieveMultiple(roleQuery).Entities[0].ToEntity<Role>();
}
}
}
Imports Microsoft.VisualBasic
Imports System
Imports System.Collections.Generic
Imports System.DirectoryServices
Imports System.Threading
' These namespaces are found in the Microsoft.Xrm.Sdk.dll assembly
' located in the SDK\bin folder of the SDK download.
Imports Microsoft.Xrm.Sdk
Imports Microsoft.Xrm.Sdk.Query
Imports Microsoft.Xrm.Sdk.Client
Imports Microsoft.Xrm.Sdk.Messages
' This namespace is found in the Microsoft.Crm.Sdk.Proxy.dll assembly
' located in the SDK\bin folder of the SDK download.
Imports Microsoft.Crm.Sdk.Messages
Namespace Microsoft.Crm.Sdk.Samples
''' <summary>
''' This class contains methods which retrieve the IDs of several fictitious Microsoft Dynamics
''' CRM system users. Several SDK samples require these additional user accounts in order to run.
''' </summary>
''' <remarks>For On-premises and IFD deployments, if these users do not exist they are created in
''' Active Directory. This assumes that the system user account under which the application runs has
''' system administrator privileges. Since it is not possible to programmatically create user accounts
''' in Microsoft account, when running this code against a Microsoft Dynamics CRM Online server, you will have
''' to manually add these users.</remarks>
Public Class SystemUserProvider
Public Shared Function RetrieveSalesManager(ByVal proxy As OrganizationServiceProxy) As Guid
Dim ldapPath As String = String.Empty
Return RetrieveSystemUser("kcook", "Kevin", "Cook", "Sales Manager", proxy, ldapPath)
End Function
Public Shared Function RetrieveSalesManager(ByVal proxy As OrganizationServiceProxy, ByRef ldapPath As String) As Guid
Return RetrieveSystemUser("kcook", "Kevin", "Cook", "Sales Manager", proxy, ldapPath)
End Function
Public Shared Function RetrieveSalespersons(ByVal proxy As OrganizationServiceProxy, ByRef ldapPath As String) As List(Of Guid)
Dim reps As New List(Of Guid)()
reps.Add(RetrieveSystemUser("nanderson", "Nancy", "Anderson", "Salesperson", proxy, ldapPath))
reps.Add(RetrieveSystemUser("dbristol", "David", "Bristol", "Salesperson", proxy, ldapPath))
Return reps
End Function
Public Shared Function RetrieveDelegates(ByVal proxy As OrganizationServiceProxy, ByRef ldapPath As String) As List(Of Guid)
Dim delegates As New List(Of Guid)()
delegates.Add(RetrieveSystemUser("dwilson", "Dan", "Wilson", "Delegate", proxy, ldapPath))
delegates.Add(RetrieveSystemUser("canderson", "Christen", "Anderson", "Delegate", proxy, ldapPath))
Return delegates
End Function
Public Shared Function RetrieveVPSales(ByVal proxy As OrganizationServiceProxy, ByRef ldapPath As String) As Guid
Return RetrieveSystemUser("mtucker", "Michael", "Tucker", "Vice President of Sales", proxy, ldapPath)
End Function
Public Shared Function RetrieveMarketingManager(ByVal proxy As OrganizationServiceProxy) As Guid
Dim ldapPath As String = String.Empty
Return RetrieveMarketingManager(proxy, ldapPath)
End Function
Public Shared Function RetrieveMarketingManager(ByVal proxy As OrganizationServiceProxy, ByRef ldapPath As String) As Guid
Return RetrieveSystemUser("ssmith", "Samantha", "Smith", "Marketing Manager", proxy, ldapPath)
End Function
Public Shared Function RetrieveAUserWithoutAnyRoleAssigned(ByVal proxy As OrganizationServiceProxy) As Guid
Dim ldapPath As String = String.Empty
Return RetrieveSystemUser("dpark", "Dan", "Park", "", proxy, ldapPath)
End Function
''' <summary>
''' Retrieves the requested SystemUser record. If the record does not exist, a new
''' Microsoft Dynamics CRM SystemUser record is created and an associated Active
''' Directory account is created, if it doesn't currently exist.
''' </summary>
''' <param name="userName">The username field as set in Microsoft Dynamics CRM</param>
''' <param name="firstName">The first name of the system user to be retrieved</param>
''' <param name="lastName">The last name of the system user to be retrieved</param>
''' <param name="roleStr">The string representing the Microsoft Dynamics CRM security
''' role for the user</param>
''' <param name="serviceProxy">The OrganizationServiceProxy object to your Microsoft
''' Dynamics CRM environment</param>
''' <param name="ldapPath">The LDAP path for your network - you can either call
''' ConsolePromptForLDAPPath() to prompt the user or provide a value in code</param>
''' <returns></returns>
Public Shared Function RetrieveSystemUser(ByVal userName As String, ByVal firstName As String, ByVal lastName As String, _
ByVal roleStr As String, ByVal serviceProxy As OrganizationServiceProxy, _
ByRef ldapPath As String) As Guid
Dim domain As String
Dim userId As Guid = Guid.Empty
If serviceProxy Is Nothing Then
Throw New ArgumentNullException("serviceProxy")
End If
If String.IsNullOrWhiteSpace(userName) Then
Throw New ArgumentNullException("UserName")
End If
If String.IsNullOrWhiteSpace(firstName) Then
Throw New ArgumentNullException("FirstName")
End If
If String.IsNullOrWhiteSpace(lastName) Then
Throw New ArgumentNullException("LastName")
End If
' Obtain the current user's information.
Dim who As New WhoAmIRequest()
Dim whoResp As WhoAmIResponse = CType(serviceProxy.Execute(who), WhoAmIResponse)
Dim currentUserId As Guid = whoResp.UserId
Dim currentUser As SystemUser = serviceProxy.Retrieve(SystemUser.EntityLogicalName, currentUserId, _
New ColumnSet("domainname")).ToEntity(Of SystemUser)()
' Extract the domain and create the LDAP object.
Dim userPath() As String = currentUser.DomainName.Split(New Char() {"\"c})
If userPath.Length > 1 Then
domain = userPath(0) & "\"
Else
domain = String.Empty
End If
Dim existingUser As SystemUser = GetUserIdIfExist(serviceProxy, domain, userName, firstName, lastName)
If existingUser IsNot Nothing Then
userId = existingUser.SystemUserId.Value
If Not String.IsNullOrWhiteSpace(roleStr) Then
' Check to make sure the user is assigned the correct role.
Dim role_Renamed As Role = RetrieveRoleByName(serviceProxy, roleStr)
' Associate the user with the role when needed.
If Not UserInRole(serviceProxy, userId, role_Renamed.Id) Then
Dim associate As New AssociateRequest() With { _
.Target = New EntityReference(SystemUser.EntityLogicalName, userId), _
.RelatedEntities = New EntityReferenceCollection() From {New EntityReference(Role.EntityLogicalName, role_Renamed.Id)}, _
.Relationship = New Relationship("systemuserroles_association")}
serviceProxy.Execute(associate)
End If
End If
Else
' Create the system user in Microsoft Dynamics CRM if the user doesn't
' already exist.
userId = CreateSystemUser(userName, firstName, lastName, domain, roleStr, serviceProxy, ldapPath)
End If
Return userId
End Function
''' <summary>
''' Helper method to check if system user already exist with either given username or first and last name.
''' </summary>
''' <param name="serviceProxy">The OrganizationServiceProxy object to your Microsoft
''' Dynamics CRM environment</param>
''' <param name="domainName">Current domain name of the account.</param>
''' <param name="userName">The username field as set in Microsoft Dynamics CRM</param>
''' <param name="firstName">The first name of the system user to be retrieved</param>
''' <param name="lastName">The last name of the system user to be retrieved</param>
''' <returns></returns>
Public Shared Function GetUserIdIfExist(ByVal serviceProxy As OrganizationServiceProxy,
ByVal domainName As String,
ByVal userName As String,
ByVal firstName As String,
ByVal lastName As String) As SystemUser
Dim userQuery As QueryExpression = New QueryExpression With
{
.EntityName = SystemUser.EntityLogicalName,
.ColumnSet = New ColumnSet("systemuserid")
}
userQuery.Criteria.Filters.Add(New FilterExpression(LogicalOperator.And))
userQuery.Criteria.Filters(0).AddCondition(New ConditionExpression("domainname", ConditionOperator.Equal, domainName & userName))
userQuery.Criteria.Filters.Add(New FilterExpression(LogicalOperator.And))
userQuery.Criteria.Filters(1).AddCondition(New ConditionExpression("firstname", ConditionOperator.Equal, firstName))
userQuery.Criteria.Filters(1).AddCondition(New ConditionExpression("lastname", ConditionOperator.Equal, lastName))
userQuery.Criteria.FilterOperator = LogicalOperator.Or
Dim existingUsers As DataCollection(Of Entity) = CType(serviceProxy.RetrieveMultiple(userQuery).Entities, DataCollection(Of Entity))
If existingUsers.Count > 0 Then
Return existingUsers(0).ToEntity(Of SystemUser)()
End If
Return Nothing
End Function
Private Shared Function CreateSystemUser(ByVal userName As String, ByVal firstName As String, ByVal lastName As String, _
ByVal domain As String, ByVal roleStr As String, ByVal serviceProxy As OrganizationServiceProxy, _
ByRef ldapPath As String) As Guid
CreateADAccount(userName, firstName, lastName, serviceProxy, ldapPath)
' Retrieve the default business unit needed to create the user.
Dim businessUnitQuery As QueryExpression = New QueryExpression With { _
.EntityName = BusinessUnit.EntityLogicalName,
.ColumnSet = New ColumnSet("businessunitid")
}
businessUnitQuery.Criteria.AddCondition(
New ConditionExpression("parentbusinessunitid",
ConditionOperator.Null))
Dim defaultBusinessUnit As BusinessUnit =
serviceProxy.RetrieveMultiple(businessUnitQuery).Entities(0).ToEntity(Of BusinessUnit)()
'Create a new system user.
Dim user As SystemUser = New SystemUser With
{
.DomainName = domain & userName,
.FirstName = firstName,
.LastName = lastName,
.BusinessUnitId = New EntityReference With
{
.LogicalName = BusinessUnit.EntityLogicalName,
.Name = BusinessUnit.EntityLogicalName,
.Id = defaultBusinessUnit.Id
}
}
Dim userId As Guid = serviceProxy.Create(user)
If Not String.IsNullOrWhiteSpace(roleStr) Then
' Retrieve the specified security role.
Dim role_Renamed As Role = RetrieveRoleByName(serviceProxy, roleStr)
' Assign the security role to the newly created Microsoft Dynamics CRM user.
Dim associate As New AssociateRequest() With
{
.Target = New EntityReference(SystemUser.EntityLogicalName, userId),
.RelatedEntities = New EntityReferenceCollection() From
{
New EntityReference(Role.EntityLogicalName, role_Renamed.Id)
},
.Relationship = New Relationship("systemuserroles_association")
}
serviceProxy.Execute(associate)
End If
Return userId
End Function
''' <summary>
''' Helper method to create an active directory account
''' </summary>
''' <param name="userName">The username field as set in Microsoft Dynamics CRM</param>
''' <param name="firstName">The first name of the system user to be retrieved</param>
''' <param name="lastName">The last name of the system user to be retrieved</param>
''' <param name="serviceProxy">The OrganizationServiceProxy object to your Microsoft
''' Dynamics CRM environment</param>
''' <param name="ldapPath">The LDAP path for your network - you can either call
''' ConsolePromptForLDAPPath() to prompt the user or provide a value in code</param>
''' <returns>Return true if new account is created or return false if account already exist.</returns>
Public Shared Function CreateADAccount(ByVal userName As String, ByVal firstName As String, ByVal lastName As String, ByVal serviceProxy As OrganizationServiceProxy, ByRef ldapPath As String) As Boolean
' Check to make sure this is not Microsoft Dynamics CRM Online.
If serviceProxy.ServiceConfiguration.AuthenticationType = AuthenticationProviderType.LiveId OrElse
serviceProxy.ServiceConfiguration.AuthenticationType = AuthenticationProviderType.OnlineFederation Then
Throw New Exception(String.Format("To run this sample, {0} {1} must be an active system user " & vbLf _
& "in your Microsoft Dynamics CRM Online organization.",
firstName, lastName))
End If
If String.IsNullOrEmpty(ldapPath) Then
ldapPath = SystemUserProvider.ConsolePromptForLDAPPath()
End If
' Create an Active Directory user account if it doesn't exist already.
If String.IsNullOrEmpty(ldapPath) Then
Throw New ArgumentException("Required argument ldapPath was not provided.")
End If
Dim directoryEntry_Renamed As DirectoryEntry
If serviceProxy.ClientCredentials.Windows IsNot Nothing Then
Dim LUser As String = serviceProxy.ClientCredentials.Windows.ClientCredential.UserName
Dim LPwd As String = serviceProxy.ClientCredentials.Windows.ClientCredential.Password
directoryEntry_Renamed = New DirectoryEntry(ldapPath, LUser, LPwd)
Else
directoryEntry_Renamed = New DirectoryEntry(ldapPath)
End If
Dim userADAccount As DirectoryEntry = Nothing
' Search AD to see if the user already exists.
Dim search As New DirectorySearcher(directoryEntry_Renamed)
search.Filter = String.Format("(sAMAccountName={0})", userName)
search.PropertiesToLoad.Add("samaccountname")
search.PropertiesToLoad.Add("givenname")
search.PropertiesToLoad.Add("sn")
search.PropertiesToLoad.Add("cn")
Dim result As SearchResult = search.FindOne()
Dim accountCreated As Boolean = False
If result Is Nothing Then
' Create the Active Directory account.
userADAccount = directoryEntry_Renamed.Children.Add("CN= " & userName, "user")
userADAccount.Properties("samAccountName").Value = userName
userADAccount.Properties("givenName").Value = firstName
userADAccount.Properties("sn").Value = lastName
userADAccount.CommitChanges()
accountCreated = True
Else
' Use the existing AD account.
userADAccount = result.GetDirectoryEntry()
accountCreated = False
End If
' Set the password for the account.
Dim password As String = "pass@word1"
userADAccount.Invoke("SetPassword", New Object() { password })
userADAccount.CommitChanges()
directoryEntry_Renamed.Close()
userADAccount.Close()
' Enable the newly created Active Directory account.
userADAccount.Properties("userAccountControl").Value =
CInt(Fix(userADAccount.Properties("userAccountControl").Value)) And Not &H2
userADAccount.CommitChanges()
' Wait 10 seconds for the AD account to propagate.
Thread.Sleep(10000)
Return accountCreated
End Function
''' <summary>
''' Helper method to prompt the user for the LDAP path for the network
''' </summary>
''' <returns>The LDAP path for your network</returns>
Public Shared Function ConsolePromptForLDAPPath() As String
' Prompt for the LDAP path.
Console.WriteLine("An Active Directory connection is required. Please enter an")
Console.WriteLine("LDAP path for your network in the format 'LDAP://server/DC=subdomain,DC=domain,DC=com': ")
Dim ldapPath As String = Console.ReadLine()
Return ldapPath
End Function
Private Shared Function UserInRole(ByVal serviceProxy As OrganizationServiceProxy,
ByVal userId As Guid, ByVal roleId As Guid) As Boolean
' Establish a SystemUser link for a query.
Dim systemUserLink As New LinkEntity() With
{
.LinkFromEntityName = SystemUserRoles.EntityLogicalName,
.LinkFromAttributeName = "systemuserid",
.LinkToEntityName = SystemUser.EntityLogicalName,
.LinkToAttributeName = "systemuserid"
}
systemUserLink.LinkCriteria.AddCondition(
New ConditionExpression("systemuserid", ConditionOperator.Equal, userId))
' Build the query.
Dim query As New QueryExpression() With
{
.EntityName = Role.EntityLogicalName,
.ColumnSet = New ColumnSet("roleid")
}
query.Criteria.AddCondition(New ConditionExpression("roleid", ConditionOperator.Equal, roleId))
Dim systemUserRoleLink As New LinkEntity() With
{
.LinkFromEntityName = Role.EntityLogicalName,
.LinkFromAttributeName = "roleid",
.LinkToEntityName = SystemUserRoles.EntityLogicalName,
.LinkToAttributeName = "roleid"
}
systemUserRoleLink.LinkEntities.Add(systemUserLink)
query.LinkEntities.Add(systemUserRoleLink)
' Retrieve matching roles.
Dim ec As EntityCollection = serviceProxy.RetrieveMultiple(query)
If ec.Entities.Count > 0 Then
Return True
End If
Return False
End Function
Private Shared Function RetrieveRoleByName(ByVal serviceProxy As OrganizationServiceProxy,
ByVal roleStr As String) As Role
Dim roleQuery As QueryExpression = New QueryExpression With
{
.EntityName = Role.EntityLogicalName,
.ColumnSet = New ColumnSet("roleid")
}
roleQuery.Criteria.AddCondition(New ConditionExpression("name", ConditionOperator.Equal, roleStr))
Return serviceProxy.RetrieveMultiple(roleQuery).Entities(0).ToEntity(Of Role)()
End Function
End Class
End Namespace
另請參閱
AssociateEntitiesRequest
RetrieveMultipleRequest
使用範例和 Helper 程式碼
Helper 程式碼:選項組的列舉
Microsoft Dynamics 365
© 2017 Microsoft. 著作權所有,並保留一切權利。 著作權