LDAP Query for expiring passwords

Posted on 2009-05-03
Last Modified: 2013-12-24
I am trying to find an LDAP query that tells me which users passwords are going to expire (within 3-4 days) in a particular group.

Can anybody help?
Question by:FphcareEnginner

Expert Comment

ID: 24292494
A simple DS Query will do, enter the below in command prompt on the dc.
dsquery user -stalepwd n

Author Comment

ID: 24292505

I can successfully use this command but want to query only members of a specific group. Could not get it right with DS query and thought an LDAP query would be better.

Can this be done with DS query?

Expert Comment

ID: 24292512
There are far more efficient tools than DS Query that allow for more filters. Take a look at this site, you will have to download the utility, but this is probalbly what you are looking for, it will allow the query of specific OU's.
Maximize Your Threat Intelligence Reporting

Reporting is one of the most important and least talked about aspects of a world-class threat intelligence program. Here’s how to do it right.


Author Comment

ID: 24292535
Thanks, unfortunately due to some internal legal reasons, we cannot use any 3rd party tools and want to try proceed with an LDAP query.

Expert Comment

ID: 24292548
Understood~ Well, then you will have to get into some C-Sharp programming or vbscripting.
LVL 57

Expert Comment

by:Mike Kline
ID: 24292876
To bad you can't use joe's tools... the are great
The ldap query is a pain because of how accountexpires is stored
The date when the account expires. This value represents the number of 100 nanosecond intervals since January 1, 1601 (UTC). A value of 0 or 0x7FFFFFFFFFFFFFFF (9223372036854775807) indicates that the account never expires.
So lets say you wanted an LDAP query for users that were going to expire before May 7th, 2009.  The users are in a group called test
In ADUC custom search advanced the query would be
I had to use a program to convert the "friendly" dayte of May 7th to that 64 bit integer.
That is why Valley suggested a script if you can't use a tool but just wanted to give some more info.
LVL 12

Accepted Solution

Krys_K earned 250 total points
ID: 24300822
Hi There
I have written a script that should do something like what you are looking for.
See how you get on with it.
Note: Copy it to notepad and save as a .vbs file. Change the GroupName  to suit (should be line 32 in the script).
Then run the script in a CMD.exe window as:
cscript.exe scriptname.vbs
Hope it helps

Option Explicit

	Call PwdExpiryInfo

Sub PwdExpiryInfo()

' Version 1.0

' Writen by Krystian Karia

' Dated 04/05/2009

' Gets a list of users from the group

' specified  and  then  checks  their

' Password Expiry date.

' NOTE: Script must be run in a CMD.exe

' window as: CScript.exe ScriptName.vbs

' This is due to the number of outputs

' that is created.

' Catch errors ourselves

' 	On Error Resume Next

' Declare Variables

	dim iTimeInterval, iMaxPwdAge

	Dim i, intUACvalue

	Dim dtmPwdChanged

	Dim objUserLDAP

	Dim arrMembers


	Const sGroup = "CN=My Group Name,OU=Groups,DC=Domain,DC=local"	' < Spcify your group name here

' Get the list of users from the given group

	arrMembers = GetMembers(sGroup)

		If IsNull(arrMembers) Then

			ShowProgress "Check your group name or its member list"


		End If


' Loop each user to check password exiry date

	For i = 0 to UBound(arrMembers)

		If arrMembers(i) <> "" Then

			ShowProgress ""

			Set objUserLDAP = GetObject(arrMembers(i))

				intUACvalue = objUserLDAP.Get("userAccountControl")



				ShowProgress objUserLDAP.sAMAccountName

				ShowProgress " Password does not expire"


				dtmPwdChanged = objUserLDAP.PasswordLastChanged 

				iTimeInterval = CInt(Now - dtmPwdChanged)

				iMaxPwdAge = GetMaxPwdAge



					ShowProgress objUserLDAP.sAMAccountName 

					ShowProgress " Password was last changed " & dtmPwdChanged

					ShowProgress " Which was " & iTimeInterval & " days ago"

				If iMaxPwdAge < 0 Then

					ShowProgress " Password does not expire (Domain Policy's Maximum Password Age set to 0)"


					ShowProgress " The Domain Policy Max Password Age is " & iMaxPwdAge & " Days"


					If iTimeInterval >= iMaxPwdAge Then

						ShowProgress " The password has expired."


						ShowProgress " The password will expire in " & CInt((dtmPwdChanged + iMaxPwdAge) - Now()) & " Days"

					End If


				End If 'iMaxPwdAge

			End If 'intUACvalue

		End If 

	Next ' arrMembers

