IsAccountLockedOut()
работает не так, как Enabled
, поскольку это две разные вещи:
- Учетная запись заблокирована из-за слишком большого количества попыток ввода неверного пароля. Это сделано для предотвращения попыток перебора пароля. Учетные записи обычно автоматически разблокируются через определенный промежуток времени. Число неправильных попыток, вызывающих блокировку, и время до автоматической разблокировки c настраивается администратором домена.
- Отключение учетной записи (
Enabled == false
) - это когда администратор специально отключил ее. Никто не сможет пройти аутентификацию с отключенной учетной записью, даже если он знает правильный пароль.
Чтобы найти заблокированные учетные записи, вы должны посмотреть на lockoutTime
атрибут. Он хранит время, когда аккаунт был заблокирован. Значение 0 означает, что оно не заблокировано. Таким образом, вы хотите искать учетные записи, у которых значение больше 0. Это будет запрос LDAP:
(&(objectCategory=person)(objectClass=user)(lockoutTime>=1))
Вы должны использовать >=1
, поскольку LDAP spe c на самом деле не поддерживает >
.
Я предполагаю, что вы задаете этот вопрос, поскольку вы пытаетесь выполнить поиск с помощью PrincipalSearcher
, что ограничивает вас поиском на основе свойств, которые предоставляет вам UserPrincipal
. Поскольку атрибут lockoutTime
не предоставляется UserPrincipal
, вы не можете сделать это таким образом. Вам придется использовать DirectorySearcher
напрямую (это то, что PrincipalSearcher
использует в любом случае за кулисами). Вот пример, который вывел бы имя пользователя и время, когда произошла блокировка:
var searcher = new DirectorySearcher() {
Filter = "(&(objectCategory=person)(objectClass=user)(lockoutTime>=1))",
PageSize = 1000, //make sure we get more than one page, if needed
PropertiesToLoad = { "sAMAccountName", "lockoutTime" } //which atrributes you want to use
};
using (var results = searcher.FindAll()) {
foreach (SearchResult result in results) {
var username = (string) result.Properties["sAMAccountName"][0];
var lockoutTime = DateTime.FromFileTime((long) result.Properties["lockoutTime"][0]);
Console.WriteLine($"{username} was locked out at {lockoutTime}");
}
}
Лично я вообще прекратил использовать UserPrincipal
/ PrincipalSearcher
, потому что производительность всегда хуже (иногда это не так заметно, в других случаях это абсолютно так), и бывают такие моменты, когда вы все равно не можете его использовать. Я написал статью о том, как добиться максимальной производительности при общении с AD, если вам интересно: Active Directory: лучшая производительность