Truly random numbers and passwords in Powershell

This week I have been teaching a MS6434 course (Powershell) and during the students labs I always sit and try some new technologies. One thing that one of my participants brought up was how to generate random passwords and that the standard RANDOM isn’t always realy random. Surely there must be a solution to this I tought and here is the resulting function:

  1. function Get-RealyRandomInt
  2. {
  3. $randomBytes = New-Object byte[] 4
  4. $(new-object System.Security.Cryptography.RNGCryptoServiceProvider).GetBytes($randomBytes)
  5. return [BitConverter]::ToInt32($randomBytes,0)
  6. }

Short, sweet and truly random. Use this to your heats content. I have also wrote a small function to generate a password:

  1. function Get-Password
  2. {
  3.  param ([int]$length=8,[switch]$noSpecialChars,[switch]$noNumbers,[switch]$noLowerCase,[switch]$noUpperCase,[switch]$includeUbiquitous)
  4.  
  5.  #Setup valid chars for generation of password
  6.  if ($includeUbiquitous) { $chars += “L”,”l”,”i”,”I”,”j”,”J”,”O”,”o”,”0″,”1″}
  7.  if (!$noUpperCase)      { $chars += “A”,”B”,”C”,”D”,”E”,”F”,”G”,”H”,”K”,”M”,”N”,”P”,”Q”,”R”,”S”,”T”,”U”,”V”,”X”,”Y”,”Z” }
  8.  if (!$noLowerCase)      { $chars += “a”,”b”,”c”,”d”,”e”,”f”,”g”,”h”,”k”,”m”,”n”,”p”,”q”,”r”,”s”,”t”,”u”,”v”,”x”,”y”,”z” }
  9.  if (!$noSpecialChars)   { $chars += “%”,”#”,”&”,”(“,”)”,”=”,”?”,”-“,”_”,”§”,”;”,”:”,”<“,”>”,”@”,”*” }
  10.  if (!$noNumbers)        { $chars += “2”,”3″,”4″,”5″,”6″,”7″,”8″,”9″ }
  11.  if ($chars.length -le 0)  {  throw “You must cannot exclude all classes of chars, passwords without chars are not good.”  }
  12.  
  13.  #Loop generation process for specified length and return the password
  14.  for ($i=1; $i -le $length; $i++)  {  $output += $chars[$(New-Object Random(Get-RealyRandomInt)).Next($chars.Length)]  }
  15.  return $output
  16. }

Both theese examples can be downloaded from the attached file

Updated at 2009-05-20 21:45: A big thanks to Niklas Goude for correcting a spelling mistake in the variable $includeUbiquitous above. Thanks!