Today I wrote a post with a Powershell function to create a complex password.
Although it does generate a complex password, it would not be enough for the complexity policy for passwords in Windows. This because the script didn’t check if there was a lowercase, uppercase, number and punctuation mark included.
Now, until now that script was sufficient for my customers because when you script a password you would not get prompted by a nasty error stating that the provided password does not meet the complexity requirements and stuff like that; it will just ram the password in your user object and be done with it.
Now, in the afternoon I received several comments (from Pete Zerger amongst others) about this limitation of my function, so (just to make the community peers happy) I re-wrote the function. And since I was at it, now a default length of 8 characters is used when no length is provided.
Function New-RandomComplexPassword ()
{
param ( [int]$Length = 8 )
#Usage: New-RandomComplexPassword 12
$Assembly = Add-Type -AssemblyName System.Web
$RandomComplexPassword = [System.Web.Security.Membership]::GeneratePassword($Length,2)
Write-Output $RandomComplexPassword
}
As you may have noticed, with this version I make use of a .NET assembly instead of native Powershell cmdlets. This is because using the .NET assembly makes the code a lot shorter and faster. Next to that, the script I started to write before I found this assembly was huge and way more complex than it needed to be.
For more information on the assembly I used, check the MSDN page.
Here is another function for that (do not remember where i found it though)
function Get-RandomPassword {
param(
$length = 7,
$characters = ‘abcdefghkmnprstuvwxyzABCDEFGHKLMNPRSTUVWXYZ123456789!”§$%&/()=?*+#_’
)
# select random characters
$random = 1..$length | ForEach-Object { Get-Random -Maximum $characters.length }
# output random pwd
#Write-Host $random
$private:ofs= “”
$password = [String]$characters[$random]
return $password
}
Hi Niklas,
Thanks for your feedback, always appreciated.
Although we already talked about it through Twitter still my reply: You’re function has the same limitation as my first one, it doesn’t enforce the requirement for the password complexity policy… but as you tweeted already, you’ve noticed that 🙂
Jeff.
Here is a function using native PowerShell I wrote that generates a random password that meats complex requirements and has a random length between 7 and 16 characters. I randomized the length to remove the predictability of the length of the generated passwords.
function Generate-RandomPassword { $rand = New-Object System.Random $Pwlength = $rand.next(7,16) Do { $pw = $null For ($i = 1; $i -le $Pwlength; $i++) { Do { $char = [char]$rand.next(33,126) } while ($char -match “[/,x22\]”) $pw += $Char } } until ($pw -match “(?-i)(?=^.{7,16}$)((?=.*d)|(?=.*W+))(?![.n])(?=.*[A-Z])(?=.*[a-z]).*$”) return $pw}
I like your elegant solution, but I am not sure I like specifying the minimum number of special characters to include within the generated password. I suppose a person could randomize this to provide more of a random password.
Hi NetSec4u,
Nice one!
Only one small functional risk to your function… it may become too complex for users to remember 🙁
But if it’s only a password for ‘first use’ and they’ll have to change it afterwards, I think your function would be ‘better’ 🙂 #kudos
Jeff.
beautiful
Nice, thanks Jeff! So I was playing with your function, and looking to meet Windows complexity requirements. The first result failed.
i;e|uyfa
Note that both Get-Random and generatePassword are not specified to return secure random values, so you shouldn’t trust them to create security sensitive items like passwords. Securely generating random numbers is difficult and these functions may well be doing it wrong.
Hi “Me”,
Please share any improvements you describe… how would you do it?
Jeff.