在多个域服务器中搜索用户的lastLogon属性
本文关键字:用户 lastLogon 属性 搜索 服务器 | 更新日期: 2023-09-27 18:07:04
首先,请原谅我没有使用正确的术语。在我用错术语的地方纠正我。
目标是以编程方式检索给定用户名的lastLogon
日期。
我们有我认为是森林的地方;两台AD服务器,如- adserver01.aa.mycompany.com
和adserver02.aa.mycompany.com
我用微软的浏览器从第三台机器连接到这些服务器来检查对象。在那里,我看到一些用户在adserver01
中有lastLogon日期,但在adserver02
中没有。例如,在adserver02
中lastLogon的值是0x0,而在adserver01
中对于某些用户来说,它是一个有效的日期。
我开发的代码到目前为止,作为一个Windows窗体应用程序,工作良好,如果只有一个AD服务器涉及。如何检查两个服务器并返回非零值(如果可用),在lastLogon日期属性中?
private static string GetLastActivityDate(string UserName)
{
string domainAndUserName = String.Format(@"LDAP://aa.mycompany.com/CN={0},OU=CLIENT_PROD,OU=clients.mycompany.com,DC=aa,DC=mycompany,DC=com", UserName);
string OUAdminUserName = "abc";
string OUAdminPassword = "xyz";
AuthenticationTypes at = AuthenticationTypes.Secure;
DateTime lastActivityDate;
string returnvalue;
long lastLogonDateAsLong;
using (DirectoryEntry entryUser = new DirectoryEntry(domainAndUserName, OUAdminUserName, OUAdminPassword, at))
using (DirectorySearcher mysearcher = new DirectorySearcher(entryUser))
try
{
using (SearchResultCollection results = mysearcher.FindAll())
{
if (results.Count >= 1)
{
DirectoryEntry de = results[0].GetDirectoryEntry();
lastLogonDateAsLong = GetInt64(de, "lastLogon");
try
{
if (lastLogonDateAsLong != -1)
{
lastActivityDate = DateTime.FromFileTime(lastLogonDateAsLong);
returnvalue = lastActivityDate.ToString();
}
else
{
returnvalue = "-Not available-";
}
}
catch (System.ArgumentOutOfRangeException aore)
{
returnvalue = "Not available";
}
}
else
{
returnvalue = string.Empty;
}
}
}
catch (System.DirectoryServices.DirectoryServicesCOMException dsce)
{
returnvalue = "- Not available -";
}
return returnvalue;
}
谢谢。
编辑: private static Int64 GetInt64(DirectoryEntry entry, string attr)
{
DirectorySearcher ds = new DirectorySearcher(
entry,
String.Format("({0}=*)", attr),
new string[] { attr },
SearchScope.Base
);
SearchResult sr = ds.FindOne();
if (sr != null)
{
if (sr.Properties.Contains(attr))
{
return (Int64)sr.Properties[attr][0];
}
}
return -1;
}
忘了说,AD架构,结构等,在两个服务器上看起来完全一样。
查看这篇文章http://www.codeproject.com/Articles/19181/Find-LastLogon-Across-All-Windows-Domain-Controlle
我也有同样的问题,但只有一个域,我通过使用以下代码解决了这个问题,但是我正在检查所有用户的lastLogin
public static Dictionary<string, DateTime> UsersLastLogOnDate()
{
var lastLogins = new Dictionary<string, DateTime>();
DomainControllerCollection domains = Domain.GetCurrentDomain().DomainControllers;
foreach (DomainController controller in domains)
{
try
{
using (var directoryEntry = new DirectoryEntry(string.Format("LDAP://{0}", controller.Name)))
{
using (var searcher = new DirectorySearcher(directoryEntry))
{
searcher.PageSize = 1000;
searcher.Filter = "(&(objectClass=user)(!objectClass=computer))";
searcher.PropertiesToLoad.AddRange(new[] { "distinguishedName", "lastLogon" });
foreach (SearchResult searchResult in searcher.FindAll())
{
if (searchResult.Properties.Contains("lastLogon"))
{
var lastLogOn = DateTime.FromFileTime((long)searchResult.Properties["lastLogon"][0]);
var username = Parser.ParseLdapAttrValue(searchResult.Properties["distinguishedName"][0].ToString());
if (lastLogins.ContainsKey(username))
{
if (DateTime.Compare(lastLogOn, lastLogins[username]) > 0)
{
lastLogins[username] = lastLogOn;
}
}
else
{
lastLogins.Add(username, lastLogOn);
}
}
}
}
}
}
catch (System.Runtime.InteropServices.COMException comException)
{
// Domain controller is down or not responding
Log.DebugFormat("Domain controller {0} is not responding.",controller.Name);
Log.Error("Error in one of the domain controllers.", comException);
continue;
}
}
return lastLogins;
}
在代码的顶部,您可以使用以下代码来获取林中的所有域。
Forest currentForest = Forest.GetCurrentForest();
DomainCollection domains = currentForest.Domains;
foreach(Domain domain in domains)
{
// check code above
}
是否有更简单的方法?实际上还有另一个属性lastLogonTimestamp,我认为与2003域级别一起添加,它试图在最后一次登录的域中保持单个一致的值。唉,它有一个奇怪的复制时间模式,可能会过期两周。