powershell random password generator

This morning I decided to replace part of a script I own at work with a random password generation function. This was easier than I thought it would be. This function takes a number that should be greater than 4, and returns back a random password of that length. The character sets are pretty obvious inside the function and can be adjusted as needed. The password generated assures the first 4 positions will always be a number, capital letter, lower case letter, and symbol, respectively, to meet some complexity requirements. The rest of the positions are a random character chosen from a random character set.

function RandomPassword ([int]$intPasswordLength)
{
if ($intPasswordLength -lt 4) {return "password cannot be <4 chars"}
$strNumbers = "1234567890"
$strCapitalLetters = "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
$strLowerLetters = "abcdefghijklmnopqrstuvwxyz"
$strSymbols = "!%^&*()+=/?{}[]~,.<>:"
$rand = new-object random
for ($a=1; $a -le $intPasswordLength; $a++)
{
if ($a -gt 4)
{
$b = $rand.next(0,4) + $a
$b = $b % 4 + 1
} else { $b = $a }
switch ($b)
{
"1" {$b = "$strNumbers"}
"2" {$b = "$strCapitalLetters"}
"3" {$b = "$strLowerLetters"}
"4" {$b = "$strSymbols"}
}
$charset = $($b)
$number = $rand.next(0,$charset.Length)
$RandomPassword += $charset[$number]
}
return $RandomPassword
}
RandomPassword 36

No doubt there are other functions and solutions to this, but I kinda just wanted my own.

2 thoughts on “powershell random password generator

  1. The example given is a good start, but it will always give passwords starting in number, capital, lower, symbol. If you want truly random passwords, I have greatly modified the function:
    function RandomPassword ([int]$intPasswordLength, [String]$classes)
    {
        if ( $intPasswordLength -lt 4 ) {
            return “password cannot be :’
        );
        # Add the character classes expressed in the classes parameter, if any
        foreach ($strClass in $arrayStrClasses) {
            if ( $strClass.IndexOfAny($classes.ToCharArray()) -ne -1 ) {
                $passwordCharClass += $strClass;    
            }
        }
        $classSize = $passwordCharClass.Length;
        
        # If we don’t have at least 2 chars (minimum for a random string), use all classes    
        if($classSize -lt 2) {    
            foreach ($strClass in $arrayStrClasses) {
                    $passwordCharClass += $strClass;
            }
            $classSize = $passwordCharClass.Length;
        }
        
        if ( $classSize -gt [byte]::MaxValue ) {
            return “Character class size exceeds design limit.”;
        }
        # Get the secure random number generator
        $rand = new-object “System.Security.Cryptography.RNGCryptoServiceProvider”;
        $randByteArrayLength = $intPasswordLength * 3;
        
        # Declare random bytes array of the right size
        $randByteArray = new-object “System.Byte[]” $randByteArrayLength;
            
        $rand.GetBytes($randByteArray);
        
        # incrementer for randByteArray;
        # $ir = 0;
        
        # $RandomPassword = “”;
        
        $upperLimit = $classSize * [System.Math]::Floor( ( [byte]::MaxValue + 1 ) / $classSize );
        
        for ($a=1; $a -le $intPasswordLength; $a++)
        {   
            # Unlikely event of not enough bytes
            if ( $ir -ge $randByteArrayLength ) {
                $rand.GetBytes($randByteArray);
                $ir = 0;
            }        
            # Note: many implementations skip this step, causing a non-uniform distribution of 
            # characters, since the numbers above the upperLimit don’t cover the entire character class
            while ( $randByteArray[$ir] -gt $upperLimit )
            {
                ++$ir;
            }
            $RandomPassword += $passwordCharClass[$randByteArray[$ir] % $classSize];
            ++$ir;
        }
        return $RandomPassword;
    };
    RandomPassword 36 “x4”
    RandomPassword 36 

Comments are closed.