在.NETFramework 3.5中,System.DirectoryServices.AccountManagement类提供了一种简便的方式来访问Active Directory中的用户。获取用户的过程非常直接,如下所示:
using(var adContext = new PrincipalContext(ContextType.Domain, ADDomainName, ADContainer))
{
string username = "ADusername";
var foundUser = UserPrincipal.FindByIdentity(adContext, username);
if(foundUser != null)
{
// 使用用户对象进行各种操作
}
}
然而,获取用户的最后登录时间(lastlogon)并不像预期的那样简单。这是因为lastLogon属性并不在域中复制,如果用户从未登录到域控制器B,那么域控制器B将不知道用户的最后登录时间。
为了解决这个问题,需要使用扩展属性来检索正确的时间。通过扩展UserPrincipal类,可以访问这些属性。这不仅包括真实的最后登录时间,还可以包括其他属性,如传真号码等。
以下是扩展的UserPrincipal类,可以使用它来代替UserPrincipal:
using System;
using System.DirectoryServices.AccountManagement;
using System.Reflection;
namespace MyNameSpace
{
[DirectoryRdnPrefix("CN")]
[DirectoryObjectClass("user")]
public class UserPrincipalExtended : UserPrincipal
{
public UserPrincipalExtended(PrincipalContext context) : base(context) { }
public UserPrincipalExtended(PrincipalContext context, string samAccountName, string password, bool enabled) : base(context, samAccountName, password, enabled) { }
public static new UserPrincipalExtended FindByIdentity(PrincipalContext context, string identityValue)
{
return (UserPrincipalExtended)FindByIdentityWithType(context, typeof(UserPrincipalExtended), identityValue);
}
public static new UserPrincipalExtended FindByIdentity(PrincipalContext context, IdentityType identityType, string identityValue)
{
return (UserPrincipalExtended)FindByIdentityWithType(context, typeof(UserPrincipalExtended), identityType, identityValue);
}
#region custom attributes
[DirectoryProperty("RealLastLogon")]
public DateTime? RealLastLogon
{
get
{
if(ExtensionGet("LastLogon").Length > 0)
{
var lastLogonDate = ExtensionGet("LastLogon")[0];
var lastLogonDateType = lastLogonDate.GetType();
var highPart = (Int32)lastLogonDateType.InvokeMember("HighPart", BindingFlags.GetProperty, null, lastLogonDate, null);
var lowPart = (Int32)lastLogonDateType.InvokeMember("LowPart", BindingFlags.GetProperty | BindingFlags.Public, null, lastLogonDate, null);
var longDate = ((Int64)highPart << 32 | (UInt32)lowPart);
return longDate > 0 ? (DateTime?)DateTime.FromFileTime(longDate) : null;
}
return null;
}
}
#endregion
}
}
[DirectoryProperty("HomePage")]
public string HomePage
{
get
{
if(ExtensionGet("HomePage").Length != 1)
return null;
return (string)ExtensionGet("HomePage")[0];
}
set
{
this.ExtensionSet("HomePage", value);
}
}