Skip to content

Instantly share code, notes, and snippets.

@indented-automation
Last active April 6, 2023 19:57
Show Gist options
  • Star 3 You must be signed in to star a gist
  • Fork 2 You must be signed in to fork a gist
  • Save indented-automation/2093bd088d59b362ec2a5b81a14ba84e to your computer and use it in GitHub Desktop.
Save indented-automation/2093bd088d59b362ec2a5b81a14ba84e to your computer and use it in GitHub Desktop.
PowerShell random password generator.

New-Password

A random password generator implementation in PowerShell.

Usage

Example

New-Password -Length 20

A single 20 character long password.

Example

10..20 | New-Password

A set of passwords with lengths from 10 to 20 characters.

Example

@(20) * 20 | New-Password

20 passwords, 20 characters long.

Example

New-Password -CharacterSet 'ABCDEF', '1234567890'

A random password generated from the specified set. The password will contain a miniumum of 1 of each character set.

Example

New-Password -CharacterSetCount 0, 1, 2, 3

A password which contains a minimum of 0 from the first set, 1 from the second, 2 from the third, and 3 from the forth.

Thanks

Thanks to faustonascimento on the PowerShell user group channel for helping rewrite this, making it far better than it was.

function New-Password {
<#
.SYNOPSIS
Generate a random password.
.DESCRIPTION
Generate a random password.
.NOTES
Change log:
27/11/2017 - faustonascimento - Swapped Get-Random for System.Random.
Swapped Sort-Object for Fisher-Yates shuffle.
17/03/2017 - Chris Dent - Created.
#>
[CmdletBinding()]
[OutputType([String])]
param (
# The length of the password which should be created.
[Parameter(ValueFromPipeline)]
[ValidateRange(8, 255)]
[Int32]$Length = 10,
# The character sets the password may contain. A password will contain at least one of each of the characters.
[String[]]$CharacterSet = ('abcdefghijklmnopqrstuvwxyz',
'ABCDEFGHIJKLMNOPQRSTUVWXYZ',
'0123456789',
'!$%&^.#;'),
# The number of characters to select from each character set.
[Int32[]]$CharacterSetCount = (@(1) * $CharacterSet.Count)
)
begin {
$bytes = [Byte[]]::new(4)
$rng = [System.Security.Cryptography.RandomNumberGenerator]::Create()
$rng.GetBytes($bytes)
$seed = [System.BitConverter]::ToInt32($bytes, 0)
$rnd = [Random]::new($seed)
if ($CharacterSet.Count -ne $CharacterSetCount.Count) {
throw "The number of items in -CharacterSet needs to match the number of items in -CharacterSetCount"
}
$allCharacterSets = [String]::Concat($CharacterSet)
}
process {
try {
$requiredCharLength = 0
foreach ($i in $CharacterSetCount) {
$requiredCharLength += $i
}
if ($requiredCharLength -gt $Length) {
throw "The sum of characters specified by CharacterSetCount is higher than the desired password length"
}
$password = [Char[]]::new($Length)
$index = 0
for ($i = 0; $i -lt $CharacterSet.Count; $i++) {
for ($j = 0; $j -lt $CharacterSetCount[$i]; $j++) {
$password[$index++] = $CharacterSet[$i][$rnd.Next($CharacterSet[$i].Length)]
}
}
for ($i = $index; $i -lt $Length; $i++) {
$password[$index++] = $allCharacterSets[$rnd.Next($allCharacterSets.Length)]
}
# Fisher-Yates shuffle
for ($i = $Length; $i -gt 0; $i--) {
$n = $i - 1
$m = $rnd.Next($i)
$j = $password[$m]
$password[$m] = $password[$n]
$password[$n] = $j
}
[String]::new($password)
} catch {
Write-Error -ErrorRecord $_
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment