2011-02-10 151 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

相關問題