.net:如何使用 C# 将用户添加到 Active Directory 安全组?

.net : How to add a user to a Active Directory Security Group using C#?

我正在查找对安全组的引用,我需要使用以下代码将用户添加到该安全组:

string strActiveDirectoryPath = @"GC://domain.com";

DirectoryEntry directoryEntryRoot = new DirectoryEntry(strActiveDirectoryPath);

using (DirectorySearcher searcher = new DirectorySearcher(directoryEntryRoot))
{  
    searcher.PageSize = 1000;
    searcher.Filter = "(&(objectClass=group)(cn=*SGNAME*))";
    //searcher.SearchScope = SearchScope.Subtree;
    SearchResult securityGroup = searcher.FindOne();  
}

上面的代码有时会抛出一个异常

Search resulted in too many records

我获取安全组的逻辑是否正确?

然后我获取用户的引用并尝试将其添加到安全组:

searcher.Filter = "(SAMAccountName=" + UserAlias + ")";
searcher.PropertiesToLoad.Add("givenname");
searcher.PropertiesToLoad.Add("displayName");               

SearchResult userALias = searcher.FindOne();

DirectoryEntry ent = new DirectoryEntry(securityGroup.Path);              
string domainString = "GC://domain.com/";
int Start =  domainString.Length;
string member = userALias.Path.Substring(domainString.Length);

ent.Properties["member"].Add(member);
// ent.Invoke("Add", new object[] { s });

ent.CommitChanges();
ent.Close();

我创建了一个 DirectoryEntry 的实例并提供了我找到的安全组的路径。

应该向 DirectoryEntry 提供什么?

CommitChanges 失败,异常:

The server is unwilling to process the request.

我看到了几个问题。第一:

searcher.Filter = "(&(objectClass=group)(cn=*SGNAME*))";
SearchResult securityGroup = searcher.FindOne();

因为您使用的是通配符,所以您正在搜索名称中任意位置带有 SGNAME 的任何组。这有两个问题:

  1. 即使 cn attribute 已建立索引,也无法使用索引,因为您在开头使用了通配符。它必须查看 每个 组以尝试找到匹配项。这会减慢您的搜索速度。
  2. 因为您正在进行通配符搜索,它可能与多个帐户匹配。 documentation for DirectorySearcher.FindOne() 表示:

If more than one entry is found during the search, only the first entry is returned.

所以你不能保证返回的群就是你想要的群

那你为什么会遇到异常?我不知道。我很想看到完整的异常详细信息。那里可能会有一个十六进制数。

但我认为这并不重要。所有这些都可以通过完全匹配名称来解决:

searcher.Filter = "(&(objectClass=group)(cn=SGNAME))";

正在向群组添加成员

我的猜测是您的 member 变量不是正确的 distinguishedName。不要尝试从 Path 中解析 DN,只需在搜索结果中请求 distinguishedName。例如:

searcher.Filter = "(SAMAccountName=" + UserAlias + ")";
searcher.PropertiesToLoad.Add("distinguishedName");

SearchResult userALias = searcher.FindOne();

DirectoryEntry ent = securityGroup.GetDirectoryEntry();              

string member = (string) userALias.Properties["distinguishedName"][0];

ent.Properties["member"].Add(member);

ent.CommitChanges();
ent.Close();

更新:您也无法通过全局目录进行更新。您必须使用 LDAP://:

string strActiveDirectoryPath = "LDAP://domain.com";

或者,如果您确实需要搜索 GC(如果您的林中有多个域),则在为组创建 DirectoryEntry 时必须切换到 LDAP。

DirectoryEntry ent = new DirectoryEntry(securityGroup.Path.Replace("GC://", "LDAP://"));