PowerShell AD Password Policy: View and Configure Settings

Security auditors ask one question every quarter: what is the current PowerShell Active Directory password policy configuration for your domain? The answer should take seconds, not a trip through Group Policy Management Console. PowerShell retrieves the default domain policy and any fine-grained password policies in one pipeline, and it can create new policies and assign them to groups without any GUI work.
Quick Answer / TL;DR
Run Get-ADDefaultDomainPasswordPolicy to see the domain password policy. Use Get-ADFineGrainedPasswordPolicy -Filter * to list any fine-grained policies.
Get Default Domain Password Policy
Every Active Directory domain has a default domain password policy that applies to all users without a fine-grained policy. Get-ADDefaultDomainPasswordPolicy returns the policy as an object with clearly named properties. No arguments are needed when run from a domain-joined machine under a domain account.
# Get the default domain password policy
$policy = Get-ADDefaultDomainPasswordPolicy
$policy | Select-Object `
MinPasswordLength,
MinPasswordAge,
MaxPasswordAge,
PasswordHistoryCount,
LockoutThreshold,
LockoutDuration,
LockoutObservationWindow,
ComplexityEnabled,
ReversibleEncryptionEnabled
MinPasswordLength : 8
MinPasswordAge : 1.00:00:00
MaxPasswordAge : 42.00:00:00
PasswordHistoryCount : 24
LockoutThreshold : 5
LockoutDuration : 00:30:00
LockoutObservationWindow : 00:30:00
ComplexityEnabled : True
ReversibleEncryptionEnabled: False
View Fine-Grained Password Policies
Fine-Grained Password Policies (PSOs) allow different password requirements for different groups of users. They override the default domain policy for their target subjects. The Get-ADFineGrainedPasswordPolicy cmdlet retrieves all defined PSOs. A domain functional level of Windows Server 2008 or higher is required.
# List all fine-grained password policies
Get-ADFineGrainedPasswordPolicy -Filter * |
Select-Object Name, MinPasswordLength, MaxPasswordAge, Precedence, AppliesTo
# Get details of a specific PSO
Get-ADFineGrainedPasswordPolicy -Identity 'PSO-Admins' | Format-List *
Create a Fine-Grained PSO
Create a new PSO with New-ADFineGrainedPasswordPolicy. The Precedence value determines which PSO wins when a user is subject to multiple policies — the lower number takes precedence. All time values are TimeSpan strings or [timespan] objects.
# Create a stricter policy for admin accounts
New-ADFineGrainedPasswordPolicy `
-Name 'PSO-DomainAdmins' `
-Precedence 10 `
-MinPasswordLength 16 `
-MinPasswordAge '1.00:00:00' `
-MaxPasswordAge '30.00:00:00' `
-PasswordHistoryCount 48 `
-LockoutThreshold 3 `
-LockoutDuration '01:00:00' `
-LockoutObservationWindow '01:00:00' `
-ComplexityEnabled $true `
-ReversibleEncryptionEnabled $false
Write-Host 'PSO-DomainAdmins created successfully'
Apply PSO to a Group
PSOs are applied to security groups or individual user accounts using Add-ADFineGrainedPasswordPolicySubject. Applying to a group is the recommended approach — add users to the group to bring them under the policy, remove them to revert to the default.
# Apply PSO to a security group
Add-ADFineGrainedPasswordPolicySubject `
-Identity 'PSO-DomainAdmins' `
-Subjects 'Domain Admins'
# Also apply to a specific user
Add-ADFineGrainedPasswordPolicySubject `
-Identity 'PSO-DomainAdmins' `
-Subjects 'svc_specialaccount'
# Verify subjects
(Get-ADFineGrainedPasswordPolicy -Identity 'PSO-DomainAdmins').AppliesTo
Check Resultant PSO for a User
Get-ADUserResultantPasswordPolicy shows exactly which policy applies to a specific user, accounting for all group memberships and PSO precedence values. This is the definitive answer to “what password rules apply to user X?”
# See the effective password policy for a specific user
$effective = Get-ADUserResultantPasswordPolicy -Identity 'jsmith'
if ($effective) {
Write-Host "Effective PSO: $($effective.Name)"
Write-Host "Min Length: $($effective.MinPasswordLength)"
Write-Host "Max Age: $($effective.MaxPasswordAge)"
} else {
Write-Host 'Default domain policy applies (no PSO)'
}
Export Password Policy Settings
Export all password policy information to a report for compliance documentation. Combine the default domain policy with all PSOs into a single CSV that includes the target groups for each PSO.
$report = @()
# Default domain policy
$ddpp = Get-ADDefaultDomainPasswordPolicy
$report += [PSCustomObject]@{
PolicyName = 'Default Domain Policy'
MinLength = $ddpp.MinPasswordLength
MaxAgeDays = $ddpp.MaxPasswordAge.Days
Precedence = 'N/A (default)'
AppliesTo = 'All users without PSO'
}
# Fine-grained policies
Get-ADFineGrainedPasswordPolicy -Filter * | ForEach-Object {
$report += [PSCustomObject]@{
PolicyName = $_.Name
MinLength = $_.MinPasswordLength
MaxAgeDays = $_.MaxPasswordAge.Days
Precedence = $_.Precedence
AppliesTo = ($_.AppliesTo -join '; ')
}
}
$report | Export-Csv -Path C:\Reports\PasswordPolicies.csv -NoTypeInformation
Write-Host "Exported to C:\Reports\PasswordPolicies.csv"
Common Errors and Fixes
- Fine-Grained Policies require domain functional level 2008+. If
New-ADFineGrainedPasswordPolicythrows an error about the domain functional level, check with(Get-ADDomain).DomainMode. The domain must be atWindows2008Domainor higher. Fine-grained policies cannot be created on domains still at 2003 functional level. - PSO precedence number — lower number wins. If a user belongs to two groups with different PSOs, the PSO with the lower
Precedencevalue is applied. Assign precedence 10 to the most restrictive admin policies and progressively higher numbers to less restrictive ones. UseGet-ADUserResultantPasswordPolicyto confirm the effective policy.
Related Cmdlets / See Also
Wrapping Up
PowerShell gives you complete control over Active Directory password policies — viewing, creating, assigning, and auditing them in seconds. Use Get-ADDefaultDomainPasswordPolicy for baseline checks, Get-ADFineGrainedPasswordPolicy for PSO inventory, and Get-ADUserResultantPasswordPolicy to determine exactly which policy governs any individual user.


