Recipe 6.11 Viewing the Account Lockout and Password Policies

6.11.1 Problem

You want to view the account lockout and password policies for a domain.

6.11.2 Solution Using a graphical user interface
  1. Open the Domain Security Policy snap-in.

  2. In the left menu, expand Default Domain Policy Computer Configuration Windows Settings Security Settings Account Policies.

  3. Click on Password Policy or Account Lockout Policy and double-click the property you want to set or view in the right frame. Using a command-line interface
> enumprop /ATTR:[RETURN] 
minpwdlength,pwdhistorylength,pwdproperties "LDAP://<DomainDN>" Using VBScript
' This code displays the current settings for the password 
' and account lockout policies.
strDomain = "<DomainDN>"   ' e.g.
' ------ END CONFIGURATION ---------

set objRootDSE = GetObject("LDAP://" & strDomain & "/RootDSE")
set objDomain  = GetObject("LDAP://" & _
                           objRootDSE.Get("defaultNamingContext") )

' Hash containing the domain password and lockout policy attributes
' as keys and the units (e.g. minutes) as the values 
set objDomAttrHash = CreateObject("Scripting.Dictionary")
objDomAttrHash.Add "lockoutDuration", "minutes"
objDomAttrHash.Add "lockoutThreshold", "attempts"
objDomAttrHash.Add "lockoutObservationWindow", "minutes"
objDomAttrHash.Add "maxPwdAge", "minutes"
objDomAttrHash.Add "minPwdAge", "minutes"
objDomAttrHash.Add "minPwdLength", "characters"
objDomAttrHash.Add "pwdHistoryLength", "remembered"
objDomAttrHash.Add "pwdProperties", " "

' Iterate over each attribute and print it
for each strAttr in objDomAttrHash.Keys
   if IsObject( objDomain.Get(strAttr) ) then
      set objLargeInt = objDomain.Get(strAttr)
      if objLargeInt.LowPart = 0 then
         value = 0
         value = Abs(objLargeInt.HighPart * 2^32 + objLargeInt.LowPart)
         value = int ( value / 10000000 )
         value = int ( value / 60 )
      end if
      value = objDomain.Get(strAttr)
   end if
   WScript.Echo strAttr & " = " & value & " " & objDomAttrHash(strAttr)

Set objDomPassHash = CreateObject("Scripting.Dictionary")
objDomPassHash.Add "DOMAIN_LOCKOUT_ADMINS", &h8

' The PwdProperties attribute requires special processing because 
' it is a flag that holds multiple settings.
for each strFlag In objDomPassHash.Keys
  if objDomPassHash(strFlag) and objDomain.Get("PwdProperties") then 
    WScript.Echo "  " & strFlag & " is enabled"
    WScript.Echo "  " & strFlag & " is disabled"
  end If

6.11.3 Discussion

Several parameters controlling account lockout and password complexity can be set on the Domain Security GPO. The properties that can be set for the "Account Lockout Policy" include:

Account lockout duration

Number of minutes an account will be locked before being automatically unlocked. A value of 0 indicates accounts will be locked out indefinitely, i.e., until an administrator manually unlocks them.

Account lockout threshold

Number of failed logon attempts after which an account will be locked.

Reset account lockout counter after

Number of minutes after a failed logon attempt that the failed logon counter for an account will be reset to 0.

The properties that can be set for the "Password Policy" include:

Enforce password history

Number of passwords to remember before a user can reuse a previous password.

Maximum password age

Maximum number of days a password can be used before a user must change it.

Minimum password age

Minimum number of days a password must be used before it can be changed.

Minimum password length

Minimum number of characters a password must be.

Password must meet complexity requirements

If enabled, passwords must meet all of the following criteria:

  • Not contain all or part of the user's account name

  • Be at least six characters in length

  • Contain characters from three of the following four categories:

    • English uppercase characters (A-Z)

    • English lowercase characters (a-z)

    • Base 10 digits (0-9)

    • Nonalphanumeric characters (e.g., !, $, #, %)

Store passwords using reversible encryption

If enabled, passwords are stored in such a way that they can be retrieved and decrypted. This is essentially the same as storing passwords in plain text. Using a graphical user interface

On a domain controller or machine that has adminpak.msi installed, the Domain Security Policy snap-in is present from the Start menu under Administrative Tools. On a member server, you need to open the GPO snap-in and locate the Domain Security policy. See Introduction in Chapter 9 for more information on GPOs. Using a command-line interface

There is no standard CLI that can be used to modify a GPO, but you can use enumprop to view each of the attributes on the domain object that make up the account lockout and password policy settings. Using VBScript

The VBScript solution required quite a bit of code to perform a simple task; printing out the account lockout and password policy settings. First, I created a Dictionary object with each of the six attributes as the keys and the unit's designation for each key (e.g., minutes) as the value. I then iterated over each key, printing it along with the value retrieved from the domain object.

Some additional code was necessary to distinguish between the values returned from some of the attributes. In the case of the time-based attributes, such as lockoutDuration, a IADsLargeInteger object was returned from the Get method instead of a pure integer or string value. IADsLargeInteger objects represent 64-bit, also known as Integer8, numbers. 32-bit systems, which make up the majority of systems today, have to break 64-bit numbers into two parts (a high and low part) in order to store them. Unfortunately, VBScript cannot natively handle a 64-bit number and stores it as a double precision. To convert a 64-bit number into something VBScript can handle, we have to first multiply the high part by 4,294,967,296 (2^32) and then add the low part to the result.

value = Abs(objLargeInt.HighPart * 2^32 + objLargeInt.LowPart)

Then I divided by 10,000,000 or 10^7, which represents the number of 100 nanosecond intervals per second.

value = int ( value / 10000000 )

I then used the int function to discard any remainder and finally divided the result by 60 (number of seconds).

value = int ( value / 60 )

Note that the result is only an approximation in minutes and can be off by several minutes, hours, or even days depending on the original value.

The last part of the code iterates over another Dictionary object that contains constants representing various flags that can be set as part of the pwdProperties attribute.

6.11.4 See Also

MS KB 221930 (Domain Security Policy in Windows 2000), MS KB 255550 (Configuring Account Policies in Active Directory), MSDN: IADsLargeInteger, and MSDN: DOMAIN_PASSWORD_INFORMATION

    Chapter 3. Domain Controllers, Global Catalogs, and FSMOs
    Chapter 6. Users
    Appendix A. Tool List