How to Configure Fine-Grained Password Policies on Windows Server 2012 R2

Prior to Windows Server 2008, Active Directory supported only a single password policy and account lockout policy per domain — defined in the Default Domain Policy GPO. This meant all users in the domain were subject to the same password rules regardless of their role or risk profile. Fine-Grained Password Policies (FGPP), introduced in Windows Server 2008 and fully supported in Windows Server 2012 R2, allow administrators to define multiple password and lockout policies within a single domain and apply them to specific users or security groups. This guide covers creating and applying Fine-Grained Password Policies on Windows Server 2012 R2.

Prerequisites

Fine-Grained Password Policies require the domain functional level to be Windows Server 2008 or higher. In Windows Server 2012 R2 environments, the functional level should already be at 2012 R2 for full feature access. You need Domain Admin rights to create and manage Password Settings Objects (PSOs). The ActiveDirectory module must be imported:

Import-Module ActiveDirectory

# Verify domain functional level
(Get-ADDomain).DomainMode

Understanding Password Settings Objects

Fine-Grained Password Policies are implemented through Password Settings Objects (PSOs), which are stored in the CN=Password Settings Container,CN=System,DC=domain,DC=com container. PSOs contain all the same settings as the Default Domain Policy password settings plus an additional attribute: msDS-PasswordSettingsPrecedence. This precedence value determines which PSO wins when multiple PSOs apply to a single user — lower numbers have higher priority. PSOs can be applied directly to user accounts or to global security groups.

Creating a Fine-Grained Password Policy

Use the New-ADFineGrainedPasswordPolicy cmdlet to create PSOs. The following example creates policies for different user categories:

# Create a strict policy for privileged/admin accounts
New-ADFineGrainedPasswordPolicy `
    -Name "PSO-AdminAccounts" `
    -Precedence 1 `
    -MinPasswordLength 16 `
    -PasswordHistoryCount 24 `
    -MinPasswordAge (New-TimeSpan -Days 1) `
    -MaxPasswordAge (New-TimeSpan -Days 30) `
    -ComplexityEnabled $true `
    -ReversibleEncryptionEnabled $false `
    -LockoutDuration (New-TimeSpan -Minutes 30) `
    -LockoutObservationWindow (New-TimeSpan -Minutes 30) `
    -LockoutThreshold 3 `
    -Description "Strict policy for domain and enterprise administrators"
# Create a standard policy for regular users
New-ADFineGrainedPasswordPolicy `
    -Name "PSO-StandardUsers" `
    -Precedence 10 `
    -MinPasswordLength 12 `
    -PasswordHistoryCount 12 `
    -MinPasswordAge (New-TimeSpan -Days 1) `
    -MaxPasswordAge (New-TimeSpan -Days 90) `
    -ComplexityEnabled $true `
    -ReversibleEncryptionEnabled $false `
    -LockoutDuration (New-TimeSpan -Minutes 15) `
    -LockoutObservationWindow (New-TimeSpan -Minutes 15) `
    -LockoutThreshold 5 `
    -Description "Standard policy for regular domain users"
# Create a policy for service accounts (long passwords, no expiry)
New-ADFineGrainedPasswordPolicy `
    -Name "PSO-ServiceAccounts" `
    -Precedence 5 `
    -MinPasswordLength 20 `
    -PasswordHistoryCount 24 `
    -MinPasswordAge (New-TimeSpan -Days 0) `
    -MaxPasswordAge (New-TimeSpan -Days 0) `
    -ComplexityEnabled $true `
    -ReversibleEncryptionEnabled $false `
    -LockoutDuration (New-TimeSpan -Hours 0) `
    -LockoutObservationWindow (New-TimeSpan -Minutes 30) `
    -LockoutThreshold 0 `
    -Description "Policy for managed service accounts (no expiry, no lockout)"

Applying PSOs to Users and Groups

PSOs are most efficiently applied to security groups. This allows you to manage PSO application by managing group membership rather than individual user accounts:

# Create security groups for each policy tier
New-ADGroup -Name "PSO-Admins-Group" `
    -GroupScope Global -GroupCategory Security `
    -Path "OU=Groups,OU=Contoso,DC=contoso,DC=com"

