我需要从Active Directory获取一个用户列表,其密码即将到期(例如在5天内)。
我需要通过向DirectorySearcher
添加过滤器来实现此目的,因为它最快。我已将samaccountname
模式添加到过滤器,但我无法弄清楚如何向其中添加pwdLastSet
。理想情况下,过滤器会将用户列表减少到仅满足密码过期标准的用户列表。
using (DirectoryEntry searchRoot = GetXYZAccountOU())
{
DirectorySearcher ds = new DirectorySearcher(searchRoot);
ds.SearchScope = SearchScope.Subtree;
ds.Filter = "(&" +
"(samaccountname=XYZ*)"
+ ")";
SearchResultCollection result = ds.FindAll();
foreach (SearchResult searchResult in result)
{
var de = searchResult.GetDirectoryEntry();
//long pwdLastSetVal = (long)de.Properties["pwdLastSet"][0];
//Console.WriteLine(de.Properties["displayName"].Value + ": " + DateTime.FromFileTimeUtc(pwdLastSetVal));
Console.WriteLine(de.Properties["displayName"].Value);
}
Console.Read();
}
此处XYZ是我的用户samaccountname
的起始字母。
如果我运行此代码,我可以获得displayName
和其他一些属性,但不能获得pwdLastSet
或计算属性msDS-UserPasswordExpiryTimeComputed
,而我可以在Active Directory浏览器中看到它们。
答案 0 :(得分:0)
您必须事先知道密码的有效期,并查询pwdLastSet
属性。但当然日期以奇怪的格式存储。
我们假设它们有效期为30天。然后你可以像这样构造查询:
var date = DateTime.Now.AddDays(-30).ToFileTime();
var query = $"(&(objectclass=user)(objectcategory=person)(!pwdlastset=0)(pwdlastset<={date})(!userAccountControl:1.2.840.113556.1.4.803:=65536))";
帐户可以设置为永不过期密码,因此您必须在查询中考虑该帐户。 userAccountControl
条件可以做到这一点。
如果您不想在代码中使用幻数,可以通过查看域根目录下的maxPwdAge
属性来查找域中密码的有效期(它以不同的,奇怪的格式存储):
var domain = new DirectoryEntry("LDAP://domain.com");
Int64 pwdAge = (Int64) domain.Properties["maxPwdAge"][0];
var maxPwdAge = pwdAge / -864000000000; //convert to days