So far in this series (Bulk Create Users in AD), we’ve created the CSV file and made sure we could create a user first. We then proceeded with writing a loop to go through each user, which we also did. Now what? Well, we still have a couple of things to do before we pull the trigger on this bad mama jama. Welcome to Part III.
\\\Random Passwords
To start with, what about randomizing passwords? How do we create unique passwords? Don’t worry, all passwords are special in their own way (just like momma always said), but we want each user to have a different password as a best practice. And like my great grandfather’s cousin’s uncle used to always say:
“Best Practices make perfect.”
We have a couple of options when doing this:
Option 1 - The Way of the Manual
Open a browser, google search a random password generator online, generate said random password, use the ol’ copy and paste.
+1
It will work, but it will feel like work:
Option 2 - The Way of the Headbanger
Click “Start,” open up “Notepad,” and then smash your head repeatedly into your keyboard and then copy what you “typed.”
-2
The password will definitely be random but this method brings up certain long term concerns to the health of your keyboard as well as your forehead. You should build a machine to do it instead.
Option 3 - The Way of the Coward
Call a super awesome tool (like www.passwordrandom.com) that will generate a random password and may even brush our teeth for us too. Nice, as long as the site is up.
+2ish
It will work, and it’s exactly what we need, and somebody already did the work for us. There’s absolutely no reason not to go with this one. But what if we WANT to reinvent the wheel!? What then???
Option 4 - The Way of the Warrior
Write your own dang generator. (mic drop)
-5
This is a bad idea and quite unnecessary. We really should avoid this, but what about the feeling of deep accomplishment you’ll get from fulfilling your destiny??
Clearly, we’re going to go with Option 4, the path that leads to doom and gloom without a safety net or a security blanket that’s filled with wet willies and possible swirlies. Oh boy! I can’t wait!
\\\Thought Process
And of course, there are a trillion ways to do this but like a Magic School Bus field trip inside my mind, here are my exact thoughts as they bounced around my internal processing department upstairs:
- Me thinks to myself, I want to write it as a function, so I can easily call it in the ForEach loop.
- I want some degree of control (length of the password) but don’t want to define every single aspect: how many characters of each type, variations of complexity, options to not include special characters, etc. I’m thinking more Apple and less Android. Man, that hurts to even say…or think…or type…
- Out of the 4 types of characters (Uppercase, Lowercase, Numerical, and Special), I feel like lowercase should be weighted the most and the others could be equal. It’s science really.
- I decided to go all mathmagician on it and make the 4 types proportionate to the total length: 40% Lowercase and 20% for the other 3 types, which I believe totals 100%.
- Depending on the length desired, I’m thinking I can use the Round method in the [math] class (that thing you flunked in HS) to get a nice, round number. I see what I did there.
\\\Writing the Function
Easy enough? After some trial and error and, of course, several cups of coffee, here’s what I ended up with:
#Randomize Passwords the hard way, Option4
function Get-RandomPassword{
Param(
[Parameter(mandatory=$true)]
[int]$Length
)
Begin{
if($Length -lt 4){
End
}
$Numbers = 1..9
$LettersLower = 'abcdefghijklmnopqrstuvwxyz'.ToCharArray()
$LettersUpper = 'ABCEDEFHIJKLMNOPQRSTUVWXYZ'.ToCharArray()
$Special = '!@#$%^&*()=+[{}]/?<>'.ToCharArray()
#For the 4 character types (upper, lower, numerical, and special),
#let's do a little bit of math magic
$N_Count = [math]::Round($Length*.2)
$L_Count = [math]::Round($Length*.4)
$U_Count = [math]::Round($Length*.2)
$S_Count = [math]::Round($Length*.2)
}
Process{
$Pwd = $LettersLower | Get-Random -Count $L_Count
$Pwd += $Numbers | Get-Random -Count $N_Count
$Pwd += $LettersUpper | Get-Random -Count $U_Count
$Pwd += $Special | Get-Random -Count $S_Count
#If the password length isn't long enough (due to rounding),
#add X special characters, where X is the difference between
#the desired length and the current length.
if($Pwd.length -lt $Length){
$Pwd += $Special | Get-Random -Count ($Length - $Pwd.length)
}
#Lastly, grab the $Pwd string and randomize the order
$Pwd = ($Pwd | Get-Random -Count $Length) -join ""
}
End{
$Pwd
}
}
function Get-RandomPassword{
Param()
Begin{}
Process{}
End{}
}
Parameters: To keep it simple, we’ll only define 1 parameter: $Length, defined as an integer and mandatory.
Param(
[Parameter(mandatory=$true)]
[int]$Length
)
Begin: If the $Length is defined as 4, don’t keep going because that’s too short of a password. Next, we’ll define $Numbers, $LettersLower, $LettersUpper, and $Special variables that we’ll use to choose random characters from. We then define a “Count” ($N_Count, $L_Count, $U_Count, and $S_Count) which will be the $Length multiplied by a percentage and then rounded to a whole number. This is so we know how many characters of each type we’re going to have.
Begin{
if($Length -lt 4){
Return
}
$Numbers = 1..9
$LettersLower = 'abcdefghijklmnopqrstuvwxyz'.ToCharArray()
$LettersUpper = 'ABCEDEFHIJKLMNOPQRSTUVWXYZ'.ToCharArray()
$Special = '!@#$%^&*()=+[{}]/?<>'.ToCharArray()
#For the 4 character types (upper, lower, numerical, and special),
#let's do a little bit of math magic
$N_Count = [math]::Round($Length*.2)
$L_Count = [math]::Round($Length*.4)
$U_Count = [math]::Round($Length*.2)
$S_Count = [math]::Round($Length*.2)
}
Process: We’re going to build our $Pwd string by starting with the $LettersLower and piping to the Get-Random cmdlet and specifying the number of random characters we want to grab with the -Count parameter. Repeat this with the $Numbers, $LettersUpper, and $Special. Next we want to check to make sure the $Pwd length isn’t less than the $Length that was specified (due to rounding down). If it is less, choose however many characters we’re missing from the $Special characters. Finally, we’re going to randomize the $Pwd order.
Process{
$Pwd = $LettersLower | Get-Random -Count $L_Count
$Pwd += $Numbers | Get-Random -Count $N_Count
$Pwd += $LettersUpper | Get-Random -Count $U_Count
$Pwd += $Special | Get-Random -Count $S_Count
#If the password length isn't long enough (due to rounding),
#add X special characters, where X is the difference between
#the desired length and the current length.
if($Pwd.length -lt $Length){
$Pwd += $Special | Get-Random -Count ($Length - $Pwd.length)
}
#Lastly, grab the $Pwd string and randomize the order
$Pwd = ($Pwd | Get-Random -Count $Length) -join ""
}
End: When we call the function, we want it to output the random password so we only need to add the $Pwd variable at the end.
End{
$Pwd
}
\\\Testing The Function
Now that we have the function written, let’s give it a whirl and witness the magic (and secretly make sure nothing blows up in the process):