End Sub ' PwdExpiryInfo

Function GetMembers(strGroup)

' Version 1.4

' Written by Krystian Karia

' Dated 04/05/2009

' Returns the LDAP path of each

' user from the given group

' Catch errors ourselves

 	On Error Resume Next

' Declare variables

    Dim oGroup, oUser

    Dim strName

    Dim arrUsers


' Check parameters

	    If strGroup = "" Then

			GetMembers = Null

	        Exit Function

	    End If

' Bind to group using the correct ADSI connector

    Set oGroup = GetObject("LDAP://" & strGroup)

		If Err.Number <> 0 Then


			ShowProgress "An error occured binding to the group " & strGroup

			GetMembers = Null

        	Exit Function

		End If

' Loop group members

		For Each oUser In oGroup.Members

	        strName = strName & oUser.ADsPath & vbNewLine


' Create an array of members

		If Trim(strName) <> "" Then

			arrUsers = Split(strName, vbNewLine)

			GetMembers = arrUsers


			GetMembers = Null

		End If


 End Function ' GetMembers

Function GetMaxPwdAge()

' Version 1.0

' Returns the Maximum Password Age

' which is usually  set in the GPO

' named "Default Domain Policy"

' Catch errors ourselves

 	On Error Resume Next

' Declare Variables

	Dim oRootDSE, oDomain, oMaxPwdAge

	Dim lngHighPart, lngLowPart

	Dim strDomainDN

' Get the current Domain DN

	Set oRootDSE = GetObject("LDAP://RootDSE")

		strDomainDN = oRootDSE.Get("DefaultNamingContext")

' Bind to current Domain

	Set oDomain = GetObject("LDAP://" & strDomainDN)

		Set oMaxPwdAge = oDomain.MaxPwdAge

' Get the 2 parts of the Integer8 value to get 2 32 bit values

	lngHighPart = oMaxPwdAge.HighPart

	lngLowPart = oMaxPwdAge.LowPart

' If the LowPart is less than 0 then we ned to add 1 to the HighPart

		If (lngLowPart < 0) Then

			lngHighPart = lngHighPart + 1

		End If


' Return the value in Days

		GetMaxPwdAge = -((lngHighPart * 2^32) + lngLowPart)/(600000000 * 1440)

End Function ' GetMaxPwdAge

Sub ShowProgress(sComment)

	WScript.Echo sComment

End Sub

Sub EndScript



End Sub

Open in new window


Featured Post

Do You Know the 4 Main Threat Actor Types?

Do you know the main threat actor types? Most attackers fall into one of four categories, each with their own favored tactics, techniques, and procedures.

Join & Write a Comment

Entity Framework is a powerful tool to help you interact with the DataBase but still doesn't help much when we have a Stored Procedure that returns more than one resultset. The solution takes some of out-of-the-box thinking; read on!
SQL Command Tool comes with APEX under SQL Workshop. It helps us to make changes on the database directly using a graphical user interface. This helps us writing any SQL/ PLSQL queries and execute it on the database and we can create any database ob…
This tutorial will walk an individual through the process of configuring their Windows Server 2012 domain controller to synchronize its time with a trusted, external resource. Use Google, Bing, or other preferred search engine to locate trusted NTP …
Polish reports in Access so they look terrific. Take yourself to another level. Equations, Back Color, Alternate Back Color. Write easy VBA Code. Tighten space to use less pages. Launch report from a menu, considering criteria only when it is filled…

706 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question

Need Help in Real-Time?

Connect with top rated Experts

12 Experts available now in Live!

Get 1:1 Help Now