VCF - Powershell password generator function for VMware Cloud Foundation
Anyone that worked with VMware Cloud Foundation (VCF) knows that passwords and valid special characters can be a tricky business.
In summary, the set of special characters allowed by VCF, is a subset of the ones that some of the individual products admit.
When I was developing some automation to deploy VCF Nested Labs there was the need of generation some random passwords on demand instead of using the same passwords for all the nested environments.
After some search and some stumbling around, I found a good base to start from and to implement my own random password generator function.
Code based on New-RandomPassword.ps1
Objective
Having a function that generates random passwords with the necessary complexity and size to use in VCF deployments.
Complexity Requirements
- Length - 8-20 characters
- At least one Uppercase, lowercase, number & special character
- Special characters allowed: @ ! # $ % ? ^
Password validation regular expression
Generating random passwords is easy, the difficulty is in validating that password against our complexity requirements.
An regular expression is probably one of the ways of doing it.
The regexp used by the function and based in New-RandomPassword.ps1
^((?=.*[a-z])(?=.*[A-Z])(?=.*[^A-Za-z0-9]))([A-Za-z\d@!#$%?^]){8,20}$
- The regular expression validates the complexity requirements listed above.
Some additional randomization by making the order of the characters in seed array random
To remove some of the non-valid characters from ASCII table, we create a seed array to be the source of our characters for the passwords. We shuffle the array just to get some extra randomization (not that it makes an huge difference).
And we created a list of the valid chars for our password generation.
$seedArray = (48..57) + (65..90) + (97..122) + @(33, 36, 37, 94)
$seedArray = $seedArray | Sort-Object Get-Random
$asciiCharsList = @()
foreach ($a in $seedArray){
$asciiCharsList += , [char][byte]$a
}
Now we generate passwords based on our character list until we get one valid one
do {
$password = ""
$loops = 1..$length
Foreach ($loop in $loops) {
$password += $asciiCharsList | Get-Random
}
} until ($password -match $regExp )
Entire function
function New-RandomPassword {
<#
.SYNOPSIS
Random Password Generator function
.DESCRIPTION
Random Password Generator function
.PARAMETER length
Length of the password to generate (defaults to 16)
.EXAMPLE
.NOTES
Original code from https://github.com/PaoloFrigo/scriptinglibrary/blob/master/Blog/PowerShell/New-RandomPassword.ps1
#>
Param(
[ValidateRange(8, 32)]
[int] $length = 16
)
# Add some extra randomization by creating the "seed array" randomly
# Remove double quotes and slash and black slash
$seedArray = (48..57) + (65..90) + (97..122) + @(33, 36, 37, 94)
$seedArray = $seedArray | Sort-Object Get-Random
$asciiCharsList = @()
foreach ($a in $seedArray){
$asciiCharsList += , [char][byte]$a
}
#regExp allowing only special characters @!#$%?^ as per VCF/VMware
$regExp = "^((?=.*[a-z])(?=.*[A-Z])(?=.*[^A-Za-z0-9]))([A-Za-z\d@!#$%?^]){8,20}$"
do {
$password = ""
$loops = 1..$length
Foreach ($loop in $loops) {
$password += $asciiCharsList | Get-Random
}
} until ($password -match $regExp )
return $password
}