On a project earlier this year, I had to create random passwords for user accounts as part of a provisioning tool. Perpetually trying to find the fastest way to do something, I came up with a one-liner that you can use to create a random text string from the following ASCII printable characters:
!”#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_abcdefghijklmnopqrstuvwxyz{|}~0123456789
To create the passwords, I use this bit of magic:
PS> $Password = ([char[]]([char]33..[char]95) + ([char[]]([char]97..[char]126)) + 0..9 | sort {Get-Random})[0..8] -join '' PS> $Password Z-=$fNgb!
That will create an 9 character password using the range operator [0..8]. And, if you want to concatenate it with a plaintext counterpart:
PS> $Password = ([char[]]([char]33..[char]95) + ([char[]]([char]97..[char]126)) + 0..9 | sort {Get-Random})[0..8] -join '' PS> $Password = "Welcome"+$Password PS> $Password WelcomeZ-=$fNgb!
Maybe not the most difficult passwords in the world, but probably good enough to give new users the first time they log on to a system.
But then, I found this gem, too:
$Password = "Welcome" + ([System.Web.Security.Membership]::GeneratePassword(x,y))
Where:
x = length in characters y = minimum number of non-alphanumeric characters
With “y”, you’ll specify a number from 0 to a maximum of what “x” is.
What ideas do you have?
Thank you so much 🙂
thumbs up
As this post is well over a year old, you probably already know that “y” is the MINUMIM number of non-alphanumeric characters – it’s not possible to specify the exact number
Yes. I’ve updated the post accordingly.
I recently found a method that uses the System.Web method from .NET framework. The below script will generate 10 passwords with eight characters, and will have at least 1 non-alphanumeric character. Gives me the ability to choose a suitable password for my end user:
[Reflection.Assembly]::LoadWithPartialName(“System.Web”)
$i = 0
while ($i -lt 9) {
[System.Web.Security.Membership]::GeneratePassword(8,0)
$i++
}
Oh, excellent! Thanks! I’ll check it out!
I found small limitation in your script – it will use each character exactly once. This somehow bother me, and it also slightly decrease the complexity :-o, finally the length of password is always same :-o, so here is my take on it:
$asci = [char[]]([char]33..[char]95) + ([char[]]([char]97..[char]126))
$password = (1..$(Get-Random -Minimum 9 -Maximum 14) | % {$asci | get-random}) -join “”
Thank you for this script. I ran a quick loop to check and like the results. I only wish I could exclude one character that has given me trouble in cloudformation scripts. The Ampersand (Char 37).
Here is my quick loop script to validate this one liner.
0..9 | % {$Password = ([char[]]([char]33..[char]95) + ([char[]]([char]97..[char]126)) + 0..9 | sort {Get-Random})[0..15] -join ”;$Password}
Returns nine 16 character passwords.
[{\7>h8<(R1MQj@,
YX7ua"%j?V^PyS-b
O%P2uA7E-hw@6oH^
Ngs~KvE-T8G5Wu%7
uR9=x)S2nDC,z7"H
j)|a<7s(LO_2W31Q
c<x5%pw4svybq,Yt
G%Npu17W'vA*t4QS
7V1[2ihr5cgq|=^y
e5S?gf_41<5@o8O}
You could use the Replace(x,y) method on your final password (in this example, I replace the & with the number 5):
0..9 | % {$Password = ([char[]]([char]33..[char]95) + ([char[]]([char]97..[char]126)) + 0..9 | sort {Get-Random})[0..15] -join ”;$Password.Replace(“&”,”5″)}
L%64uBV:\Epqk,mU
l9V@/0cTW(‘gn,.[
IO]G2f5;5$137″g(
.:wIa00f”lFQimLg
*i52^DTLm$@z,\!r
2d\c4;LBy)D9!*U’
_p”)i!6^dJP95/Bq
W6602″xB\fev-Lcp
<P|[uYF}mnbi3~6S
0:9nQ{W@h\da5;p4
Didn’t work for me.
What version of PowerShell are you using?
I tested in both Windows Server 2012 and 2008 R2:
PS C:\> $PSVersionTable
Name Value
—- —–
CLRVersion 2.0.50727.5485
BuildVersion 6.1.7601.17514
PSVersion 2.0
WSManStackVersion 2.0
PSCompatibleVersions {1.0, 2.0}
SerializationVersion 1.1.0.1
PSRemotingProtocolVersion 2.1
PS C:\> $Password = ([char[]]([char]33..[char]95) + ([char[]]([char]97..[char]126)) + 0..9 | sort {Get-Random})[0..8] -j
oin ”
PS C:\> $Password
E8{(f)1@T
PS C:\>
———-
PS C:\> $PSVersionTable
Name Value
—- —–
PSVersion 4.0
WSManStackVersion 3.0
SerializationVersion 1.1.0.1
CLRVersion 4.0.30319.34209
BuildVersion 6.3.9600.17400
PSCompatibleVersions {1.0, 2.0, 3.0, 4.0}
PSRemotingProtocolVersion 2.2
PS C:\> $Password = ([char[]]([char]33..[char]95) + ([char[]]([char]97..[char]126)) + 0..9 | sort {Get-Random})[0..8] -join ”
PS C:\> $Password
_bK{a-k0Z
PS C:\>
First, thank you. Second, do you need the “+ 0..9”? I see numbers in the char[33] to char[95] section. I guess it increases the chance for a number to be included.
Joe–you are right. 0-9 are included in the earlier [char] ranges. I included it again, though, since the problem I found is that if you’re using any password complexity filters, it was occasionally possible to generate a password that only included letters. Once you introduce those extra 10 digits, the probability of you generating a password that the system won’t accept is much lower.
Maybe there’s a slick way to create a one-liner that pulls “n” number of characters from various character groups to ensure complexity rules are matched?
Thanks
very cool