I’m a fan of using correcthorsebatterystaple.net for generating temporary passwords for users, rather than always using a static password. The site itself is a reference to the XKCD webcomic, and yes, I’m aware that there are plenty of opinions on the web about this topic.
I’ve had the idea in the back of my mind for a while to see if I could replicate the site’s functionality in PowerShell. I noticed that the source code for the site is on GitHub, so I ducked over there to check out the word list.
I found that it’s possible to replicate most of the functionality of the site with just two lines of PowerShell (although it doesn’t result in very readable code):
- I used Invoke-WebRequest to grab the word list from GitHub
- I then expanded out the Content property, and split it up given the comma delimiter
- I then used a combination of the Range operator, Foreach-Object, [string]::join,Get-Random and the TextInfo class to generate a given number of passwords along these rules:
- 4 random words, each with the first letter capitalised
- A separator in between
- A random number between 1 and 99 at the end
Note that this isn’t failure-proof, and isn’t intended to be used in any complex scenario. There’s no error handling, and not much flexibility built in. It’s just a quick function you could put into your PowerShell profile.
You can, at least, do the following:
Here’s the code:
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
function Get-RandomPassword { | |
[OutputType([string])] | |
Param | |
( | |
[int] | |
$Count = 1, | |
[string] | |
$Separator = '–' | |
) | |
$words = (Invoke-WebRequest 'https://bitbucket.org/jvdl/correcthorsebatterystaple/raw/773dbccc9b9e1320f076c432d600f19785c41792/data/wordlist.txt' | Select-Object –ExpandProperty Content).Split(',') | |
1..$Count | ForEach-Object {"$([string]::Join($Separator,(1..4 | ForEach-Object {[cultureinfo]::CurrentCulture.TextInfo.ToTitleCase(($words | Get-Random))})))$Separator$(1..99 | Get-Random)"} | |
} |