2011-02-10 147 views
2

首先,我必须枚举当前用户的所有AD组。获取SID和名字很简单:计数Active Directory安全组成员

foreach(var group in WindowsIdentity.GetCurrent().Groups) 
{ 
    var sid = new SecurityIdentifier(group.Value); 
    string name = (group.Translate(typeof(NTAccount)) as NTAccount).Value; 
} 

然后,我需要确定每个组的成员的数量,我不能得到那个工作。我想我需要一种方法来获取当前用户组的可分辨名称。任何想法如何获得?

我做了什么至今:我尝试了WMI这样的查询,但它不返回任何结果,因为我需要完全合格的域名,但NTAccount给我唯一的“友好”域帐户(域\组) :

SELECT PartComponent FROM Win32_GroupUser 
WHERE (GroupComponent = "Win32_Group.Domain='somedomain', Name='somegroup'") 

然后我试图LDAP,通过结合到该组的SID周围缺少路径/专有名称的工作:

var adGroupEntry = new DirectoryEntry(String.Format("LDAP://<SID={0}>", group.Value)); 
if (adGroupEntry != null) 
{ 
    IEnumerable members = adGroupEntry.Invoke("Members", null) as IEnumerable; 
    if (members != null) 
    { 
    foreach (object member in members) 
    { 
     noOfMembers++; 
    } 
    } 
} 

我t找到该组,名称属性返回正确的值,但Members从不包含任何元素。如果我知道一个组的完整LDAP路径(例如,当我硬编码它),上面的代码实际上会产生组中的正确数量的用户。

我在这里错过了什么?我对Active Directory或WMI不是很熟悉。

限制:

  • 我不能硬编码任何域名或LDAP路径。
  • 我仅限于.NET 2.0,所以我不能使用System.DirectoryServices.AccountManagement

回答

1

我可以在您的环境中重现您的问题。这听起来像ADSI中的一个bug。

如果您同时使用serverless bindingSID binding,则返回的COM对象不起作用。

我可以通过不使用无服务器的bindnig来解决这个问题。即使用这个LDAP://*yourdomain.com*/<SID={0}>而不是

我也可以通过再次绑定对象来解决这个问题。

var adGroupEntry = new DirectoryEntry(String.Format("LDAP://<SID={0}>",group.Value)); 
string dn = adGroupEntry.Properties["distinguishedName"].Value as string; 
DirectoryEntry de = new DirectoryEntry("LDAP://" + dn); 
if (de != null) 
{ 
    IEnumerable members = de.Invoke("Members", null) as IEnumerable; 
    if (members != null) 
    { 
     foreach (object member in members) 
     { 
      noOfMembers++;  
     } 
    } 
} 
+0

非常感谢您测试我的代码和解决方法!它实际上也解决了我的问题:)我没想到能够从属性中获得可分辨名称,因为此信息的类型化属性在QuickWatch中没有包含有用的内容。 – realMarkusSchmidt 2011-02-11 15:40:30

相关问题