Active Directory在Windows服务中获取锁定/解锁状态

时间:2015-06-29 19:39:34

标签: c# active-directory windows-services windows-server-2012-r2

我正在制作一个 Windows服务,它会在我的本地域TRY.local中获取所有Active Directory帐户的锁定/解锁状态。 即使名为user1的帐户被锁定,它也会为 IsAccountLocked()提供 false 值。

using (var context = new PrincipalContext(ContextType.Domain, "TRY.local"))
{
    using (var searcher = new PrincipalSearcher(new UserPrincipal(context)))
    {
        foreach (var result in searcher.FindAll())
        {
            DirectoryEntry de = result.GetUnderlyingObject() as DirectoryEntry;
            Library.WriteErrorLog("SAM Account Name : " + de.Properties["samaccountname"].Value);
            int uc = Convert.ToInt32(de.Properties["userAccountControl"][0]);
            const int ADS_LOCKOUT = 0x00000010;
            bool account_LockedOut = (uc & ADS_LOCKOUT)==ADS_LOCKOUT;
            Library.WriteErrorLog("IsAccountLockedOut : "+account_LockedOut);                                       
        }
    }
}

我也试过

(places:[AnyObject], error: NSError) -> Void

WriteErrorLog(string abc)将abc写入文本文件It gives false even if the account is Locked

user1 is Locked

如果我能够获得有关此问题的指导,我将非常感激,因为我是Active Directory的新手。 在此先感谢!

2 个答案:

答案 0 :(得分:1)

您必须拥有有效的网络凭据才能查询Active Directory。

当服务作为本地服务运行时,它没有网络凭据 - 它只能在本地系统上运行。如果需要网络凭据,请将服务配置为以网络服务的形式运行。 (如果您需要本地计算机上的管理员访问权限,请使用本地系统;这具有网络凭据和本地管理员访问权限。)

作为网络服务或本地系统运行的服务在访问网络时使用计算机的Active Directory帐户,即,如果计算机名为PLUGH,则用于访问网络的用户名为{{1 }}

答案 1 :(得分:0)

我发现当 UserPrincipal 对象用于获取帐户的锁定状态时,整个LDAP路径直到用户所在的组织单位(OU)应该作为PrincipalContext的参数以及管理员登录名和密码提供。

例如:

using (var context = new PrincipalContext(ContextType.Domain, "TRY.local"))
{
    using (var searcher = new PrincipalSearcher(new UserPrincipal(context)))
    {
        foreach (var result in searcher.FindAll())
        {
            DirectoryEntry de = result.GetUnderlyingObject() as DirectoryEntry;
            string path = de.Path;
            var offset = path.IndexOf('/');
            offset = path.IndexOf('/', offset+1);
            offset = path.IndexOf('/', offset+1);
            path = path.Substring(offset+1);
            string user_id = Convert.ToString(de.Properties["samaccountname"].Value); 

            PrincipalContext ctx = new PrincipalContext(ContextType.Domain,
                                       "TRY.local",
                                       path,
                                       "administrator",
                                       "password");

要使用UserPrincipal,我们现在将ctx和user_id作为参数传递给UserPrincipal.FindByIdentity(PrincipalContext,string)方法。

字符串路径最终将包含:“CN = User,OU = USERS,OU = DEPARTMENT,DC = SERVER,DC = COM”

UserPrincipal user_locked = UserPrincipal.FindByIdentity(ctx, username);
if (user_locked != null) {
    if (user_locked.IsAccountLockedOut()){
       user_locked.UnlockAccount();                                         
    }
    user_locked.Dispose();
    Console.WriteLine("Unlocked");
}
ctx.Dispose();