简体   繁体   English

Active Directory用户密码到期日期.NET / OU组策略

[英]Active Directory user password expiration date .NET/OU Group Policy

I have searched the site for information and found this: ASP.NET C# Active Directory - See how long before a user's password expires 我搜索了该站点以获取信息,并发现: ASP.NET C#Active Directory - 查看用户密码到期之前的时间

which explains how to get the value of when the password expires as per Domain Policy. 它解释了如何根据域策略获取密码何时到期的值。

My question is this: what if the user has an OU Group Policy that has a different MaxPasswordAge value, overriding the one specified in Domain Group Policy? 我的问题是:如果用户的OU组策略具有不同的MaxPasswordAge值,覆盖域组策略中指定的值,该怎么办? How to programatically get the OU's Group Policy Object? 如何以编程方式获取OU的组策略对象?

Edit: To make this question a little bit more clear, I am adding this edit. 编辑:为了使这个问题更加清晰,我正在添加此编辑。 What I am after is to being able to tell when user's password expires. 我所追求的是能够告诉用户的密码何时到期。 As far as I understand that date value can either be governed by domains local policy or by group object policy. 据我所知,日期值可以由域本地策略或组对象策略控制。 I have a Linq2DirectoryService Provider that translates Linq to Ldap queries. 我有一个Linq2DirectoryService Provider,它将Linq转换为Ldap查询。 So an LDAP query to get the date expiration value would be optimal for this subj. 因此,获取日期到期值的LDAP查询对于此subj将是最佳的。 If you answer includes what objects wrappers supported by .net are included into this equation - it would be a dead on answer! 如果你回答包括.net所支持的对象包装器被包含在这个等式中 - 它将是一个死的答案!

Let me start with http://support.microsoft.com/kb/323750 which contains Visual Basic and VBScript examples and http://www.anitkb.com/2010/03/how-to-implement-active-directory.html which outlines how the maxPwdAge OU setting impacts computers, not users. 让我从http://support.microsoft.com/kb/323750开始,其中包含Visual Basic和VBScript示例以及http://www.anitkb.com/2010/03/how-to-implement-active-directory.html其中概述了maxPwdAge OU设置如何影响计算机,而不是用户。 It also has a comment pointing to AloInfo.exe as a tool from MS that can be used to get password ages. 它还有一个注释,指向AloInfo.exe作为MS的工具,可用于获取密码年龄。

Here is the example: 这是一个例子:

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();
        }
    }
}

The following code worked for me to get the password expiration date on both domain and local user accounts: 以下代码可以帮助我获取域和本地用户帐户的密码到期日期:

public static DateTime GetPasswordExpirationDate(string userId, string domainOrMachineName)
{
    using (var userEntry = new DirectoryEntry("WinNT://" + domainOrMachineName + '/' + userId + ",user"))
    {
        return (DateTime)userEntry.InvokeGet("PasswordExpirationDate");
    }
}

Use following method to get expiration date of the account- 使用以下方法获取帐户的到期日期 -

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");
    }

Some of the previous answers rely on the DirectoryEntry.InvokeGet method, which MS says should not be used . 以前的一些答案依赖于DirectoryEntry.InvokeGet方法, MS说不应该使用它 So here's another approach: 所以这是另一种方法:

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

You'll need to add a reference to the ActiveDS COM library typically found at C:\\Windows\\System32\\activeds.tlb. 您需要添加对通常位于C:\\ Windows \\ System32 \\ activeds.tlb中的ActiveDS COM库的引用。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM