noc4.jpg
.: 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.
.: Comments (2)
.: Eggy writes:

thx a lot i used it for the script i'm doing

.: Guillaume writes:

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      }

    # Declare the various character classes we will select from
    # If you want to change the proportions of the classes, you can
    # declare them multiple times
    $arrayStrClasses = (
        '1234567890', 
        'ABCDEFGHIJKLMNOPQRSTUVWXYZ',
        'abcdefghijklmnopqrstuvwxyz',
        '$!%^&*()+=/?{}[]~,.>:'
    );

    # 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 

Post a comment