The script checks whether a password that is assigned to a user meets Password Complexity Requirements, has the required minimum length, and is not forbidden.
A password that meets complexity requirements cannot contain the user account name or display name, or parts of the name that exceed two consecutive characters. Also, such passwords must contain at least three of the following four items:
- English lowercase letters
- English uppercase letters
- Numerals
- Nonalphanumeric characters, such as $ ; [ ] { } ! .
You can use the script on user creation to check passwords of newly created users, for example. To do this, create a business rule that runs the script automatically before user creation. For details on how to create it, see Validate/Modify User Input Using a Script.
Parameters:
- $minLength - Specifies the minimum number of characters for a password.
- $minRequirementsToPass - Specifies the minimum number of requirements to be met for counting the password as valid.
- $requirements - Specifies the requirements for the password to be valid.
- $forbiddenPasswords - Specifies the list of passwords whose usage is forbidden.
PowerShell
$minLength = 7 # TODO: modify me
$minRequirementsToPass = 3 # TODO: modify me
$requirements = @{
[regex]"[A-Z]" = 1, "The password does not contain an upper-case character.";
[regex]"[a-z]" = 1, "The password does not contain a lower-case character.";
[regex]"[0-9]" = 1, "The password does not contain a number.";
[regex]"[^a-zA-Z0-9]" = 1, "The password does not contain a special character."
} # TODO: modify me. Example: @{ = , "Error message"}
$forbiddenPasswords = @(
'P@$$w0rd',
'$ecretW0rd'
) # TODO: modify me
if ($Context.IsPasswordChanged())
{
$password = $Context.GetNewPassword();
# Check password length
if($password.length -lt $minLength)
{
$Context.Cancel("The password does not have at least $minLength characters.")
return
}
# Check blacklist
if($forbiddenPasswords -contains $password)
{
$Context.Cancel("The password is forbidden.")
return
}
# Passwords must not contain the user's entire samAccountName (Account Name) value.
$username = "%username%".ToLower()
if ($password.ToLower().Contains($username.SubString(0,3)))
{
$Context.Cancel("The password should not contain the username or parts of it.")
return
}
# Passwords must not contain the user's entire displayName (Display Name) value
$displayName = "%displayName%"
if (!([System.String]::IsNullOrEmpty($displayName)))
{
$delimiters = @(".", ",", "-", "_", " ", "#")
$displayNameParts = $displayName.Split($delimiters)
foreach ($string in $displayNameParts)
{
if ($string.length -lt 3)
{
continue
}
if ($password.ToLower().Contains($string.ToLower()))
{
$Context.Cancel("The password should not contain the user's Display Name or parts of it.")
return
}
}
}
# Check whether the password meets at least 3 complexity requirements
$requirementsPassed = 0
$errorMessages = @()
foreach ($requirement in $requirements.Keys)
{
$minNubmerCharacters = ($requirements[$requirement])[0]
if ($requirement.Matches($password).Count -lt $minNubmerCharacters)
{
$errorMessages += ($requirements[$requirement])[1]
continue
}
$requirementsPassed++
}
# If the password does not meet the specified number of requirements, cancel operation
if ($requirementsPassed -lt $minRequirementsToPass)
{
$requirementsLeft = $minRequirementsToPass - $requirementsPassed
$requirementsCount = $requirements.Count
$Context.Cancel("The password must meet at least $minRequirementsToPass out of $requirementsCount complexity requirements of which only $requirementsPassed has been met. Meet at least $requirementsLeft more of the requirements above.")
foreach ($message in $errorMessages)
{
$Context.LogMessage($message, "Error")
}
return
}
}