Generating a New Password with Windows PowerShell

Generating a New Password with Windows PowerShell

  • Comments 7
  • Likes

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 www.powershell.org 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:

GET-RANDOM

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() {

Param(

[int]$length=10,

[string[]]$sourcedata

)

 

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

YYEGQXCBHTHOBIHSGDL

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

XWsX=yxlJxRW85#dF9'#eu%Qe[jjRZbzCU&M+w6"_*H

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

tPl/kN-%R

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.

$ascii=$NULL;

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

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

l8_[mzx[u

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

$PW | 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’…

~Sean

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 scripter@microsoft.com, or post your questions on the Official Scripting Guys Forum. See you tomorrow. Until then, peace.

Ed Wilson, Microsoft Scripting Guy

Your comment has been posted.   Close
Thank you, your comment requires moderation so it may take a while to appear.   Close
Leave a Comment
  • I suppose you could write a custom function, but why not just call  [System.Web.Security.Membership]::GeneratePassword()

  • @Casey

    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 Poshcode.org 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 :)

    Cheers!

    Sean

    "The Energized Tech"

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

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

  • 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!
    ...
    v&O@1[qP
    v&O@1[qP
    v&O@1[qP
    gaFUksNk
    gaFUksNk
    gaFUksNk
    +0X@9QG@
    +0X@9QG@
    +0X@9QG@
    ...

  • @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.