PoshCode Archive  Artifact [a8b467067f]

Artifact a8b467067f2536f71697d26b10d7dec6cca8531aafd31fba73d3af2c5d1ded3e:

  • File New-ComplexPassword.ps1 — part of check-in [e1534529d0] at 2018-06-10 13:58:57 on branch trunk — Generate random passwords with specific complexity requirements (user: Jon Webster size: 2822)

# encoding: ascii
# api: powershell
# title: New-ComplexPassword
# description: Generate random passwords with specific complexity requirements
# version: 0.1
# type: function
# author: Jon Webster
# license: CC0
# function: New-ComplexPassword
# x-poshcode-id: 567
# x-archived: 2012-06-16T07:56:53
# x-published: 2009-09-05T20:01:00
#
#
# $Id: New-ComplexPassword.ps1 170 2008-09-05 19:49:48Z jon $
# $Revision: 170 $

Function New-ComplexPassword ([int]$Length=8, $digits=$null, $alphaUpper=$null, $alphaLower=$null, $special=$null)
{

	#  ASCII data taken from http://msdn2.microsoft.com/en-us/library/60ecse8t(VS.80).aspx

	# Make sure the password is long enough to meet complexity requirements
	if($digits+$alphaUpper+$alphaLower+$special -gt $Length) { throw "Password too short for specified complexity" }

	# Define character groups and the number of each required by passwords

	# In case this is used in a DCPromo answer files, theres a few chars to 
	# avoid: Ampersand, Less than, double quote and back slash
	# (34,38,60,92)
	
	$groups = @()
	$group = New-Object System.Object
	Add-Member -In $group -Type NoteProperty -Name "Group" -Value "0123456789" # 48..57

	Add-Member -In $group -Type NoteProperty -Name "Count" -Value $Digits
	$groups += $group

	$group = New-Object System.Object
	Add-Member -In $group -Type NoteProperty -Name "Group" -Value "ABCDEFGHIJKLMNOPQRSTUVWXYZ" # 65..90
	Add-Member -In $group -Type NoteProperty -Name "Count" -Value $alphaUpper
	$groups += $group

	$group = New-Object System.Object
	Add-Member -In $group -Type NoteProperty -Name "Group" -Value "abcdefghijklmnopqrstuvwxyk" # 97..122
	Add-Member -In $group -Type NoteProperty -Name "Count" -Value $alphaLower
	$groups += $group

	$group = New-Object System.Object
	Add-Member -In $group -Type NoteProperty -Name "Group" -Value '~`!@#$%^&*()-_={}[]\|;:"<>?,./'' ' #  32..47, 58..64, 91..96, 123..126
	Add-Member -In $group -Type NoteProperty -Name "Count" -Value $special
	$groups += $group 

	# initilize random number generator
	$ran = New-Object Random

	# make sure password meets complexity requirements
	foreach ($req in $groups)
	{
		if ($req.count)
		{
			$charsAllowed += $req.group

			for ($i=0; $i -lt $req.count; $i++)
			{
				$r = $ran.Next(0,$req.group.length)
				$password += $req.group[$r]	
			}
		} elseif ($req.count -eq 0) {
			$charsAllowed += $req.group
		}
	}

	# make sure password meets length requirement
	if(!$charsAllowed)
	{
		$groups |% { $charsAllowed += $_.group }
	}

	for($i=$password.length; $i -lt $length; $i++)
	{
		$r = $ran.Next(0,$charsAllowed.length)
		$password += $charsAllowed[$r]
	}

	# randomize the password
	return [string]::join('',($password.ToCharArray()|sort {$ran.next()}))
}