January 9th, 2014

Use PowerShell to Get Account Lockout and Password Policy

Doctor Scripto
Scripter

Summary: Microsoft guest blogger and PFE, Ian Farr, talks about using Windows PowerShell to get account lockout and password policies.

Microsoft Scripting Guy, Ed Wilson, is here. Welcome back guest blogger, Ian Farr. Ian is a Microsoft PFE in the UK.

Recently, I was asked how to retrieve a domain’s Account Lockout Policy and Password Policy with Windows PowerShell. Both are stored as attributes on each domain’s Domain Naming Context. In fact, when you update these policies with the Group Policy Management Console, it is the role of the domain’s PDC emulator to write the changes to the header of the domain naming context.

This function reads policy information from a domain header: Get-ADDomainAccountPolicies.

Account Lockout Policy

Here’s how to get the Account Lockout Policy settings. First, connect to the RootDSE of a domain controller:

$RootDSE = Get-ADRootDSE -Server $Domain

Use Get-ADObject to retrieve properties from the domain naming context (defaultNamingContext):

$AccountPolicy = Get-ADObject $RootDSE.defaultNamingContext -Property lockoutDuration, lockoutObservationWindow, lockoutThreshold 

Next, produce a customized output representing the policy.

     $AccountPolicy | Select @{n="PolicyType";e={"Account Lockout"}},`

                            DistinguishedName,`

                            @{n="lockoutDuration";e={"$($_.lockoutDuration / -600000000) minutes"}},`

                            @{n="lockoutObservationWindow";e={"$($_.lockoutObservationWindow / -600000000) minutes"}},`

                            lockoutThreshold | Format-List

 Select-Object displays some standard properties: DistinguishedName and LockoutThreshold. It also displays some custom properties constructed with the aid of two hash tables. Let’s look at the format of the lockout duration value: 

@{n="lockoutDuration";e={"$($_.lockoutDuration / -600000000) minutes"}}

  • @{} denotes the hash table, which contains one or more key-value pairs
  • n is the name of the property to be stored, and its value is lockoutDuration
  • e is the expression that Windows PowerShell evaluates, and that value is…

What’s the expression doing? The LockoutDuration property of the current object  $_ is a negative 64-bit time value interval expressed in nanoseconds. This is divided by -600000000 to give a positive value in minutes. This calculation is performed as part of a subexpression, which is recognized by this notation: ‘$( )’. The code in brackets is calculated first. The returned value is then added to a string where minutes is appended and stored as the value associated with e.

We now have a hash table with two elements, n and e, that Select-Object recognizes and formats into a display property to the console screen. The previous process also applies to the LockoutObservationWindow value.

Here’s some sample output:

Image of command output

Password Policy

Again, use Get-ADObject to retrieve properties from the domain naming context:

$PasswordPolicy = Get-ADObject $RootDSE.defaultNamingContext -Property minPwdAge, maxPwdAge, minPwdLength, pwdHistoryLength, pwdProperties 

Next, produce a customized output that represents the policy:

     $PasswordPolicy | Select @{n="PolicyType";e={"Password"}},`

                              DistinguishedName,`

                              @{n="minPwdAge";e={"$($_.minPwdAge / -864000000000) days"}},`

                              @{n="maxPwdAge";e={"$($_.maxPwdAge / -864000000000) days"}},`

                              minPwdLength,`

                              pwdHistoryLength,`

                              @{n="pwdProperties";e={Switch ($_.pwdProperties) {

                                  0 {"Passwords can be simple and the administrator account cannot be locked out"}

                                  1 {"Passwords must be complex and the administrator account cannot be locked out"}

                                  8 {"Passwords can be simple, and the administrator account can be locked out"}

                                  9 {"Passwords must be complex, and the administrator account can be locked out"}

                                  Default {$_.pwdProperties}}}}

We’re doing similar stuff here with the hash tables, except that we calculate days, not minutes, from the negative nanosecond value.

For the last value returned, we’re taking $_.pwdProperties and attempting to match it to a known value by using a Switch statement. For example, if $_.pwdPropeties is 8, then the value associated with e will be "Passwords can be simple, and the administrator account can be locked out."

Here is a sample output:

Image of command output

Not the prettiest function, but certainly effective!

You can download the entire function from the Script Center Repository: Get-ADDomainAccountPolicies Function.

~Ian

Thank you, Ian, for once again sharing your time and knowledge.

I invite you to follow me on Twitter and Facebook. If you have any questions, send email to me at scripter@microsoft.com, or post your questions on the Official Scripting Guys Forum. See you tomorrow. Until then, peace.

Ed Wilson, Microsoft Scripting Guy

Author

The "Scripting Guys" is a historical title passed from scripter to scripter. The current revision has morphed into our good friend Doctor Scripto who has been with us since the very beginning.

1 comment

Discussion is closed. Login to edit/delete existing comments.

  • John Bevan

    Thanks for sharing this.
    NB: I noticed one slight ommision; you specify the domain when getting the rootdse, but not when fetching the required information from AD; so if you’re running the script on a different domain to the rootDSE’s domain, you’ll get a “cannot find an object with identity…” error

    Fix is to replace:

    $AccountPolicy = Get-ADObject $RootDSE.defaultNamingContext -Property lockoutDuration, lockoutObservationWindow, lockoutThreshold

    with:

    $AccountPolicy = Get-ADObject $RootDSE.defaultNamingContext -Property lockoutDuration, lockoutObservationWindow, lockoutThreshold -Server $Domain