Kylo approves of passwords 105 characters in length, which is important to us for some reason. Episode 8 was horrible. That’s all I have to say.
\\\Using the Function
Neato gang! Let’s take our existing code we’ve written from Part 1 and 2 of the Bulk Create Users in AD series and add some zest to it. We’ll add this function above our ForEach loop and then inside the loop we’ll define a new variable called $Pwd (that way we’ll have in plain text to write back to our CSV file later) and use it with the ConvertTo-SecureString cmdlet when we define the AccountPassword value. Finally, our ForEach loop now looks this:
#Nearly Complete Loop with dynamic variables
#(+ the $Pwd variable using our new Get-RandomPassword function)
Foreach($U in $Users){
#Define Name Variations
$FirstDotLast = "$($U.First).$($U.Last)"
$Display = "$($U.First) $($U.Last)"
$UPN = "$FirstDotLast@empire.local"
$Pwd = Get-RandomPassword -Length 8
#Define Parameters
$Parameters = @{
Name = $FirstDotLast
GivenName = $U.First
Surname = $U.Last
SamAccountName = $FirstDotLast
DisplayName = $Display
UserPrincipalName = $UPN
AccountPassword = (ConvertTo-SecureString $Pwd -AsPlainText -Force)
Enabled = $true
ChangePasswordAtLogon = $true
Title = $U.Title
OtherAttributes = @{"Allegiance"=$U.Allegiance;"Species"=$U.Species}
}
#Create New User in AD with the Parameters defined
New-ADUser @Parameters
}
Now that we can generate a random password and we’ve added it into our loop, we have a few steps left to finish this script off. I mean, setting a random password is great and all, but how do we know what random password we set for each user? How do we relay that information to them? Check out Part IV of the Bulk Create Users in AD series to see the last steps!