This post isn’t going to set the world on fire because of it’s revelations and new features; instead, I am going to talk about a feature that has been around since Windows Server 2008 called Fine Grained Password Policies.
Active Directory Password Policies are, even in 2018, still misunderstood. For all the consulting engagements I do, I still encounter customer environments where admins have tried to configure multiple Group Policy Objects to control password policy at various levels within their OU structure. An example of this behaviour would be to set the Default Domain Policy object to a standard password complexity and then have an OU containing administrative accounts for Domain Admins which has a GPO applying a more complex policy.
Setting the Record Straight
Before we go any further then, let’s set the record straight. In a standard configuration AD domain there can be only one password policy. It matters not where or how many times you try to link and create GPOs to set different policies, it will not work. In a default AD domain, the password policy is configured in the Default Domain Policy which is applied at the root, the top-level of the domain. The password policy is enacted and controlled by the Domain Controllers not by the computer or user object of a client.
In the modern era of PowerShell, we can see that the default password policy for the domain is by using the Get-ADDefaultDomainPasswordPolicy PowerShell command which outputs similar to the screenshot below. In this example, the lockout duration and observation windows are 15 minutes each, accounts are locked out after five failed attempts and passwords must be at least seven characters long, meet complexity requirements, be no older than 90 days but more than 1 day old, and the previous 12 passwords are remembered.
Defining Granular Password Policies
Enter Windows Server 2008 R2 which brought with it a feature, as part of Active Directory, called Fine Grained Password Policies. What this new feature allows us to do, at last, it to have control over the password policy for specific users or groups. Want uber complex admin account passwords? Sure, do it. Want to force HR or Finance staff to have a slightly more complex policy than normal users but a little less than admins? Go right ahead! Now, it’s time to be honest. The feature was first introduced in Windows Server 2008, however, it got a lot easier with Windows Server 2012. In this post I will be concentrating on the latter.
To make this work, there are two things we need to do and one thing we need to understand.
- We need to create password policy objects
- We need to link password policy objects to users or groups
- We need to understand the precendence
Clearing the understanding out of the way first, we need to make sure that the correct policy is applied to the correct user or group. When we create a policy, one of the parameters required is precedence. The value for this must be a positive integer starting from 1. A user or a group can be assigned multiple policies: when this happens, the policy which wins is determined by the precedence. If a user has a direct policy linked to them with a value of 10 but they are also a member of a group which has a policy value of 5, the policy with the value of 5 will win.
Creating the Password Policy
The first real step is to create the policy. This is one, albeit long, line of PowerShell. The full list of parameters and possible values are in the Microsoft documentation at https://technet.microsoft.com/ru-ru/library/hh852234(v=wps.620).aspx. In this example, I have created a policy which backs off the default policy to allow users to keep their current password for up to 365 days.
The command executed in the example and the screenshot below:
New-ADFineGrainedPasswordPolicy -Name "MaxPassword365Days" -DisplayName "Max Password Age 365 Days" -ComplexityEnabled $true -Description "Increases the Maximum Password Age to 365 days." -LockoutDuration 00:15:00 -LockoutObservationWindow 00:15:00 -LockoutThreshold 5 -MaxPasswordAge 365:00:00:00 -MinPasswordAge 1:00:00:00 -MinPasswordLength 7 -PasswordHistoryCount 12 -ReversibleEncryptionEnabled $false -Precedence 100
With our policy now created, it won’t do anything because it isn’t linked to a user or a group so the next step is to link it. If you are testing this then by all means link it to a single user, however, in the real-world I would always use a group to allow you to be flexible and manage these policies more effectively.
To link the policy, we use the Add-ADFineGrainedPasswordPolicySubject PowerShell command. Once linked, we can use the Get-ADFineGrainedPasswordPolicy command to verify that the policy is linked.
Add-ADFineGrainedPasswordPolicySubject MaxPassword365Days -Subjects Max_Password_Age_365_Days_GG
In the example above, we can see that I used the Add-ADFineGrainedPasswordPolicySubject command. In the command we give the name of the Password Settings Object that we want to use. We then use the -Subjects parameter to declare who it should be applied to. In my case, this is a Global Group in Active Directory but this could just as easily be a user object.
Once the policy has been applied we can use the Get-ADFineGrainedPasswordPolicy to see what’s being applied. In the screenshot, we see that the MaxPassword365Days policy has an AppliesTo value of the Global Group that I set in the former command.