Powershell

Ok last time I made a password generator, it was fun.  Really it was.

No REALLY! I’m not lying!

Then a buddy Joel "Jaykul” Bennett showed me really cool Password generator in Powershell on Poshcode.org . It would generate semi pronouncable passwords using a series of Arrays contains the sets of characters and the ‘Switch’ Statement

It was incredible, but I looked at it and thought “I’d like to improve upon it”

So I tried

Then end result Has all of the arrays combined into one Dynamic Array, a more universal function to eliminate much of the code, and the ability to pop the new password to the Clipboard, Straight text and SecureString.

I think it could still be improved upon.  I’d like to go the next level sometime and have a giant source dictionary, having the system optionally generate quasi “l33t sp34k” passwords.

But for now? I’m happy. 

Here’s the function and you’re happy to take IT to the next level.

————————— Script ——————————–

Function global:GET-NEWpassword( $Length, $Complexity) {

# $Length variable serves a dual Purpose
# It assumes nobody wants a tiny password less than
# 8 characters so anything less than than it used
# to pull up one of 8 predined password templates

    If ($Length -eq $NULL) { $Length = 0 }

# If you’re going "100%" random you can provide a second
# value which is complexity.
#
# 1 – just random lowercase letter3
# 3 – is pretty decent (upper/lower/numbers)
# 9 – is "Muah hahaahahahahah!!!"

    If ($Complexity -eq $NULL) { $Complexity = 3 }

# If password Length provided is less than eight
# Function will use one of 8 predefined templates

# Default Settings 8 Character SemiPronouncable Password from a previous
# password generator on Poshcode.org
#
# These are predinable password sets, as long as you like, max *8*
# C = Upper Case Consanant
# c = Lower Case Consanant
# L = Upper Case Alphabet
# l = Lower Case Alphabet
# D = Decimal numbers
# h = Hexidecimal series with Lowercase a-f
# H = Hexidecimal series with Uppercase A-F
# * = Any defined character in the sets

    $passwordTemplateList=,"Cvcvcdd."
    $passwordTemplateList+=,"CvCddvVc"
    $passwordTemplateList+=,"********"
    $passwordTemplateList+=,"CccddVvv"
    $passwordTemplateList+=,"HHHHHHHH"
    $passwordTemplateList+=,"d.d.d.d."
    $passwordTemplateList+=,"dddddddd"
    $passwordTemplateList+=,"0V0cC.0C"

    $PasswordTemplate=$NULL

# All character sets are part of a single Dynamic Array which you
# can easily add to

#Lowercase
    $AsciiArray=,("l","abcdefghijklmnopqrstuvwxyz")
#Uppercase
    $AsciiArray+=,("L","ABCDEFGHIJKLMNOPQRSTUVWXYZ")
#Decimal Numbers
    $AsciiArray+=,("d","0123456789")
#Punctuation
    $AsciiArray+=,(".","!#$%'()*+,-./:;=>?@[]^-")
#Lowercase Vowels
    $AsciiArray+=,("v","aeiou")
#Uppercase Vowels
    $AsciiArray+=,("V","AEIOU")
#HexadecimalNumbers (lowercase on the a-f)
    $AsciiArray+=,("h","0123456789abcdef")
#HexadecimalNumbers (UPPERCASE on the A-F)
    $AsciiArray+=,("H","0123456789ABCDEF")
#Lowercase Consonants
    $AsciiArray+=,("c","abcdfghjklmnpqrstvwxyz")
#Uppercase Consonants
    $AsciiArray+=,("C","ABCDFGHJKLMNPQRSTVWXYZ")

# This variable is important.  If you ADD to the Array
# It checks the size for all of the calculations below
# First Character in the Array such as l,L,d,v etc
# identifies the contents of that row of the array
# such as lowercaseletter, UPPERCASELETTER, Decimalnumber
# vowel

    $Arraysize=($AsciiArray.Length)-1

# Here is part of the magic
#
# If we have a password length less than 8 supplied
# from the parameter, we will call up one of 8
# predefined templates and use THAT format for
# the password.
#

    If ($Length -lt 8)
    {
        $PasswordTemplate = $PasswordTemplateList[$Length];
        $Complexity = $Arraysize
    }
#
# Otherwise it is a large password and we will build
# A Pseudo template where each character is our "*"
# wildcard

    Else
    {
        Foreach ($count in 1..$Length)
        { $PasswordTemplate+="*" }
    }

# Blank out the new Password for good measure, JUST CUZ!

    $NewPassword=$NULL
# First loop.  Look at and ACT upon each character in the template
# to produce the appropriate content for that position in the
# password

Foreach ( $item in 0..(($passwordTemplate.Length)-1) ) {
    $Asciiset = $passwordtemplate[$item]

# Here is our second loop.  We’re going to match the Type of
# Character being used against the master list in the array
# When found, we use that set

# Special scenario.  If we’re doing a "Wildcard" "*" then we have to pick
# a random set from the Array to be able to pick a random character

    If ($AsciiSet -eq "*"){ $Asciiset=$AsciiArray[(GET-RANDOM $Complexity)][0]}

    $Arraypos=0
# While the two don’t match, keep checking the sets.

    while ([byte][char]$AsciiSet -ne [byte][char]($AsciiArray[$Arraypos][0])){$Arraypos++}

# $Arraypos holds the correct set.  Pull out the String of Characters
# Get the length of the array, and use GET-RANDOM to pick a byte

    $String=$AsciiArray[$ArrayPos][1]
    $StringLength=$String.Length

# Now add that to the password

    $NewPassword+=$String.substring((GET-RANDOM $StringLength),1)

# End of loop – this goes on until the password is built

    }

    # this line doesn’t work in Windows XP natively, but you can download a utility
    # called "ToClip" that does the same thing.  REplace "Clip" with "ToClip"
    # http://www.fullspan.com/proj/toclip/index.html
    #
    # Send the password to the Clipboard

    $NewPassword | clip

    # Return the password in Plaintext and as Secure-String

    Return $NewPassword, (CONVERTTO-Securestring $NewPassword -asplaintext -force)

}

————————— Script ——————————–