I often get tasked with finding out where some of the limits of our products might be and one of them that has come up is the ability to work with larger Active Directory configurations. Running a lab I obviously don’t have thousands of users so I wanted a way to quickly create and remove users and groups. In comes the powershell scripts that I have below. I created this is multiple parts but have since made each part a function and put a nice menu around it. The final BulkAdd.ps1 is the total script that you are free to download and use for your environment. You can follow the flow in the diagram below.
You can get the full script Bulk-Menu_v2 but I will list all the parts below. All of the scripts start the same way and I have some centralized variables at the top of the main script.
You can see the script in action
100 Groups and 200 Users Created and Removed in 2 Min
- Intro and Variables
- Create User Function
- Create Group Function
- Delete User Function
- Delete Group Function
- Confirm Account Function
- Sub Menus
- Menus
- Main Code Section
Intro and Variables
This section will be needed to talk to Active Directory
# Import active directory module for running AD cmdlets
Import-Module activedirectory
This section is all on variables
#Get Domain Base
$searchbase = Get-ADDomain | ForEach { $_.DistinguishedName }
#User Info for Bulk user Creation
$Username = "Demo"
$Password = "P@ssw0rd"
$Firstname = "Demo"
$Lastname = "User"
#OU That Users will be placed in - Both are needed for now
$User_OU = "OU=BulkUsers"
#Name of Security Group that all Users will be placed in
$Group = "BulkUsers"
#Starting Security Group Name - Numbers will be added to the end starting at 1
$Sec_Group = "Demo_Group"
#OU that groups will be place in
$Bulk_Group_OU = "OU=BulkGroups"
Create User Function
This will confirm the OU already exists, then check if the user already exists before looping to create the users until the number of users requested. The numbers of users needs to be passed to the function as a parameter.
function Create-Users
{
#Parameters
Param([int]$maxusers)
#Check if the User OU exists
$UserOUcheck = [ADSI]::Exists("LDAP://$($User_OU),$($searchbase)")
New-ADGroup -GroupScope Global -Name $group -GroupCategory Security -Path $path
#Loop through all range of users to create
ForEach ($i In 1..$maxusers)
{
$Account = $Username+$i
If ($UserOUcheck -eq $True)
{
Try
{
#Check if the User already exists
$exists = Get-ADUser $Account
Write-Host "User $($Account) already exists! User creation skipped!"
}
Catch
{
#Create the user if it doesn't exist
$create = New-ADUser -Name $Account -Enabled $True -Path $path -AccountPassword (convertto-securestring $Password -AsPlainText -Force) -ChangePasswordAtLogon $False
Add-ADPrincipalGroupMembership $Account -MemberOf $Group
Write-Host "User $($Account) created and added to the $($Group) group!"
}
}
Else
{
Write-Host "Target OU $($User_OU) can't be found in $($searchbase)! User creation skipped!"
}
}}
Create Group Function
The function to create the groups uses two parameter when passed through, it needs the number of groups requested along with a user account that will be placed in all the groups. The script will then check to make sure the OU needed exists and then if the group exists before creating the group. The user validation is done with a separate function.
function Create-Groups
{
#Parameters
Param(
[int]$maxgroups,
[string]$user)
#Check if the Group OU exists
$GroupOUcheck = [ADSI]::Exists("LDAP://$($Bulk_Group_OU),$($searchbase)")
#Loop through all range of users to create
ForEach ($i In 1..$maxgroups)
{
$Sec_GroupName = $Sec_Group+$i
If ($GroupOUcheck -eq $True)
{
Try
{
#Check if the Group already exists
$exists = Get-ADGroup $Sec_GroupName
Write-Host "Group $($Sec_GroupName) already exists! Group creation skipped!"
}
Catch
{
#Create the group if it doesn't exist
$create = New-ADGroup -Name $Sec_GroupName -GroupScope Global -Path ($($Bulk_Group_OU)+","+$($searchbase))
Add-ADPrincipalGroupMembership $AdminUser -MemberOf $Sec_GroupName
Write-Host "Group $($Sec_GroupName) created with user $($AdminUser) included!"
}
}
Else
{
Write-Host "Target OU $($Bulk_Group_OU) can't be found in $($searchbase)! User creation skipped!"
}
}
}
Delete User Function
Deleting the user takes a smaller function. This also though asks for the number of users that you plan do delete. At the end we also delete the group that was created for the bulk user creation.
function Remove-Users
{
#Parameters
Param([int]$maxusers)
#Loop through all range of users to delete
ForEach ($i In 1..$maxusers)
{
#Check if the OU exists
$check = [ADSI]::Exists("LDAP://$($User_OU),$($searchbase)")
$Account = $Username+$i
If ($check -eq $True)
{
#Remove the User Account
Remove-ADUser -Identity $Account -Confirm:$false
Write-Host "User $($Account) has been deleted!"
}
Else
{
Write-Host "Target OU $($OU) can't be found in $($searchbase)! User deletion skipped!"
}
}
Remove-ADGroup -Identity $group -Confirm:$False
}
Delete Group Function
This will remove the groups that have been placed in the OU. First checking that the OU exists.
function Remove-Groups
{
#Parameters
Param(
[int]$maxgroups
)
#Loop through all range of users to create
ForEach ($i In 1..$maxgroups)
{
#Check if the OU exists
$GroupOUcheck = [ADSI]::Exists("LDAP://$($Bulk_Group_OU),$($searchbase)")
$Sec_Group_Name = $Sec_Group+$i
If ($GroupOUcheck -eq $True)
{
#Remove the Security Group
Remove-ADGroup -Identity $Sec_Group_Name -Confirm:$false
Write-Host "Group $($Sec_Group_Name) has been deleted!"
}
Else
{
Write-Host "Target OU $($Bulk_Group_OU) can't be found in $($searchbase)! Group deletion skipped!"
}
}
}
Confirm Account Function
This function confirms that the account being added to the groups is a valid account and will not let you continue otherwise.
function Check-Account
{
#Parameters
Param ($User)
#Check if the Account exists
do
{
If (dsquery user -samid $user)
{
Write-Host "User Account Confirmed - $($user)"
}
Else
{
Write-Host "User $($user) does not exist."
$user = Read-Host -Prompt "Enter a valid account?"
}
}
until (dsquery user -samid $user)}
Sub-Menus
I broke the menu down into multiple functions. One for each of the 4 categories. This is primarily because each does some checking to confirm you are entering the correct information like not deleting more groups than exist. These also check that there are groups or users present if you try to remove either when there are not any present yet.
function Create-Groups-Menu
{
cls
Write-Host "================ Security Group Creation ================="
write-host ""
$groupcount = Read-Host -Prompt "How many groups would you like to create?"
write-host ""
$User = Read-Host -Prompt "What account would you like to be added to all groups?"
write-host ""
Check-Account -User $User
Write-Host "This will create $($groupcount) security groups and add the $($AdminUser) account to all of them,"
Write-Host "if you dont want this Ctrl-C out of the script now"
pause
Write-Host ""
Create-Groups -maxgroups $groupcount -user $AdminUser
}
function Create-Users-Menu
{
cls
Write-Host "================ User Account Creation ================"
Write-Host ""
$usercount = Read-Host -Prompt "How many users would you like to create?"
Write-Host ""
Write-Host "This will create $($usercount) User Accounts in the new $($group) security group,"
Write-Host "if you dont want this Ctrl-C out of the script now"
pause
Write-Host ""
Create-Users -maxusers $usercount
}
function Delete-Groups-Menu
{
cls
Write-Host "================ Security Group Deletion ================"
Write-Host ""
$CurrentGroupCount = (Get-ADGroup -Filter * -SearchBase ($($Bulk_Group_OU)+","+$($searchbase))).count
Write-Host "You currently have $($CurrentGroupCount) in $($Bulk_Group_OU) "
#Check for No groups present
If ($CurrentGroupCount -eq 0)
{
Write-Host "You do not have any groups to delete"
return
}
ELSE
{
Write-Host ""
$groupcount = Read-Host -Prompt "How many groups would you like to delete?"
#Check Input for # of groups
Do
{
If ($groupcount -gt $CurrentGroupCount)
{
Write-Host "You can only delete $CurrentGroupCount groups."
$groupcount = Read-Host -Prompt "How many groups would you like to delete?"
}
Else
{
Write-Host ""
Write-Host "This will delete $($groupcount) groups from the $($Bulk_Group_OU),"
Write-Host "if you dont want this Ctrl-C out of the script now"
pause
}
}
until ($groupcount -le $CurrentgroupCount)
Write-Host ""
Remove-Groups -maxgroups $groupcount
}
}
function Delete-Users-Menu
{
cls
Write-Host "================ User Account Deletion ================"
Write-Host ""
$CurrentUserCount = (Get-ADUser -Filter * -SearchBase ($($User_OU)+","+$($searchbase))).count
Write-Host "You currently have $CurrentUserCount in $User_OU"
#Check for No accounts present
If ($CurrentUserCount -eq 0)
{
Write-Host "You do not have any accounts to delete"
return
}
ELSE
{
Write-Host ""
$usercount = Read-Host -Prompt "How many users would you like to delete?"
#Check input for # of Users
Do
{
If ($usercount -gt $CurrentUserCount)
{
Write-Host "You can only delete $CurrentUserCount accounts."
$usercount = Read-Host -Prompt "How Many users would you like to delete?"
}
Else
{
Write-Host ""
Write-Host "This will delete $usercount User Accounts in the $group security group,"
Write-Host "if you dont want this Ctrl-C out of the script now"
pause
}
}
until ($usercount -le $CurrentUserCount)
Write-Host ""
Remove-Users -maxusers $usercount
}
}
Main Menus
This section will show the first menu you see
function Show-Menu
{
param (
[string]$Title = 'Bulk User and Group Creation'
)
cls
Write-Host "================ $Title ================"
Write-Host " To Utilize this script you must first have created"
Write-Host "the BulkGroups and/or BulkUsers OU and have rights to AD"
Write-Host ""
Write-Host "1: Press '1' to create bulk groups."
Write-Host "2: Press '2' to create bulk users."
Write-Host "3: Press '3' to delete bulk groups."
Write-Host "4: Press '4' to delete bulk users."
Write-Host "Q: Press 'Q' to quit."
}
Main Code
This section calls the menus and the initial input and loops until you press “q” to quit.
do
{
Show-Menu
$input = Read-Host "Please make a selection"
switch ($input)
{
'1' {
#Create Groups
Create-Groups-Menu
} '2' {
#Create Users
Create-Users-Menu
} '3' {
#Remove Groups
Delete-Groups-Menu
} '4' {
#Remove Users
Delete-Users-Menu
} 'q' {
return
}
}
pause
}
until ($input -eq 'q')
I would love to hear what suggestion and comments you have to make this better. It has the process much faster for me and hopefully it helps you.
Thank you for this article