Generating a New Password with Windows PowerShell

Summary: Microsoft Windows PowerShell MVP and Honorary Scripting Guy, Sean Kearney, talks about generating passwords with Windows PowerShell in Windows Server 2012.

Microsoft Scripting Guy, Ed Wilson, is here. If you are a seasoned Hey, Scripting Guy! Blog reader, you know that the most frequent guest blogger is Sean Kearney. If you are new to the blog, I welcome you, and I encourage you to catch up with Sean’s previous blogs.

Sean is a Windows PowerShell MVP and an Honorary Scripting Guy. Sean has been selected to present sessions called Integrating with Microsoft System Center 2012 and Windows PowerShell at TechEd NA and TechEd Europe this year. In his free time, Sean has written several blog posts about Hyper-V and some other cool stuff. Sean will be the blogger all week, and today he is writing about passwords.

BTW, if you are in New Orleans for TechEd this week, be sure to come by the Scripting Guys booth and say hello. The Scripting Wife and I will be there in addition to Chris Duck and Brian Wilhite. We also invited to share the booth with us, so come by say hello to Don Jones, Jason Helmick, and Mike Robbins. I am also sure Sean will be hanging out at the booth.

Take it away Sean…

Generating a password really isn’t too tricky when you think about it. I can run the following cmdlet:


It will immediately produce a 10 character random numeric number. Sure, it could be a really cool pin code for somebody’s voicemail or a really lousy login Password.

Get-Random can even work with random data from an array such as this:

“dog”,”cat”,”rubber chicken” | GET-RANDOM

So we could improve our random Password by submitting a string containing the entire alphabet to the Get-Random cmdlet. First, we generate a variable that contains all of the uppercase characters in the alphabet as a start.

$alphabet=$NULL;For ($a=65;$a –le 90;$a++) {$alphabet+=,[char][byte]$a }

I could then loop through this, say 10 times, to generate a 10-character password. We can build a simple function to meet this need, and supply the raw data and the length of the password as parameters.

