【发布时间】:2018-05-03 15:09:17
【问题描述】:
这篇文章是对以下内容的后续:
Active Directory: DirectoryEntry member list <> GroupPrincipal.GetMembers()
我有一个函数可以检索 Active Directory 中组的所有成员的 distinctName 属性。此函数用于检索所有用户和组对象的非常大的脚本(总运行时间为 7-10 分钟)。我的问题是,distinguishedName 上的下游 SSIS 查找非常慢。这并不奇怪,因为它查找的是 varchar(255) 与 UniqueIdentifier(16 字节)。我可以在源上执行 SQL Select,然后 Merge Join,这样可以加快速度。但是,我注意到提取物中存在潜在的竞争条件(请参阅上面的运行时间),其中组成员存在而没有匹配的 distinctName。如果是这种情况,那么我需要解决这个问题;但是,Merge Join 不会使加载失败,而 Lookup 可以设置为使加载失败。
所以,我需要通过 DistinguishedName 即时获取 guid。但是,当我尝试使用以下方法时,GetGroupMemberList 函数的性能会大幅下降。有没有更好/更快的方法来通过 distinctName 获取组成员 guid?
方法(用于两个循环):
listGroupMemberGuid.Add(new DirectoryEntry("LDAP://" + member, null, null, AuthenticationTypes.Secure).Guid);
listGroupMemberGuid.Add(new DirectoryEntry("LDAP://" + user, null, null, AuthenticationTypes.Secure).Guid);
功能:
private List<string> GetGroupMemberList(string strPropertyValue, string strActiveDirectoryHost, int intActiveDirectoryPageSize)
{
// Variable declaration(s).
List<string> listGroupMemberDn = new List<string>();
string strPath = strActiveDirectoryHost + "/<GUID=" + strPropertyValue + ">";
const int intIncrement = 1500; // https://msdn.microsoft.com/en-us/library/windows/desktop/ms676302(v=vs.85).aspx
var members = new List<string>();
// The count result returns 350.
var group = new DirectoryEntry(strPath, null, null, AuthenticationTypes.Secure);
//var group = new DirectoryEntry($"LDAP://{"EnterYourDomainHere"}/<GUID={strPropertyValue}>", null, null, AuthenticationTypes.Secure);
while (true)
{
var memberDns = group.Properties["member"];
foreach (var member in memberDns)
{
members.Add(member.ToString());
}
if (memberDns.Count < intIncrement) break;
group.RefreshCache(new[] { $"member;range={members.Count}-*" });
}
//Find users that have this group as a primary group
var secId = new SecurityIdentifier(group.Properties["objectSid"][0] as byte[], 0);
/* Find The RID (sure exists a best method)
*/
var reg = new Regex(@"^S.*-(\d+)$");
var match = reg.Match(secId.Value);
var rid = match.Groups[1].Value;
/* Directory Search for users that has a particular primary group
*/
var dsLookForUsers =
new DirectorySearcher {
Filter = string.Format("(primaryGroupID={0})", rid),
SearchScope = SearchScope.Subtree,
PageSize = 1000,
SearchRoot = new DirectoryEntry(strActiveDirectoryHost)
};
dsLookForUsers.PropertiesToLoad.Add("distinguishedName");
var srcUsers = dsLookForUsers.FindAll();
foreach (SearchResult user in srcUsers)
{
members.Add(user.Properties["distinguishedName"][0].ToString());
}
return members;
}
更新 1:
foreach(searchResult)中检索DN的代码:
foreach (SearchResult searchResult in searchResultCollection)
{
string strDn = searchResult.Properties["distinguishedName"][0].ToString();
var de = new DirectoryEntry("LDAP://" + strDn, null, null, AuthenticationTypes.Secure);
de.RefreshCache(new[] { "objectGuid" });
var guid = new Guid((byte[])de.Properties["objectGuid"].Value);
}
【问题讨论】:
标签: c# ssis active-directory