Functions/New-RandomPassword.ps1
<#
.SYNOPSIS Create a random password .DESCRIPTION The function creates a random password using a given set of available characters. The password is generated with fixed or random length. .PARAMETER MinPasswordLength Minimum password length when generating a random length password .PARAMETER MaxPasswordLength Maximum password length when generating a random length password .PARAMETER PasswordLength Fixed password length .PARAMETER InputStrings String array containing sets of available password characters .PARAMETER FirstChar Specifies a string containing a character group from which the first character in the password will be generated .PARAMETER Count Number of passwords to generate, default = 1 .EXAMPLE New-RandomPassword -MinPasswordLength 6 -MaxPasswordLength 12 Generates a random password fo minimum length 6 andmaximum length 12 characters .EXAMPLE New-RandomPassword -PasswordLength 20 Generates a password of 20 characters .EXAMPLE New-RandomPassword -InputStrings Value -FirstChar Value -Count Value Describe what this call does .NOTES Author of function: Thomas Stensitzki Stolen from: https://github.com/Apoc70/GlobalFunctions/blob/master/GlobalFunctions/GlobalFunctions.psm1 Based on Simon Wahlin's script published here: https://gallery.technet.microsoft.com/scriptcenter/Generate-a-random-and-5c879ed5 Story behind: http://blog.simonw.se/powershell-generating-random-password-for-active-directory/ #> function New-RandomPassword { [CmdletBinding(DefaultParameterSetName='FixedLength')] [OutputType([String])] param( [Parameter(ParameterSetName='RandomLength')] [ValidateScript({$_ -gt 0})] [Alias('Min')] [int]$MinPasswordLength = 8, [Parameter(ParameterSetName='RandomLength')] [ValidateScript({ if($_ -ge $MinPasswordLength){$true} else{Throw 'Max value cannot be lesser than min value.'}})] [Alias('Max')] [int]$MaxPasswordLength = 12, [Parameter(ParameterSetName='FixedLength')] [ValidateRange(1,2147483647)] [int]$PasswordLength = 8, [String[]]$InputStrings = @('abcdefghjkmnpqrstuvwxyz', 'ABCEFGHJKLMNPQRSTUVWXYZ', '23456789', '=+_?!"*@#%&'), [String] $FirstChar, # Specifies number of passwords to generate. [ValidateRange(1,2147483647)] [int]$Count = 1 ) Function Get-Seed{ # Generate a seed for randomization $RandomBytes = New-Object -TypeName 'System.Byte[]' 4 $Random = New-Object -TypeName 'System.Security.Cryptography.RNGCryptoServiceProvider' $Random.GetBytes($RandomBytes) [BitConverter]::ToUInt32($RandomBytes, 0) } For($iteration = 1;$iteration -le $Count; $iteration++){ $Password = @{} # Create char arrays containing groups of possible chars [char[][]]$CharGroups = $InputStrings # Create char array containing all chars $AllChars = $CharGroups | ForEach-Object {[Char[]]$_} # Set password length if($PSCmdlet.ParameterSetName -eq 'RandomLength') { if($MinPasswordLength -eq $MaxPasswordLength) { # If password length is set, use set length $PasswordLength = $MinPasswordLength } else { # Otherwise randomize password length $PasswordLength = ((Get-Seed) % ($MaxPasswordLength + 1 - $MinPasswordLength)) + $MinPasswordLength } } # If FirstChar is defined, randomize first char in password from that string. if($PSBoundParameters.ContainsKey('FirstChar')){ $Password.Add(0,$FirstChar[((Get-Seed) % $FirstChar.Length)]) } # Randomize one char from each group Foreach($Group in $CharGroups) { if($Password.Count -lt $PasswordLength) { $Index = Get-Seed While ($Password.ContainsKey($Index)){ $Index = Get-Seed } $Password.Add($Index,$Group[((Get-Seed) % $Group.Count)]) } } # Fill out with chars from $AllChars for($i=$Password.Count;$i -lt $PasswordLength;$i++) { $Index = Get-Seed While ($Password.ContainsKey($Index)){ $Index = Get-Seed } $Password.Add($Index,$AllChars[((Get-Seed) % $AllChars.Count)]) } } return $(-join ($Password.GetEnumerator() | Sort-Object -Property Name | Select-Object -ExpandProperty Value)) } |