Password complexity checker
Password complexity checker

If you have enabled in your domain group policy the password complexity (see below), users will probably have some troubles to find the right password that meet these requirements.
passcompgpo

The complexity requirements are explained in the “Explain” tab of the policy :

This security setting determines whether passwords must meet complexity requirements.

If this policy is enabled, passwords must meet the following minimum requirements:

Not contain the user’s account name or parts of the user’s full name that exceed two consecutive characters
Be at least six characters in length
Contain characters from three of the following four categories:
English uppercase characters (A through Z)
English lowercase characters (a through z)
Base 10 digits (0 through 9)
Non-alphabetic characters (for example, !, $, #, %)
Complexity requirements are enforced when passwords are changed or created.

For me, the first rule was not clear. I have found a better explanation on this site :

Passwords must not contain the user’s entire samAccountName (Account Name) value or entire displayName (Full Name) value. Both checks are not case sensitive:

The samAccountName is checked in its entirety only to determine whether it is part of the password. If the samAccountName is less than three characters long, this check is skipped.

The displayName is parsed for delimiters: commas, periods, dashes or hyphens, underscores, spaces, pound signs, and tabs. If any of these delimiters are found, the displayName is split and all parsed sections (tokens) are confirmed not to be included in the password. Tokens that are less than three characters in length are ignored, and substrings of the tokens are not checked. For example, the name “Erin M. Hagens” is split into three tokens: “Erin,” “M,” and “Hagens.” Because the second token is only one character long, it is ignored. Therefore, this user could not have a password that included either “erin” or “hagens” as a substring anywhere in the password.

I have written the following script to help users to check the password with the requirements described above.

  • The script checks first the samaccountname and the displayname of the user that runs the script using the cmdlet GetAD-User.
  • After that the complexity requirements are checked.
  • Finally, the script gives the reason why the password is valid or not.
function testuser($psw,$usr) {
	$sam_match = 1
	if (($usr.length -ge 3) -and ($psw -match $usr)){
		$sam_match = 0
	}
	return $sam_match
}

function testdsn($psw,$dsn) {
	$dsnparts = @()
	$dsnparts_match = @()
	$dsnparts += $dsn.split(" ,.-_	")| % { if (($_ -notmatch " ") -and ($_) -and ($_.length -ge 3)) { $_ } }
	$dsnparts | % { 
		if ($psw -match $_) { 
			$dsnparts_match += $_ 
		} 
	}
	return $dsnparts_match
}

function passchars($psw) {
	$upper_chrs = '[A-Z]'
	$lower_chrs = '[a-z]'
	$num_chrs = '[0-9]'
	
	$result = 0
	
	if ($psw -cmatch $upper_chrs) {
		$result += 1
	}
	if ($psw -cmatch $lower_chrs) {
		$result += 2
	}
	if ($psw -match $num_chrs) {
		$result += 4
	}
	if ($psw -notmatch '^[a-zA-Z0-9\s]+$'){
		$result += 8
	}

	return $result
}

$username = [Environment]::UserName
$strFilter = "(&(objectCategory=User)(samAccountName=$username))"

$objSearcher = New-Object System.DirectoryServices.DirectorySearcher
$objSearcher.Filter = $strFilter

$objPath = $objSearcher.FindOne()
$objUser = $objPath.GetDirectoryEntry()

$displayname = $objUser.displayname

Write-Host "`n----------------------------------"
Write-Host "Windows Password Complexity Tester"
Write-Host "----------------------------------`n"

Write-Host "--------"
Write-Host "REMINDER"
Write-Host "--------"
Write-Host "If the policy `"Password must meet complexity requirements`" is enabled, passwords must meet the following minimum requirements:
`t- Not contain the user's account name or parts of the user's full name that exceed two consecutive characters
`t- Be at least six characters in length
`n`tContain characters from three of the following four categories:
`t`t- English uppercase characters (A through Z)
`t`t- English lowercase characters (a through z)
`t`t- Base 10 digits (0 through 9)
`t`t- Non-alphabetic characters (for example, !, $, #, %)`n`n"

Write-Host "My username (samaccountname) : $username"
Write-Host "My display name (displayname) : $displayname"

Write-Host "`nEnter a password to validate`n"

$password = read-host

$j = testuser $password $username

$output_dsn = testdsn $password $displayname
if ($output_dsn) {$k = 0} else {$k = 1}

$output_chars = passchars $password

if ($password.length -lt 6) {
	$l = 0
}
else {
	$l = 1
}

$i=0
@(1,2,4,8) | % { if ($output_chars -band $_) { $i +=1 }  }

if ( ($i -ge 3) -and ($j -eq 1) -and ($k -eq 1) -and ($l -eq 1)) {
	Write-Host -foreground Green "The password is valid and meet the following complexity requirements:"
	if ($j -eq 1 ) {Write-Host -ForegroundColor green "The password does not contain the samaccountname : $username"}
	if ($k -eq 1 ) {Write-Host -ForegroundColor green "The password does not contain any parts of the display name : $displayname" }
	if ($l -eq 1 ) {Write-Host -ForegroundColor green "The password contains" $password.length "characters in length"}
	if ($output_chars -band 1) { Write-Host -ForegroundColor green "The password contains English uppercase characters (A through Z)" }
	if ($output_chars -band 2) { Write-Host -ForegroundColor green "The password contains English lowercase characters (a through z)" }
	if ($output_chars -band 4) { Write-Host -ForegroundColor green "The password contains Base 10 digits (0 through 9)" }
	if ($output_chars -band 8) { Write-Host -ForegroundColor green "The password contains Non-alphabetic characters (for example, !, $, #, %)" }
}
else {
	Write-Host -ForegroundColor Red "The password does not meet the complexity requirements:`n"
	if ($i -lt 3 ) {
		if ((15 -bxor $output_chars) -band 1) { Write-Host -ForegroundColor Red "The password must contain English uppercase characters (A through Z)" }
		if ((15 -bxor $output_chars) -band 2) { Write-Host -ForegroundColor Red "The password must contain English lowercase characters (a through z)" }
		if ((15 -bxor $output_chars) -band 4) { Write-Host -ForegroundColor Red "The password must contain Base 10 digits (0 through 9)" }
		if ((15 -bxor $output_chars) -band 8) { Write-Host -ForegroundColor Red "The password must contain Non-alphabetic characters (for example, !, $, #, %)" }
	}
	if ($j -eq 0 ) {Write-Host -ForegroundColor Red "The password contains the samaccountname ($username)"}
	if ($k -eq 0 ) {$output_dsn | % { Write-Host -ForegroundColor Red "The password contains this part of the display name : $_" }}
	if ($l -eq 0 ) {Write-Host -ForegroundColor Red "The password must contain, at least, six characters"}
}

$password = ""

Output

outputcomp1

outputcomp2

Do not hesitate to leave a comment if you have any questions

<>

Password complexity checker

Leave a Reply

Your email address will not be published. Required fields are marked *