Workoho.Automation.Common/Public/Get-Auto_RandomPassword.ps1
<# .SYNOPSIS Generates a random password with specified length and character requirements. .DESCRIPTION This script generates a random password by combining characters from different character sets, such as lowercase letters, uppercase letters, numbers, and special characters. The length of the password and the minimum number of characters required from each set can be specified as parameters. .PARAMETER length The length of the generated password. .PARAMETER minLower The minimum number of lowercase letters required in the password. Default is 0. .PARAMETER minUpper The minimum number of uppercase letters required in the password. Default is 0. .PARAMETER minNumber The minimum number of numbers required in the password. Default is 0. .PARAMETER minSpecial The minimum number of special characters required in the password. Default is 0. .PARAMETER maxSpecial The maximum number of special characters allowed in the password. Default is unlimited. .OUTPUTS System.String The generated random password. .EXAMPLE PS> Get-Auto_RandomPassword -length 12 -minLower 2 -minUpper 2 -minNumber 2 -minSpecial 2 Generates a random password with a length of 12, including at least 2 lowercase letters, 2 uppercase letters, 2 numbers, and 2 special characters. #> function Get-Auto_RandomPassword { [CmdletBinding()] Param( [Parameter(Mandatory)] [Int32]$length, [Int32]$minLower = 0, [Int32]$minUpper = 0, [Int32]$minNumber = 0, [Int32]$minSpecial = 0, [Int32]$maxSpecial = -1 ) Write-Auto_FunctionBegin $MyInvocation #region [COMMON] INPUT VALIDATION ---------------------------------------------- if ($length -lt $minLower + $minUpper + $minNumber + $minSpecial) { Write-Error 'Password length must be greater than or equal to the sum of minLower, minUpper, minNumber, and minSpecial.' -ErrorAction Stop exit 1 } #endregion --------------------------------------------------------------------- #region [COMMON] FUNCTIONS ----------------------------------------------------- function Get-CryptoRandomNumber([Int32]$maxValue) { $rng = [System.Security.Cryptography.RNGCryptoServiceProvider]::new() $randomByte = [byte[]]::new(4) $rng.GetBytes($randomByte) $randomNumber = [System.BitConverter]::ToUInt32($randomByte, 0) return $randomNumber % $maxValue } function Get-RandomCharacter([Int32]$length, [string]$characters) { if ($length -lt 1) { return '' } $random = 1..$length | ForEach-Object { Get-CryptoRandomNumber $characters.Length } $private:ofs = '' return [string]$characters[$random] } function Get-ScrambleString([string]$inputString) { $characterArray = $inputString.ToCharArray() $scrambledArray = [System.Text.StringBuilder]::new() 0..($characterArray.Length - 1) | ForEach-Object { $randomIndex = Get-CryptoRandomNumber $characterArray.Length $scrambledArray.Append($characterArray[$randomIndex]) | Out-Null $characterArray = $characterArray[0..($randomIndex - 1)] + $characterArray[($randomIndex + 1)..($characterArray.Length - 1)] } return $scrambledArray.ToString() } #endregion --------------------------------------------------------------------- # Define character sets $lowerChars = 'abcdefghijklmnopqrstuvwxyz' $upperChars = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' $numberChars = '0123456789' $specialChars = "~`!@#$%^&*()_-+={[}]|\:;`"'<,>.?/" # Calculate the number of characters needed for each set $totalChars = $minLower + $minUpper + $minNumber + $minSpecial $remainingChars = $length - $totalChars $lowerCharsNeeded = [Math]::Max($minLower - $remainingChars, 0) $upperCharsNeeded = [Math]::Max($minUpper - $remainingChars, 0) $numberCharsNeeded = [Math]::Max($minNumber - $remainingChars, 0) $specialCharsNeeded = [Math]::Max($minSpecial - $remainingChars, 0) if ($maxSpecial -eq 0) { $specialCharsNeeded = 0 } elseif ($maxSpecial -le -1) { $specialCharsNeeded = [Math]::Min($specialCharsNeeded, $maxSpecial) } # Initialize a counter for special characters $specialCharCount = 0 try { # Generate the password $return = [System.Text.StringBuilder]::new() if ($lowerCharsNeeded -gt 0) { [void] $return.Append((Get-RandomCharacter -length $lowerCharsNeeded -characters $lowerChars)) } if ($upperCharsNeeded -gt 0) { [void] $return.Append((Get-RandomCharacter -length $upperCharsNeeded -characters $upperChars)) } if ($numberCharsNeeded -gt 0) { [void] $return.Append((Get-RandomCharacter -length $numberCharsNeeded -characters $numberChars)) } if ($specialCharsNeeded -gt 0) { [void] $return.Append((Get-RandomCharacter -length $specialCharsNeeded -characters $specialChars)) $specialCharCount += $specialCharsNeeded } $remainingChars = $length - $return.Length if ($remainingChars -gt 0) { while ($remainingChars -gt 0) { if ($maxSpecial -le -1 -or $specialCharCount -lt $maxSpecial) { $combinedChars = $lowerChars + $upperChars + $numberChars + $specialChars } else { $combinedChars = $lowerChars + $upperChars + $numberChars } $randomChar = Get-RandomCharacter -length 1 -characters $combinedChars [void] $return.Append($randomChar) if ($specialChars.Contains($randomChar) -and ($maxSpecial -le -1 -or $specialCharCount -lt $maxSpecial)) { $specialCharCount++ } $remainingChars = $length - $return.Length } } $return = Get-ScrambleString $return.ToString() } catch { Throw "An error occurred: $_" } Write-Auto_FunctionEnd $MyInvocation return $return } |