Passwords.psm1
<#
.SYNOPSIS This function generates a new password. .DESCRIPTION This function generates a new password. This function is superior to [System.Web.Security.Membership]::GeneratePassword() as it is able to guarantee a minimum number of lowercase characters, uppercase characters and digits. #> function New-Password { [CmdletBinding(PositionalBinding=$false)] param ( # The number of characters in the password. [Parameter(Mandatory=$true)] [ValidateScript({ $_ -gt 0 })] [Int]$numberOfCharacters, # The minimum number of lowercase characters in the password. # Set to -1 to indicate no lowercase characters should be present in the password. [Parameter(Mandatory=$false)] [ValidateScript({ $_ -ge -1 })] [Int]$minLowercaseCharacters = 1, # The minimum number of uppercase characters in the password. # Set to -1 to indicate no uppercase characters should be present in the password. [Parameter(Mandatory=$false)] [ValidateScript({ $_ -ge -1 })] [Int]$minUppercaseCharacters = 1, # The minimum number of numerical digits in the password. # Set to -1 to indicate no numerical digits should be present in the password. [Parameter(Mandatory=$false)] [ValidateScript({ $_ -ge -1 })] [Int]$minDigits = 1, # The minimum number of special characters in the password. # Set to -1 to indicate no special characters should be present in the password. [Parameter(Mandatory=$false)] [ValidateScript({ $_ -ge -1 })] [Int]$minSpecialCharacters = 1, # A list containing the special characters to use. # If this parameter is provided, it will be used as the special character set, # instead of the default special character set. [Parameter(Mandatory=$false)] [ValidateNotNull()] [ValidateScript({ $_.length -and !($_ | Where-Object { $_.GetType() -ne [String] }) })] [PSObject[]]$specialCharacters ) # Verify inputs if ($minLowercaseCharacters + $minUppercaseCharacters + $minDigits + $minSpecialCharacters -gt $numberOfCharacters) { Write-Error "Invalid combination of inputs: the sum of the minimum number of each category of characters is greater than the total number of characters." return "" } elseif ($minLowercaseCharacters + $minUppercaseCharacters + $minDigits + $minSpecialCharacters -eq -4) { Write-Error "The minimum number of characters in each category will result in an empty password." return "" } # Store password characters as a list $password = @() # Generate list of lowercase characters (97 to 122 in ASCII) $lowercaseCharacters = 97 .. 122 | ForEach-Object -Process { "$([Char]$_)" } # Add lowercase characters to password for ($i = 0; $i -lt $minLowercaseCharacters; ++$i) { $password += Get-Random -InputObject $lowercaseCharacters -Count 1 } # Generate list of uppercase characters (65 to 90 in ASCII) $upperCaseCharacters = 65 .. 90 | ForEach-Object -Process { "$([Char]$_)" } # Add uppercase characters to password for ($i = 0; $i -lt $minUppercaseCharacters; ++$i) { $password += Get-Random -InputObject $upperCaseCharacters -Count 1 } # Generate list of digits (48 to 57 in ASCII) $digits = 48 .. 57 | ForEach-Object -Process { "$([Char]$_)" } # Add digits to password for ($i = 0; $i -lt $minDigits; ++$i) { $password += Get-Random -InputObject $digits -Count 1 } # Generate list of special characters (33 to 47, 58 to 64, 91 to 96 in ASCII), if not provided if (!$specialCharacters) { $specialCharacters = ((33 .. 47) + (58 .. 64) + (91 .. 96)) | ForEach-Object -Process { "$([Char]$_)" } } # Add special characters to password for ($i = 0; $i -lt $minSpecialCharacters; ++$i) { $password += Get-Random -InputObject $specialCharacters -Count 1 } # Generate character set containing remaining characters $allCharacters = @() if ($minLowercaseCharacters -ge 0) { $allCharacters += $lowercaseCharacters } if ($minUppercaseCharacters -ge 0) { $allCharacters += $upperCaseCharacters } if ($minDigits -ge 0) { $allCharacters += $digits } if ($minSpecialCharacters -ge 0) { $allCharacters += $specialCharacters } # Fill up password with remaining characters $numRemainingCharacters = $numberOfCharacters - $password.length for ($i = 0; $i -lt $numRemainingCharacters; ++$i) { $password += Get-Random -InputObject $allCharacters -Count 1 } # Randomly permute password $password = $password | Sort-Object { Get-Random } # Join password into a string and return $password -join "" } |