Function GET-Temppassword() {






For ($loop=1; $loop –le $length; $loop++) {

            $TempPassword+=($sourcedata | GET-RANDOM)


return $TempPassword


Now we could call up a function to generate a simply random password like this:

GET-Temppassword –length 19 –sourcedata $alphabet


This works well, but only produces a password of UPPERCASE characters. This is hardly anything that would meet most security guidelines. So we can build a bigger character set. We could modify our “Building the alphabet loop,” starting with the first available ASCII character until we basically run out.

$ascii=$NULL;For ($a=33;$a –le 126;$a++) {$ascii+=,[char][byte]$a }

Then we plug this into our function for a Temporary password. Let’s have some fun and hand our user a 43-character password!

GET-Temppassword –length 43 –sourcedata $ascii


Wow! I think we’ve definitely hit the “Password complexity” rules, but I suspect that although Security will be dancing with joy, our Help Desk will get hit severely with staff mistyping this new password.

Of course, simply by limiting the number of characters, we might have a more palatable password…say 9?

GET-Temppassword –length 9 –sourcedata $ascii


Or to really balance things down, we could refine the list of characters to Mostly Alphabetic, Numeric, and a few “Specials” by picking a sequence of ASCII characters that meet our needs.


For ($a=48;$a –le 122;$a++) {$ascii+=,[char][byte]$a }

Running with this combination, we get a slightly more palatable password:


Now here’s another neat trick...

You can pipe this function to a built-in feature in Windows 7 and Windows 8, called clip.exe. This will take the output and place it directly onto the clipboard.

GET-Temppassword –length 9 –sourcedata $ascii | CLIP

Or if you want to generate the password as something useful for a New user, and the cmdlet requires that the password is in a secure-string format, you could do something like this to save it, clip it, and make it secure:

$PW= GET-Temppassword –length 9 –sourcedata $ascii | CLIP


$SecurePW=CONVERTTO-Securestring $PW -asplaintext -force

How you build the source data for generating a password is up to you. There are some excellent scripts in the Script Repository for building passwords in a myriad of ways. What’s important for you, is that you can generate them relatively easily and in methods under your control.

I would suggest avoiding enforcing the 43-character minimum as the limit. Just sayin’…


Thank you, Sean, for a useful and interesting blog post. Join us tomorrow as Sean begins a three-part series about using Windows PowerShell to create home drives.

I invite you to follow me on Twitter and Facebook. If you have any questions, send email to me at, or post your questions on the Official Scripting Guys Forum. See you tomorrow. Until then, peace.

Ed Wilson, Microsoft Scripting Guy

Comments (10)

  1. Casey4 says:

    I suppose you could write a custom function, but why not just call  [System.Web.Security.Membership]::GeneratePassword()

  2. Sean Kearney says:


    An excellent point.  The reason for a Custom function is the options you can leverage to define some more interesting passwords.    For example there was an amazing password generator developed by Joel on that was re-adapted on the TechNet Script Repository which allows more defined passwords.

    Passwords such as

    Purely numeric (Pin code?)

    Pronounceable (yet not dictionary works)

    REALLY Crazy ones for service accounts (Is 44,000 characters enough?)

    I like that method in .NET, it's simple and effective.   But I also like that I can use PowerShell to truly define the parameters of my password in so many unique ways.

    Use the tool that fits your task best 🙂



    "The Energized Tech"

  3. grenade says:

    if you want to lose your `for` loop: `(0..9 + [char[]](48..122) | sort {get-random})[0..12] -join ”`

  4. grenade says:

    actually: `([char[]](48..122) | sort {get-random})[0..12] -join ”`

  5. Andrew says:

    Hi Sean, I have been experimenting with some PS I found on the web to generate a secure password, I’m having some issues in understanding my output while trying to use that function.

    The function outputs a random password of 8 characters whenever I call it normally.

    Now I’m trying to use that function to generate a specific number of passwords like so

    0..50 | foreach | {$passAry += Get-RandomPassword}

    Although this seems to work the output shows repeated passwords. and If I index them individually I also see they are repeated. Please help me understand what I’m missing here! Thank you!


  6. Casey4 says:

    @Andrew Probably you’re running into problems because Get-Random uses a pseudo-random number generator that does not very well approximate true randomness. Another reason to use [System.Web.Security.Membership]::GeneratePassword() instead of implementing
    it yourself.

  7. Drew Novack says:

    # Gets a random password of specified length containing numbers, uppercase letters,

    # lowercase letters and special characters. Minimum length required is 4 characters
    # since password must contain all four types of characters.
    function GetRandomPassword ([int] $length=10) {
    if ($length -lt 4) {return $null}

    # Define list of numbers, this will be CharType 1
    For ($a=48;$a –le 57;$a++) {$numbers+=,[char][byte]$a }

    # Define list of uppercase letters, this will be CharType 2
    For ($a=65;$a –le 90;$a++) {$uppercase+=,[char][byte]$a }

    # Define list of lowercase letters, this will be CharType 3
    For ($a=97;$a –le 122;$a++) {$lowercase+=,[char][byte]$a }

    # Define list of special characters, this will be CharType 4
    For ($a=33;$a –le 47;$a++) {$specialchars+=,[char][byte]$a }
    For ($a=58;$a –le 64;$a++) {$specialchars+=,[char][byte]$a }
    For ($a=123;$a –le 126;$a++) {$specialchars+=,[char][byte]$a }

    # Need to ensure that result contains at least one of each CharType
    # Initialize buffer for each character in the password
    $Buffer = @()
    For ($a=1;$a –le $length;$a++) {$Buffer+=0 }

    # Randomly chose one character to be number
    while ($true) {
    $CharNum = (Get-Random -minimum 0 -maximum $length)
    if ($Buffer[$CharNum] -eq 0) {$Buffer[$CharNum] = 1; break}

    # Randomly chose one character to be uppercase
    while ($true) {
    $CharNum = (Get-Random -minimum 0 -maximum $length)
    if ($Buffer[$CharNum] -eq 0) {$Buffer[$CharNum] = 2; break}

    # Randomly chose one character to be lowercase
    while ($true) {
    $CharNum = (Get-Random -minimum 0 -maximum $length)
    if ($Buffer[$CharNum] -eq 0) {$Buffer[$CharNum] = 3; break}

    # Randomly chose one character to be special
    while ($true) {
    $CharNum = (Get-Random -minimum 0 -maximum $length)
    if ($Buffer[$CharNum] -eq 0) {$Buffer[$CharNum] = 4; break}

    # Cycle through buffer to get a random character from the available types
    # if the buffer already contains the CharType then use that type
    $Password = ""
    foreach ($CharType in $Buffer) {
    if ($CharType -eq 0) {$CharType = ((1,2,3,4)|Get-Random)}
    switch ($CharType) {
    1 {$Password+=($numbers | GET-RANDOM)}
    2 {$Password+=($uppercase | GET-RANDOM)}
    3 {$Password+=($lowercase | GET-RANDOM)}
    4 {$Password+=($specialchars | GET-RANDOM)}
    return $Password

  8. Drew Novack says:

    That was my version using the techniques Sean and Ed showed above. Thought I would share in case anyone else finds it useful.


  9. aaron says:

    Is it possible to exclude specific special characters?

  10. KERR says:

    I use this, but the passwords aren’t pretty:

    Add-Type -AssemblyName System.Web
    [System.Web.Security.Membership]::GeneratePassword(10, 3)

Skip to main content