New-ADGroup -Name "PSO-ServiceAcct-Group" `
    -GroupScope Global -GroupCategory Security `
    -Path "OU=Groups,OU=Contoso,DC=contoso,DC=com"

# Add accounts to the groups
Add-ADGroupMember -Identity "PSO-Admins-Group" `
    -Members @("Administrator","jadmin","bwilliams-admin")

Add-ADGroupMember -Identity "PSO-ServiceAcct-Group" `
    -Members @("svc-sql","svc-iis","svc-backup")
# Apply PSOs to groups
Add-ADFineGrainedPasswordPolicySubject `
    -Identity "PSO-AdminAccounts" `
    -Subjects "PSO-Admins-Group"

Add-ADFineGrainedPasswordPolicySubject `
    -Identity "PSO-ServiceAccounts" `
    -Subjects "PSO-ServiceAcct-Group"

# Apply PSO directly to a specific user (higher priority wins if multiple PSOs apply)
Add-ADFineGrainedPasswordPolicySubject `
    -Identity "PSO-AdminAccounts" `
    -Subjects "jadmin"

Viewing Resultant PSO for a User

The Resultant PSO (RPSO) is the single PSO that actually applies to a user after precedence resolution. If a user belongs to multiple groups with different PSOs, the PSO with the lowest precedence number applies:

# Get the resultant PSO for a specific user
Get-ADUserResultantPasswordPolicy -Identity "jadmin"

# View all PSOs that apply to a user (including via group membership)
Get-ADFineGrainedPasswordPolicySubject -Identity "PSO-AdminAccounts"

# List all PSOs in the domain
Get-ADFineGrainedPasswordPolicy -Filter * |
    Select-Object Name, Precedence, MinPasswordLength, MaxPasswordAge,
    LockoutThreshold, LockoutDuration

Modifying an Existing PSO

# Update minimum password length on an existing PSO
Set-ADFineGrainedPasswordPolicy -Identity "PSO-StandardUsers" `
    -MinPasswordLength 14 `
    -MaxPasswordAge (New-TimeSpan -Days 60)

# Increase lockout threshold
Set-ADFineGrainedPasswordPolicy -Identity "PSO-StandardUsers" `
    -LockoutThreshold 10

Removing PSO Subjects and Deleting PSOs

# Remove a group from a PSO
Remove-ADFineGrainedPasswordPolicySubject `
    -Identity "PSO-AdminAccounts" `
    -Subjects "PSO-Admins-Group" `
    -Confirm:$false

# Delete a PSO
Remove-ADFineGrainedPasswordPolicy -Identity "PSO-AdminAccounts" -Confirm:$false

Auditing and Reporting PSO Configuration

# Generate a report of all PSOs and their subjects
Get-ADFineGrainedPasswordPolicy -Filter * | ForEach-Object {
    $pso = $_
    $subjects = Get-ADFineGrainedPasswordPolicySubject -Identity $pso.Name
    [PSCustomObject]@{
        PSO = $pso.Name
        Precedence = $pso.Precedence
        MinLength = $pso.MinPasswordLength
        MaxAge = $pso.MaxPasswordAge.Days
        LockoutThreshold = $pso.LockoutThreshold
        Subjects = ($subjects | Select-Object -ExpandProperty Name) -join ", "
    }
} | Format-Table -AutoSize

Verifying Policy Application

# Verify a user's effective password policy
$user = Get-ADUser -Identity "jadmin" -Properties msDS-ResultantPSO
if ($user.'msDS-ResultantPSO') {
    $pso = Get-ADObject $user.'msDS-ResultantPSO' -Properties *
    Write-Host "Resultant PSO: $($pso.Name)"
    Write-Host "Min Length: $($pso.'msDS-PasswordComplexityEnabled')"
} else {
    Write-Host "No FGPP applied — using Default Domain Policy"
}

Summary

Fine-Grained Password Policies on Windows Server 2012 R2 enable granular control over password and lockout settings at the user and group level within a single domain. PSOs replace the need to create separate domains solely to enforce different password policies. Best practices include applying PSOs to security groups rather than individual users, assigning clear precedence values, and creating distinct policies for privileged accounts, standard users, and service accounts. Regular auditing of PSO assignments ensures the intended policies are in effect for all user categories.