.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
的任何组。这有两个问题:
- 即使
cn
attribute 已建立索引,也无法使用索引,因为您在开头使用了通配符。它必须查看 每个 组以尝试找到匹配项。这会减慢您的搜索速度。
- 因为您正在进行通配符搜索,它可能与多个帐户匹配。 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://"));
我正在查找对安全组的引用,我需要使用以下代码将用户添加到该安全组:
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
的任何组。这有两个问题:
- 即使
cn
attribute 已建立索引,也无法使用索引,因为您在开头使用了通配符。它必须查看 每个 组以尝试找到匹配项。这会减慢您的搜索速度。 - 因为您正在进行通配符搜索,它可能与多个帐户匹配。 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://"));