14

我搜索了该站点的信息并发现了这一点: ASP.NET C# Active Directory - See how long before a user's password expires

它解释了如何根据域策略获取密码过期时间的值。

我的问题是:如果用户的 OU 组策略具有不同的 MaxPasswordAge 值,覆盖域组策略中指定的值怎么办?如何以编程方式获取 OU 的组策略对象?

编辑:为了让这个问题更清楚一点,我添加了这个编辑。我所追求的是能够判断用户密码何时过期。据我了解,日期值可以由域本地策略或组对象策略管理。我有一个将 Linq 转换为 Ldap 查询的 Linq2DirectoryService 提供程序。因此,获取日期到期值的 LDAP 查询对于这个主题是最佳的。如果您的回答包括.net 支持的对象包装器包含在此等式中 - 这将是一个死答案!

4

4 回答 4

15

让我从包含 Visual Basic 和 VBScript 示例的http://support.microsoft.com/kb/323750和http://www.anitkb.com/2010/03/how-to-implement-active-directory.html开始其中概述了 maxPwdAge OU 设置如何影响计算机,而不是用户。它还有一条评论指出AloInfo.exe作为 MS 的工具,可用于获取密码年龄。

这是示例:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.DirectoryServices;

namespace LDAP
{
    class Program
    {
        static void Main(string[] args)
        {
            string domainAndUsername = string.Empty;
            string domain = string.Empty;
            string userName = string.Empty;
            string passWord = string.Empty;
            AuthenticationTypes at = AuthenticationTypes.Anonymous;
            StringBuilder sb = new StringBuilder();

            domain = @"LDAP://w.x.y.z";
            domainAndUsername = @"LDAP://w.x.y.z/cn=Lawrence E."+
                        " Smithmier\, Jr.,cn=Users,dc=corp,"+
                        "dc=productiveedge,dc=com";
            userName = "Administrator";
            passWord = "xxxpasswordxxx";
            at = AuthenticationTypes.Secure;

            DirectoryEntry entry = new DirectoryEntry(
                        domain, userName, passWord, at);

            DirectorySearcher mySearcher = new DirectorySearcher(entry);

            SearchResultCollection results;
            string filter = "maxPwdAge=*";
            mySearcher.Filter = filter;

            results = mySearcher.FindAll();
            long maxDays = 0;
            if(results.Count>=1)
            {
                Int64 maxPwdAge=(Int64)results[0].Properties["maxPwdAge"][0];
                maxDays = maxPwdAge/-864000000000;
            }

            DirectoryEntry entryUser = new DirectoryEntry(
                        domainAndUsername, userName, passWord, at);
            mySearcher = new DirectorySearcher(entryUser);

            results = mySearcher.FindAll();
            long daysLeft=0;
            if (results.Count >= 1)
            {
                var lastChanged = results[0].Properties["pwdLastSet"][0];
                daysLeft = maxDays - DateTime.Today.Subtract(
                        DateTime.FromFileTime((long)lastChanged)).Days;
            }
            Console.WriteLine(
                        String.Format("You must change your password within"+
                                      " {0} days"
                                     , daysLeft));
            Console.ReadLine();
        }
    }
}
于 2010-11-15T04:47:33.843 回答
11

以下代码对我有用,可以获取域和本地用户帐户的密码到期日期:

public static DateTime GetPasswordExpirationDate(string userId, string domainOrMachineName)
{
    using (var userEntry = new DirectoryEntry("WinNT://" + domainOrMachineName + '/' + userId + ",user"))
    {
        return (DateTime)userEntry.InvokeGet("PasswordExpirationDate");
    }
}
于 2011-07-20T08:41:33.747 回答
4

使用以下方法获取帐户的到期日期-

public static DateTime GetPasswordExpirationDate(string userId)
    {
        string forestGc = String.Format("GC://{0}", Forest.GetCurrentForest().Name);
        var searcher = new DirectorySearcher();
        searcher = new DirectorySearcher(new DirectoryEntry(forestGc));
        searcher.Filter = "(sAMAccountName=" + userId + ")";
        var results = searcher.FindOne().GetDirectoryEntry();
        return (DateTime)results.InvokeGet("PasswordExpirationDate");
    }
于 2017-07-12T11:19:59.567 回答
1

以前的一些答案依赖于 DirectoryEntry.InvokeGet 方法,MS 说不应该使用该方法。所以这是另一种方法:

public static DateTime GetPasswordExpirationDate(UserPrincipal user)
{
    DirectoryEntry deUser = (DirectoryEntry)user.GetUnderlyingObject();
    ActiveDs.IADsUser nativeDeUser = (ActiveDs.IADsUser)deUser.NativeObject;
    return nativeDeUser.PasswordExpirationDate;
}

您需要添加对通常位于 C:\Windows\System32\activeds.tlb 的 ActiveDS COM 库的引用。

于 2018-05-16T14:23:31.977 回答