2012-04-20 4 views
7

я нашел How can I get a list of users from active directory?Выберите запись пользователя идентификатор по имени и фамилии

Это полезно, когда у меня есть только несколько пользователей, но у меня есть очень много пользователей в AD, поэтому, когда я запускаю мой запрос

if ((String)(entry.Properties["sn"].Value) == "lname" 
    && (String)(entry.Properties["givenName"].Value) == "fname") 
{ 
    return entry.Properties["samAccountName"].Value.ToString(); 
} 

Понадобилось слишком много времени, чтобы закончить.

Что я могу сделать, чтобы выполнить поиск одного идентификатора входа в систему по имени и фамилии?

ответ

7

Поскольку вы находитесь на .NET 4 вы должны проверить пространство имен (S.DS.AM). Читайте об этом здесь:

В принципе, вы можете определить контекст домена и легко найти пользователей и/или групп в AD:

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

// find a user - by e.g. his "samAccountName", or the Windows user name or something 
UserPrincipal user = UserPrincipal.FindByIdentity(ctx, "SomeUserName"); 

if(user != null) 
{ 
    // do something here....  
    string samAccountName = user.SamAccountName; 
} 

Если вы не можете найти пользователя, указанного по имени пользователя, вы также можете использовать новую функцию поиска:

// define a "query-by-example" principal - here, we search for a UserPrincipal 
// and with the first name (GivenName) and a last name (Surname) 
UserPrincipal qbeUser = new UserPrincipal(ctx); 
qbeUser.GivenName = firstName; 
qbeUser.Surname = lastName; 

// create your principal searcher passing in the QBE principal  
PrincipalSearcher srch = new PrincipalSearcher(qbeUser); 

// find all matches 
foreach(var found in srch.FindAll()) 
{ 
    // do whatever here - "found" is of type "Principal" - it could be user, group, computer.....   
} 

Новый S.DS.AM позволяет очень легко играть с пользователями и группами в AD! И просто поиск одного пользователя тоже будет относительно быстрым.

+0

большой помощи, я хочу, чтобы я мог принять все anwsers ваших ребят игровой – user1225072

+0

@marc_s это было именно то, что я искал, идеально, спасибо. Однако я обнаружил, что, если какое-либо поле, которое вы запрашиваете у пользователя для поиска, не требуется, пропустите соответствующее свойство в 'UserPrincipal'. Я изначально нажимал 'string.empty', а затем даже« null »и получал ** no ** результаты. Однако, как только я добавил оператор 'if' и проигнорировал этот элемент в' UserPrincipal', у меня наконец были возвращены результаты (_ie: skipped ** GivenName **, когда ** FirstName ** не было заполнено, вместо настройки по умолчанию_). – famousKaneis

0

Вам необходимо установить QueryFilter на searcher, а затем позвонить searcher.FindOne() вместо searcher.FindAll(). Фильтр запросов может быть установлен на объект UserPrincipal, где вы задаете поля, которые хотите найти.

Microsoft имеет хороший пример этого на странице Query By Example, хотя их пример ожидает найти несколько объектов, соответствующих заданным критериям.

Особенно буквальная адаптация связанного вопроса к вашему требованию будет

using (var context = new PrincipalContext(ContextType.Domain, "mydomain.com")) 
{ 
    using (var searcher = new PrincipalSearcher(new UserPrincipal(context) { GivenName = "fname", Surname = "lname" })) 
    { 
      foreach (var result in searcher.FindAll()) 
      { 
       DirectoryEntry de = result.GetUnderlyingObject() as DirectoryEntry; 
       return de.Properties["samAccountName"].Value.ToString(); 
      } 
    } 
} 
0

Если entry является частью IEnumerable коллекции, вы могли бы сделать что-то вроде:

var entries = {do your population of the collection here} 

var entry = entries.Where(e=>e.Properties["sn"].Value.ToString() == "lname" 
    && e=>.Properties["givenName"].Value.ToString() == "fname") 
    .FirstOrDefault(); 
2

Вы должны использовать сервер AD для фильтрации. Сделайте это, предоставив синтаксический фильтр LDAP. Кроме того, указать только свойство, нужно с помощью propertiesToLoad аргумента FindAll:

public static SearchResultCollection FindByName(
     string domain, string firstName, string lastName, string[] properties) { 
     var rootEntry = new DirectoryEntry("LDAP://" + domain); 
     var filter = string.Format("(&(sn={0})(givenName={1}))", lastName, firstName); 
     var searcher = new DirectorySearcher(rootEntry, filter, properties); 
     return searcher.FindAll(); 
    } 

    // Using the method: 
    var result = FindByName("mydomain", "Robert", "Smith", new[] { "samAccountName" })[0]; 
    string uName = (string)result.Properties["samAccountName"][0];