2012-02-28 96 views
6

回到我的活動目錄工具...獲取活動目錄中的組成員資格(memberOf)列表

我試圖列出用戶的「member of」屬性中的組。 下面是我使用的功能:

public static DataTable ListGroupsByUser(string selectedOu) 
{ 
    DataTable groupListByUser = new DataTable(); 
    String dom = "OU=" + selectedOu + ",OU=XXX,DC=XXX,DCXXX,DC=XXX,DC=XXX"; 
    DirectoryEntry directoryObject = new DirectoryEntry("LDAP://" + dom); 

    DataColumn column; 
    DataRow row; 

    column = new DataColumn(); 
    column.ColumnName = "ID"; 
    groupListByUser.Columns.Add(column); 

    column = new DataColumn(); 
    column.ColumnName = "User"; 
    groupListByUser.Columns.Add(column); 

    column = new DataColumn(); 
    column.ColumnName = "Groups"; 
    groupListByUser.Columns.Add(column); 
    int i = 1; 

    foreach (DirectoryEntry child in directoryObject.Children) 
    {     
     row = groupListByUser.NewRow(); 
     groupListByUser.Rows.Add(row); 
     row["ID"] = i++; 

     if (child.Properties["memberOf"].Value != null) 
     {      
      row["User"] = child.Properties["sAMAccountName"].Value.ToString(); 
      row["Groups"] = child.Properties["memberOf"].Value.ToString(); 
     } 
     else 
     { 
      row["Groups"] = "blabla"; 
     } 
    } 
    return groupListByUser; 
} 

它返回僅屬於一組用戶的權利組。只要有多個組,它就會返回System.Object []。

如何才能看到所有組?

回答

4

如果您使用的是.NET 3.5及更高版本,則應檢查System.DirectoryServices.AccountManagement(S.DS.AM)命名空間。在這裏閱讀全部內容:

基本上,你可以定義域範圍內,並可以輕鬆地查找用戶和/或組AD:

// set up domain context 
PrincipalContext ctx = new PrincipalContext(ContextType.Domain); 

// find a user 
UserPrincipal user = UserPrincipal.FindByIdentity(ctx, "SomeUserName"); 

if(user != null) 
{ 
    var groups = user.GetGroups(); 
    // or there's also: 
    //var authGroups = userByEmail.GetAuthorizationGroups() 
} 

的致電GetGroups()GetAuthorizationGroups()返回嵌套組成員身份 - so不再需要你去追捕那些嵌套的會員資格了!

新的S.DS.AM可以很容易地與AD中的用戶和羣組玩耍!

+0

謝謝Marc,我設法處理用戶和組,我無法做的是循環訪問用戶的成員名單。我用accountManagement命名空間而不是directoryServices重建該工具是否值得? – 2012-02-28 12:52:13

+0

@奧利弗:謝謝你們。儘管你的建議,我找到了一個解決方案,如下:'code'if(child.Properties [「memberOf」]。Value!= null) { foreach(child.Properties [「memberOf」]){ // row [「User」] = child.Properties [「sAMAccountName」]。Value.ToString(); row [「Member Of」] + = memberof.ToString()+「///」; } } else row [「Member Of」] =「No Group Defined」; } – 2012-02-29 14:02:54

4

問題是您的Properties["memberOf"].Value.ToString()

我做了一個小調查,該代碼爲我工作:

var memberGroups = child.Properties["memberOf"].Value; 

if (memberGroups.GetType() == typeof(string)) 
{ 
    row["Groups"] = (String)memberGroups; 
} 
else if (memberGroups.GetType().IsArray) 
{ 
    var memberGroupsEnumerable = memberGroups as IEnumerable; 

    if (memberGroupsEnumerable != null) 
    { 
     var asStringEnumerable = memberGroupsEnumerable.OfType<object>().Select(obj => obj.ToString()); 
     row["Groups"] = String.Join(", ", asStringEnumerable); 
    } 
} 
else 
{ 
    row["Groups"] = "No group found."; 
} 

這不是很可愛它的工作原理,並給出了進一步改進的餘地。 ;-)

+0

謝謝奧利弗,我試過你的解決方案,但似乎有點棘手。我不明白我在做什麼:var groups = objArray.Cast ()。Select(elem => elem.Values.ToString());它返回一個錯誤:值不能爲空。 參數名稱:source – 2012-02-29 08:10:51

+0

@HenryMeyer:我重寫了我的代碼,但我認爲marc_s方法在長期運行中確實更好,因爲您不必爲這些字符串和對象數組而煩惱。他們是類型特定的類,使得veeerry更容易訪問所有這些東西,更方便。 – Oliver 2012-02-29 09:53:53