以下是在AD中创建用户的简单代码。代码是DC非特定的。它不关心它创建它的DC,它将使用服务器连接的Windows默认值。
using (PrincipalContext pc = new PrincipalContext(ContextType.Domain, Domain, path, ContextOptions.Negotiate, ManagementUsername, ManagementPassword))
{
try
{
using (UserPrincipal up = new UserPrincipal(pc, username, password, true))
{
up.GivenName = firstName; up.Surname = lastName; up.DisplayName = firstName + " " + lastName; up.UserPrincipalName = username + "@" + Domain; up.Save();
}
}
catch (PasswordException) { return null; }
}
问题在于新帐户的复制时间(通常是域名有15分钟)。当想要在连接到与服务器不同的DC的工作站上使用该帐户的人请求帐户时,尝试实现按需帐户创建时,这不起作用。他们最终不得不坐在工作站前15分钟无法登录。
问题: 有没有办法连接到基于客户端IP地址的DC来创建它?或者有没有办法在所有DC上创建帐户并使复制正常?或者强制帐户以编程方式进行复制(基于搜索SO,我猜不是)。
答案 0 :(得分:2)
Forest adForest = Forest.GetCurrentForest();
ActiveDirectorySite[] sites = new ActiveDirectorySite[adForest.Sites.Count];
adForest.Sites.CopyTo(sites, 0);
List<ActiveDirectorySubnet> subnets = new List<ActiveDirectorySubnet>();
sites.ToList().ForEach(x =>
{
ActiveDirectorySubnet[] subnetTemp = new ActiveDirectorySubnet[x.Subnets.Count];
x.Subnets.CopyTo(subnetTemp, 0);
subnets.AddRange(subnetTemp);
});
IPAddress address = IPAddress.Parse("IPAddress to look up closest DC");
var currentSubnet = subnets.Where(x => address.IsInRange(x.Name));
var location = currentSubnet.First().Site.Name;
DomainController dc = DomainController.FindOne(new DirectoryContext(DirectoryContextType.Domain, Domain), location);
这将使您获得与该站点和域相关联的DC,该站点和域最接近拓扑中的指定IP地址。 然后将DC IP地址传递给Principal Context。
using (PrincipalContext pc = new PrincipalContext(ContextType.Domain, dc.IPAddress, path, ContextOptions.Negotiate, ManagementUsername, ManagementPassword))
{
try
{
using (UserPrincipal up = new UserPrincipal(pc, username, password, true))
{
up.GivenName = firstName; up.Surname = lastName; up.DisplayName = firstName + " " + lastName; up.UserPrincipalName = username + "@" + Domain; up.Save();
}
}
catch (PasswordException) { return null; }
}
创建用户。
注意:IPAddress函数是通过github上的NetTools IPAddressRange类以及它的以下自定义扩展来完成的。
/// <summary>
/// All extensions for IPAddress type
/// </summary>
public static class IPAddressExtension
{
/// <summary>
/// Determine whether this IP address is part of the range/subnet
/// </summary>
/// <param name="range">A range of IPAddresses</param>
/// <returns></returns>
public static bool IsInRange(this IPAddress thisIP, IPAddressRange range)
{
return range.Contains(thisIP);
}
/// <summary>
/// Determine whether this IP address is part of the range/subnet
/// </summary>
/// <param name="range">Can be specified in CIDR/UNI (ex: 192.168.10.0/24) </param>
/// <returns></returns>
public static bool IsInRange(this IPAddress thisIP, string rangeIP)
{
IPAddressRange range = IPAddressRange.Parse(rangeIP);
return range.Contains(thisIP);
}
/// <summary>
/// Determine whether this IP address is part of the range/subnet
/// </summary>
/// <param name="ipBegin">Beginning IP address of range</param>
/// <param name="ipEnd">Ending IP address of range</param>
/// <returns></returns>
public static bool IsInRange(this IPAddress thisIP, IPAddress ipBegin, IPAddress ipEnd)
{
IPAddressRange range = new IPAddressRange(ipBegin, ipEnd);
return range.Contains(thisIP);
}
}