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.”

Somebody Brilliant

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 (UppercaseLowercaseNumerical, 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
    }
} 
The basic function that we’re going to create will look like this:

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!

OTHER POSTS YOU WANT TO READ

Index Scripts for Windows Search

So you just finished writing some code and you go to save your file. You summarize all of the important aspects this section of code contains into a nice, easy-to-read file name that your future self will immediately recognize. Fast forward to the future where you...

Array vs ArrayList (PowerShell)

For some tasks in life, being precise is a necessity. But most of us get away with rounding, paraphrasing, and hitting in the general vicinity most of the time. Depending on your personality, you may be one who strives for perfection and strains on every miniscule...

Spice Up HTML Emails with PowerShell – Part III

So far in this series we've fumbled our way around the kitchen and tried to wing it when sending HTML emails with PowerShell. It was clunky to say the least. We then went through our spice rack and built an HTML template, highlighting the nuances of each spicy element...

Spice up HTML Emails with PowerShell – Part II

In Part I of our scrumptious concoction we put our script into the oven to let it bake. But we forgot to add our secret sauce that's sure to leave our recipients drooling, which is clearly our goal. In this post we'll continue to spice up HTML emails with PowerShell...

Spice Up HTML Emails with PowerShell – Part I

I live in the South, specifically in God's country AKA TEXAS BABAY! There's plenty of amazing things about Texas and definitely some reasons to loathe being from Houston, but it's hard to knock our food. I mean, is there really even a debate between Whataburger vs...
%d bloggers like this: