2011-02-04 101 views
8

下面的代码让我的用户组中,但它返回 "CN=johnson\,Tom,OU=Users,OU=Main,DC=company,DC=com"获取用户名通过.NET

我只想返回第一个和最后一个名字。我怎样才能做到这一点?

DirectoryEntry ou = new DirectoryEntry(); 
DirectorySearcher src = new DirectorySearcher(); 

src.Filter = ("(&(objectClass=group)(CN=Gname))"); 
SearchResult res = src.FindOne(); 
if (res != null) 
{ 
    DirectoryEntry deGroup = new DirectoryEntry(res.Path); 
    PropertyCollection pcoll = deGroup.Properties; 

    foreach (object obj in deGroup.Properties["member"]) 
    { 
      ListBox1.Items.Add(obj.ToString()); 
    } 
} 
+0

下面是不是一个真正的答案,只是一个警告:从调用[DirectorySearcher.FindAll]换你的DirectoryEntry,和的DirectorySearcher特别任何SearchResultCollections(例如(HTTP ://msdn.microsoft.com/en-us/library/system.directoryservices.directorysearcher.findall.aspx))在using语句中,或try/finally与Dispose调用。 SearchResultCollections不能被垃圾收集。在使用我在网上找到的例子后,我查找了几天的内存泄漏,但没有处理任何内容。仔细检查MS文档以查看搜索Active Directory涉及哪些类hav – 2011-03-02 05:06:22

回答

22

我更喜欢使用System.DirectoryServices.AccountManagement类:

PrincipalContext principalContext = new PrincipalContext(ContextType.Domain); 
GroupPrincipal group = GroupPrincipal.FindByIdentity(principalContext, "GName"); 

搜索通过group.Members属性,直到你有你想要一个主要。然后提取像这样的名字:

foreach (Principal principal in group.Members) 
{ 
    string name = principal.Name; 
} 
+4

您需要添加对** System.DirectoryServices.AccountManagement **项目的引用。 – bigtlb 2011-02-04 19:20:38

+1

很好的回答!谢谢 – Eric 2011-02-04 19:30:46

2

使用你的代码中,给定名称名字)和SN)的属性应该工作。

如果使用System.DIrectoryServices.AccountManagement命名空间UserPrincipal(如@拉塞尔 - 麦克卢尔建议),你会发现给定名称性也。

除非您必须遍历受信任的林并需要全局编录才能找到用户,否则AccountManagement非常方便。

0

这是我在不使用AccountManagement类的情况下做的一个PowerShell脚本。它应该很容易把它翻译成C#:

[void][System.Reflection.Assembly]::LoadWithPartialName("System.DirectoryServices"); 

$groupName = "Grupo Domain"; 

$directoryEntry = New-Object System.DirectoryServices.DirectoryEntry; 
$directorySearcher = New-Object System.DirectoryServices.DirectorySearcher($directoryEntry, "(&(objectClass=group)(CN=$groupName))"); 
[void]$directorySearcher.PropertiesToLoad.Add("objectSid"); 
[void]$directorySearcher.PropertiesToLoad.Add("member"); 
$result = $directorySearcher.FindOne(); 

if ($result -eq $null) { return; } 

# Try get the group members through the "member" property. 
if ($result.Properties["member"].Count -gt 0) { 
    foreach ($member in $result.Properties["member"]) { 
     $memberSearcher = New-Object System.DirectoryServices.DirectorySearcher($directoryEntry, "(&(objectClass=*)(distinguishedName=$member))"); 
     [void]$memberSearcher.PropertiesToLoad.Add("msDS-PrincipalName"); 
     $memberResult = $memberSearcher.FindOne(); 
     if ($memberResult -eq $null) { continue; } 
     Write-Output $memberResult.Properties["msDS-PrincipalName"]; 
    } 
    return; 
} 
if ($result.Properties["objectSid"].Count -gt 0) { 
    # The group might be an AD primary group. Try get the members by the PrimaryGroupID. 
    $groupSid = New-Object System.Security.Principal.SecurityIdentifier($result.Properties["objectSid"][0], 0); 
    # Hacky way to get only the last RID. 
    $primaryGroupSid = $groupSid.Value.Replace($groupSid.AccountDomainSid.ToString(), [String]::Empty).TrimStart('-'); 
    $memberSearcher = New-Object System.DirectoryServices.DirectorySearcher($directoryEntry, "(&(objectClass=*)(primaryGroupId=$primaryGroupSid))"); 
    [void]$memberSearcher.PropertiesToLoad.Add("msDS-PrincipalName"); 
    $memberResult = $memberSearcher.FindAll(); 
    if ($memberResult -eq $null) { continue; } 
    foreach ($member in $memberResult) { 
     Write-Output $member.Properties["msDS-PrincipalName"]; 
    } 
}