Skip to content

Instantly share code, notes, and snippets.

@HumanEquivalentUnit
Last active September 21, 2018 05:18
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save HumanEquivalentUnit/3228fdca4d1965d7f29be053702eca92 to your computer and use it in GitHub Desktop.
Save HumanEquivalentUnit/3228fdca4d1965d7f29be053702eca92 to your computer and use it in GitHub Desktop.
Test AD Password Complexity v3
<#
.Synopsis
Tests a string against Active Directory default password complexity requirements
.DESCRIPTION
Checks password length, and whether it meets 3 out of 4 of the following:
- Lowercase character a-z
- Uppercase character A-Z
- Digit 0-9
- Special character !,#,-, etc.
.EXAMPLE
PS C:\> Test-PasswordComplexity -Password 'letmein'
Password IsLongEnough Complexity Result
-------- ------------ ---------- ------
letmein False 1 of 4 Fail
.EXAMPLE
PS C:\> Test-PasswordComplexity -Password 'letmein' -Quiet
False
.EXAMPLE
PS C:\> 'letmein', 'Let.Me.In' | Test-PasswordComplexity
Password IsLongEnough Complexity Result
-------- ------------ ---------- ------
letmein False 1 of 4 Fail
Let.Me.In True 3 of 4 Pass
.EXAMPLE
PS C:\> Test-PasswordComplexity 'Letmein' | Format-List -Property *
Password : Letmein
IsLongEnough : False
HasLowercase : True
HasUppercase : True
HasDigit : False
HasNonAlpha : False
IsComplexEnough : False
Result : Fail
NumCharTestsPassed : 2
Complexity : 2 of 4
.INPUTS
A string containing a possible password, or an array of them.
#>
function Test-PasswordComplexity
{
[CmdletBinding()]
Param(
[Parameter(ValueFromPipeline=$true)]
[string[]]
$Password,
[switch]
$Quiet = $false
)
begin {
$requiredPasswordLength = 9
$TypeData = @{
TypeName = 'PasswordComplexityTestResults'
DefaultDisplayPropertySet = 'Password', 'IsLongEnough', 'Complexity', 'Result'
}
Update-TypeData @TypeData -Force
}
process {
foreach ($p in $Password)
{
$testResults = [ordered]@{
PSTypeName = 'PasswordComplexityTestResults'
Password = $p
IsLongEnough = $p.Length -ge $requiredPasswordLength
HasLowercase = $p -cmatch '[a-z]'
HasUppercase = $p -cmatch '[A-Z]'
HasDigit = $p -cmatch '[0-9]'
HasNonAlpha = $p -cmatch '[^a-zA-Z0-9]'
}
if ($p.Length -lt $requiredPasswordLength)
{
$testResults.IsComplexEnough = $false
$testResults.Result = 'Fail'
}
$testResults.NumCharTestsPassed = @(
$testResults.HasLowercase, $testResults.HasUppercase, $testResults.HasDigit, $testResults.HasNonAlpha
).Where{$_}.Count
$testResults.Complexity = '{0} of 4' -f $testResults.NumCharTestsPassed
if ($testResults.NumCharTestsPassed -lt 3)
{
$testResults.IsComplexEnough = $false
$testResults.Result = 'Fail'
}
# If there was no reason to fail the password, it must be good enough
if (-not $testResults.Contains('IsComplexEnough'))
{
$testResults.IsComplexEnough = $true
$testResults.Result = 'Pass'
}
# Output just a True/False if the -Quiet switch is passed,
# or a full detailed answer
if ($Quiet)
{
$testResults.IsComplexEnough
}
else
{
[PSCustomObject]$testResults
}
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment