Quick Script Share - Adding A Bunch Of Random Test Users To Active Directory
I recently had a need to add a bunch of random users to a specific OU in Active Directory to do some testing. I didn’t care what their names were, but, I wanted to be able to find all the users that belonged to each batch. Here’s the script I wrote to do this.
#requires -Version 2 -Modules ActiveDirectory
<#
.Synopsis
Adds a bunch of dummy users to Active Directory.
.Description
Prompts a user for an OU in their AD and makes a bunch of random users in that OU.
.Example
New-RandomADUsers.ps1
Runs the script with default paramaters, will prompt for an OU
.Example
New-RandomADUsers.ps1 -OU 'OU=testing,OU=workingsysadmin,DC=lab,DC=workingsysadmin,DC=com' -Count 10
Creates 10 random users in the specified OU
.Parameter OU
The OU to create random users in. Takes a distinguished name.
.Parameter Count
How many new users to create. Defaults to 10.
.Parameter Password
The password to assign to all the created users. Defaults to 'P@ssw0rd'.
.Notes
NAME: New-RandomADUsers.ps1
AUTHOR: Thomas Rayner
LASTEDIT: 04/15/2016
KEYWORDS:
.Link
https://thomasrayner.ca
#>
[CmdletBinding()]
param
(
[String]
[Parameter(Position=0)]
$OU,
[int]
[Parameter(Position=1)]
$Count = 10,
[string]
[Parameter(Position=2)]
$Password = 'P@ssw0rd'
)
#region FUNCTIONS
##########################START OF FUNCTIONS##########################
#Show a GUI to select an OU
function Select-GUIOU
{
#load required assemblies
[void] [System.Reflection.Assembly]::LoadWithPartialName('System.Windows.Forms')
[void] [System.Reflection.Assembly]::LoadWithPartialName('System.Drawing')
#build the form
$objForm = New-Object System.Windows.Forms.Form
$objForm.Text = 'Select an OU'
$objForm.Size = New-Object System.Drawing.Size(900,430)
$objForm.StartPosition = 'CenterScreen'
#add the OK button
$OKButton = New-Object System.Windows.Forms.Button
$OKButton.Location = New-Object System.Drawing.Size(75,350)
$OKButton.Size = New-Object System.Drawing.Size(75,23)
$OKButton.Text = 'OK'
#assign the OK button to the AcceptButton param
$OKButton.DialogResult = [System.Windows.Forms.DialogResult]::OK
$objForm.Controls.Add($OKButton)
$objForm.AcceptButton = $OKButton
#add the cancel button
$CancelButton = New-Object System.Windows.Forms.Button
$CancelButton.Location = New-Object System.Drawing.Size(150,350)
$CancelButton.Size = New-Object System.Drawing.Size(75,23)
$CancelButton.Text = 'Cancel'
#assign the cancel button to the CancelButton param
$CancelButton.DialogResult = [System.Windows.Forms.DialogResult]::Cancel
$objForm.Controls.Add($CancelButton)
$objForm.CancelButton = $CancelButton
#add the Select OU label
$objLabel = New-Object System.Windows.Forms.Label
$objLabel.Location = New-Object System.Drawing.Size(10,20)
$objLabel.Size = New-Object System.Drawing.Size(400,20)
$objLabel.Text = "Please select an OU. Don't see one you want? Cancel and create it."
$objForm.Controls.Add($objLabel)
#add the listbox to select an OU from
$objListBox = New-Object System.Windows.Forms.ListBox
$objListBox.Location = New-Object System.Drawing.Size(10,40)
$objListBox.Size = New-Object System.Drawing.Size(860,90)
$objListBox.Height = 300
#get all the OUs in the organization, sort them alphabetically and add them to the listbox
$OUs = Get-ADOrganizationalUnit -filter '*'
$OUs | Sort-Object | % { [void] $objListBox.Items.Add($_) }
#add the listbox to the form
$objForm.Controls.Add($objListBox)
#open this window on top of other windows
$objForm.TopMost = $True
#return the OU selected
$result = $objForm.ShowDialog()
#if the user clicks OK and selected an OU, return it
if ($result -eq [System.Windows.Forms.DialogResult]::OK -and $objListBox.SelectedIndex -ge 0)
{
$selection = $objListBox.SelectedItem
return $selection
}
else
{
throw { 'Did not select an OU. Script terminated.' }
}
}
#Get the OU to create users in
function Get-OU
{
[CmdletBinding()]
param
(
[String]
[Parameter(Position=0)]
$OU
)
#if there was no OU passed, select one using the GUI
if ([string]::IsNullOrEmpty($OU))
{
return $(Select-GUIOU).DistinguishedName
}
#if there was an OU passed, validate it exists
else
{
#try to get the OU, if this is successful, return the value we used to find it (should be a DN)
try
{
$TestOU = Get-ADOrganizationalUnit -Identity $OU
return $TestOU.DistinguishedName
}
#if we couldn't find an OU with the name specified, use the GUI to find a new one
catch [Exception]
{
Write-Output "[Oops] Couldn't find an OU that matched $OU so I made you pick again"
return $(Select-GUIOU).DistinguishedName
}
}
}
###########################END OF FUNCTIONS###########################
#endregion
#validate the OU is set to something valid, communicate valid OU to user
$OU = Get-OU $OU
Write-Output "Selected OU: $OU"
#don't need to validate Count because the param block that leads this script will throw an error if Count isn't an integer...
#... assuming users are smart enough to enter a positive number (for loop below will throw an index error and nothing bad should happen)
Write-Output "Selected Count: $Count"
#create array of all upper and lowercase letters (char code representative)
$Upper = (65..90)
$Lower = (97..122)
#create an ID for this batch of created users
$ID = (Get-Date).Ticks
#create $count many users
$null = for ($i = 0; $i -lt $Count; $i++)
{
#make a random first name, first initial capitalized
$Initial = Get-Random -InputObject $Upper -Count 1 | % { [char]$_ }
$RestOfname = Get-Random -InputObject $Lower -Count 4 | % { [char]$_ }
$FirstName = $Initial + $RestOfName -replace ' ',''
#make a random last name, first initial capitalized
$Initial = Get-Random -InputObject $Upper -Count 1 | % { [char]$_ }
$RestOfname = Get-Random -InputObject $Lower -Count 4 | % { [char]$_ }
$LastName = $Initial + $RestOfName -replace ' ',''
#craft the displayname, name, samaccountname, UPN attributes
#in the future, this will detect name collisions and mitigate
$DisplayName = "$FirstName $LastName"
$Name = $DisplayName
$SamAccountName = "$($FirstName[0])$LastName" #first initial last name, IE: Thomas Rayner becomes TRayner
$UPN = $SamAccountName + '@' + (Get-ADDomain).DNSRoot #UPN suffix won't always be the value of (Get-ADDomain).DNSRoot but it usually is... this is why you read scripts before running them
#assign the password
$AccountPassword = ConvertTo-SecureString -AsPlainText $Password -Force
#create description that can be used to group users created in different batches
$Description = "Created by MVP Tool: New-RandomADUsers.ps1. Batch: $ID"
#announce the creation of a user
Write-Output "Creating $Name. Username: $SamAccountName"
#add all the params to the user list
$UserParams = @{}
$UserParams.Add('GivenName',$FirstName)
$UserParams.Add('Surname',$LastName)
$UserParams.Add('DisplayName',$DisplayName)
$UserParams.Add('Name',$Name)
$UserParams.Add('SamAccountName',$SamAccountName)
$UserParams.Add('AccountPassword',$AccountPassword)
$UserParams.Add('Description',$Description)
$UserParams.Add('Path',$OU) #put them all in the OU we created
$UserParams.Add('Enabled',$True) #enable the account
#create the AD user
New-ADUser @UserParams
}
#list the users created, verify they can be found in AD
$CreatedUsers = (Get-ADUser -SearchBase $OU -Filter "Description -like '*$ID*'").SamAccountName
Write-Output 'Created following users'
$CreatedUsers
Written on April 15, 2016