Подсчет членов группы безопасности Active Directory

Во-первых, мне нужно перечислить все группы AD текущего пользователя. Получить SID и имя просто:

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

Затем мне нужно определить количество членов в каждой из групп, и я не могу заставить это работать. Думаю, мне нужен способ получить отличительное имя групп текущих пользователей. Есть идеи, как это получить?

Что я сделал до сих пор: я попробовал выполнить такой запрос WMI, но он не дал результатов, потому что мне понадобится полное доменное имя, но NTAccount дает мне только "дружественную" учетную запись домена (DOMAIN \ group ):

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++;
    }
  }
}

Он находит группу, свойство name возвращает правильное значение, однако Members никогда не содержит никаких элементов. Если бы я знал полный путь LDAP для группы (например, когда я его жестко запрограммировал), приведенный выше код фактически дал бы правильное количество пользователей в группе.

Что мне здесь не хватает? Я не очень знаком с Active Directory или WMI.

Ограничения:

  • Я не могу жестко запрограммировать какие-либо доменные имена или пути LDAP.
  • Я ограничен .NET 2.0, поэтому не могу использовать System.DirectoryServices.AccountManagement.

person realMarkusSchmidt    schedule 10.02.2011    source источник


Ответы (1)


Я могу воспроизвести вашу проблему в своем окружении. Для меня это звучит как ошибка в ADSI.

Возвращенный COM-объект не работает, если вы используете бессерверная привязка и привязка SID одновременно.

Я мог бы обойти это, не используя бессерверную привязку. т.е. используя вместо этого 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++;     
        }   
    } 
} 
person Harvey Kwok    schedule 11.02.2011
comment
Большое спасибо за тестирование моего кода и обходного пути! Это фактически устранило проблему и для меня :) Я не ожидал, что смогу получить отличительное имя из свойств, поскольку типизированное свойство для этой информации не содержало полезного содержимого в QuickWatch. - person realMarkusSchmidt; 11.02.2011