Получите только включенные учетные записи из Active Directory

Я использую System.DirectoryServices.AccountManagement.dll для работы с Active Directory, чтобы получить всех пользователей в группе «Пользователи домена».

Это возвращает всех пользователей в домене, но мне нужно получить только включенных.

Вот пример кода:

List<string> users = new List<string>();

PrincipalContext pcContext = GetPrincipalContext();

GroupPrincipal grp = GroupPrincipal.FindByIdentity(pcContext,
                               IdentityType.Name,
                               "Domain Users");

foreach (Principal user in grp.GetMembers(true).OfType<UserPrincipal>())
{
    if (user.Enabled != false)
    {
        users.Add(user.Name);
    }
}

Другие группы работают нормально, но когда группа «Пользователи домена», значение свойства Enabled равно false для всех пользователей. Это делает невозможным различие между включенными и отключенными пользователями без выполнения дополнительного запроса для каждого пользователя.


person Moutasim Momani    schedule 17.01.2013    source источник
comment
Вам нужно только имя учетной записи? Есть ли требование использовать пространство имен AccountManagement? Делаете ли вы что-нибудь с объектом UserPrincipal, кроме сохранения имени? Я спрашиваю только потому, что ваши требования могут быть лучше удовлетворены с использованием пространства имен DirectoryServices и DirectorySearcher с фильтром LDAP, например: (&(objectclass=user)(memberOf=CN=Domain Users,dc=company,dc=com)(! (userAccountControl:1.2.840.113556.1.4.803:=2))) Что вернет всех пользователей в этой группе, которые включены.   -  person randcd    schedule 12.08.2013
comment
randcd: Я бы предпочел использовать пространство имен AM, так как оно предоставляет очень чистый API. Я, конечно, мог бы использовать LDAP, но тогда все становится намного сложнее (особенно в случае, когда пользователи являются только членами группы «Пользователи домена», потому что это их основная группа, поскольку в этом случае она не указана в memberOf).   -  person RobSiklos    schedule 13.08.2013
comment
Принципал в цикле ForEach на самом деле должен быть UserPrincipal — Enabled не является методом или свойством, доступным для объекта Princpal. По крайней мере, не в .net 4.6.1. Все это можно сделать с помощью пространства имен System.DirectoryServices.AccountManagement.   -  person DtechNet    schedule 20.12.2016


Ответы (3)


Объекты UserPrinciple имеют для этого логическое свойство Enabled.

http://msdn.microsoft.com/en-us/library/system.directoryservices.accountmanagement.userprincipal_properties.aspx

// Add this to GetUserDetails
objUserDetails.EmployeeId = UserPrinical.EmployeeId;


// Then condition the add to only add enabled
if (objUserDetails.Enabled) {
    objUserDetails.Add(GetUserDetails(p.Name));
}
person Joe Petrini    schedule 18.01.2013
comment
Это не решает проблему, поскольку свойство Enabled не заполняется должным образом, когда запрашиваемой группой являются пользователи домена. - person RobSiklos; 09.08.2013

Метод решения этой проблемы может заключаться в том, чтобы сначала найти включенных пользователей с помощью класса PrincipalSearcher, а затем использовать метод принципала IsMemberOf().

List<string> users = List<string>();
PrincipalContext pcContext = GetPrincipalContext();
GroupPrincipal grp = GroupPrincipal.FindByIdentity(pcContext, IdentityType.Name, "Domain Users");
UserPrincipal searchFilter = new UserPrincipal(pcContext){ Enabled = true }
PrincipalSearcher searcher = new PrincipalSearcher(searchFilter);
PrincipalSearchResult<Principal> results = searcher.FindAll();
foreach (Principal user in results)
    if (user.IsMemberOf(grp))
        users.Add(user.SamAccountName);
person Hive    schedule 21.12.2015

На странице MSDN свойства Enabled есть примечание. говоря:

Если принципал не был сохранен в хранилище, это свойство возвращает значение null. После сохранения принципала включенный параметр по умолчанию зависит от хранилища. Хранилища AD DS и AD LDS отключают новых участников, когда они сохраняются, тогда как SAM включает новых участников, когда они сохраняются. Приложение может установить для этого свойства значение только после того, как оно будет сохранено в хранилище.

Возможно, это связано, если по умолчанию установлено значение false?

Кроме того, на форуме MSDN есть сообщение о UserPrincipal.Enabled возвращает False для учетных записей, которые фактически включены? и это действительно похоже на вашу проблему. Согласно сообщению, возможно, здесь есть решение:

Думаю, я неправильно понял. Не обращайте внимания на то, что я написал ранее. Кажется, я знаю, что происходит. Очевидно, что метод GetMembers не загружает данные UserPrincipal. Я не знаю, есть ли лучшее решение, но работает следующее (по крайней мере, в моем AD):

foreach (UserPrincipal user in group.GetMembers(false))
{
   UserPrincipal tempUser = UserPrincipal.FindByIdentity(context, user.SamAccountName);
   // use tempUser.Enabled
   // other code here
}
person Emmanuel Istace    schedule 11.08.2013
comment
Пользователи уже сохранены, поэтому первая часть вашего ответа не имеет отношения к вопросу. Что касается остального, да - я знаю, что могу это сделать - в вопросе говорится, что мы хотим иметь правильное значение для свойства Enabled без выполнения каких-либо дополнительных запросов (особенно не по одному на пользователя, например в этом цикле foreach). В сообщении, которое вы цитируете, даже говорится, что это решение слишком медленное, чтобы быть полезным. - person RobSiklos; 12.08.2013