Creating and Removing AD Users Using PowerShell 2.0 or Newer
I created this script based on a someone elses work, figured why reinvent the wheel.
As the original was not my own I have left the comments in the top section of the script as well as including the source files to give credit where its deserved.
The Remove Users based on group script I wrote from scratch as this was done based on my own initiative to automate tasks done in my work experience.
It is expected that the TAFE Labs will use this long after I am gone and as I wont be getting paid I may as well share it with anyone who wants it.
This is the powershell script for adding users:
###########################################################
# AUTHOR : Marius / Hican - http://www.hican.nl - @hicannl
# DATE : 26-04-2012
# EDIT : 07-08-2014
# COMMENT : This script creates new Active Directory users,
# including different kind of properties, based
# on an input_create_ad_users.csv.
# VERSION : 1.3
###########################################################
# CHANGELOG
# Version 1.2: 15-04-2014 - Changed the code for better
# - Added better Error Handling and Reporting.
# - Changed input file with more logical headers.
# - Added functionality for account Enabled,
# PasswordNeverExpires, ProfilePath, ScriptPath,
# HomeDirectory and HomeDrive
# - Added the option to move every user to a different OU.
# Version 1.3: 08-07-2014
# - Added functionality for ProxyAddresses
##########################################################################################
# CHANGELOG - Leslie
##########################################################################################
###########################################################
# AUTHOR : Leslie - https://www.designwright.com.au
# Email : Ommited for webpage
# DATE : 09-09-2014
# EDIT : 10-09-2014
# COMMENT : This script creates new Active Directory users,
# including different kind of properties, based
# on input_create_ad_users.csv.
# VERSION : 1.6
###########################################################
# Removed unnessacay code for associated fields also modified the imported .csv file
############################
# - OfficeName
# - Description
# - Mail
# - StreetAddress
# - City
# - PostalCode
# - State
# - Country
# - Company
# - Department
# - EmployeeID
# - ExtensionAttribute1
# - Title
# - Phone
# - Manager
# - ProfilePath
# - ScriptPath
# - HomeDirectory
# - HomeDrive
# - ProxyAddresses
# - Added New Field and code for Group
# - Added additional sam account name formatting to prevent possible error exceptions
#------------------------------------------------------------------------------------------------
# - Added new "for" loop for error handling and new users with the same name as an existing user
# - Added functionality to have multiple users with the same names be added with sam account names of
# e.g. Leslie.1, Leslie.2 etc this will be reflected in the output log file in future
# revisions. NOTE: A maximum of 99 has been enforced to prevent addional string manipulation.
# - No longer requires Valid Initials for account creation (removed them from the Sam Account Name)
# - Added email contact details for support requests
# (please note I don't know powershell but I understand programing so this has been a crossover of that skillset)
############################
####################################################################################################################
# Future Planned Modifications Include:
# * Updating the Info Messages and Log outputs for the new error handling on existing users (partially complete)
# * Possible modification to the Log output file format and structure (to excel format for simple distrobution)
#
# * Alternatively Create a Seperate Output For teachers to distribute accounts to students e.g.
# Username, Default Password, Group Name(For class Identification purposes, examples include: CertIV, Dip, CertIII)
####################################################################################################################
# ERROR REPORTING ALL
Set-StrictMode -Version latest
#----------------------------------------------------------
# LOAD ASSEMBLIES AND MODULES
#----------------------------------------------------------
Try
{
Import-Module ActiveDirectory -ErrorAction Stop
}
Catch
{
Write-Host "[ERROR]`t ActiveDirectory Module couldn't be loaded. Script will stop!"
Exit 1
}
#----------------------------------------------------------
#STATIC VARIABLES
#----------------------------------------------------------
$path = Split-Path -parent $MyInvocation.MyCommand.Definition
$newpath = $path + "\import_create_ad_users.csv"
$log = $path + "\log_create_ad_users.log"
$date = Get-Date
$addn = (Get-ADDomain).DistinguishedName
$dnsroot = (Get-ADDomain).DNSRoot
$i = 1
#----------------------------------------------------------
#START FUNCTIONS
#----------------------------------------------------------
Function Start-Commands
{
Create-Users
}
Function Create-Users
{
# Log Start time
"Processing started (on " + $date + "): " | Out-File $log -append
"--------------------------------------------" | Out-File $log -append
# Import the CSV containing the User Account Information to be added
Import-CSV $newpath | ForEach-Object {
#Reset Variable
[int]$attempt = 1
If (($_.Implement.ToLower()) -eq "yes")
{
If (($_.GivenName -eq "") -Or ($_.LastName -eq ""))
{
Write-Host "[ERROR]`t Please provide valid GivenName and LastName. Processing skipped for line $($i)`r`n"
"[ERROR]`t Please provide valid GivenName and LastName. Processing skipped for line $($i)`r`n" | Out-File $log -append
}
Else
{
# Set the target OU
$location = $_.TargetOU + ",$($addn)"
# Set the Enabled and PasswordNeverExpires properties
If (($_.Enabled.ToLower()) -eq "true") { $enabled = $True } Else { $enabled = $False }
If (($_.PasswordNeverExpires.ToLower()) -eq "true") { $expires = $True } Else { $expires = $False }
# Replace dots / points (.) and spaces in SamAccountNames, because AD will error when a
# name ends with a dot or a SamAccountName contains a Space(and it looks cleaner as well)
$replaceLN = $_.Lastname.Replace(".","")
$replaceLN = $replaceLN.Replace(" ","")
$replaceFN = $_.GivenName.Replace(".","")
$replaceFN = $replaceFN.Replace(" ","")
#--------------------------------------------------------------------
#SamAccountName String Manipulation
#--------------------------------------------------------------------
# Create SamAccountName Following this 'naming convention' for TAFE Labs:
# <GivenName><dot><LastName> for example
# Leslie.
$MaxLength = $replaceFN + "." + $replaceLN
# Shorten SamAccountName due to 20 charater limitation
# NOTES: if a firstname.lastname exceeds this limit the
# firstname will be shortened to the first 7 charaters
# and Lastname will be shortened to the first 12 chars
If($MaxLength.length -le 20){}
Else
{
$MaxLength = $replaceFN.substring(0,7) + "." + $replaceLN.substring(0,12)
}
# Create a more appropiately named variable
$sam = $MaxLength
#Set maximum number of Attempts for following loop
[int]$maxAttempts = 99
# Run a Loop to determine if user exists then add one to sam account name and try again
For( [int]$attempt = 1; $attempt -le $maxAttempts; $attempt++ )
{
[bool]$success = $False;
Write-Output "[INFO] Checking if Sam Account Name $($sam) exists`r"
try
{
$exists = Get-ADUser -LDAPFilter "(sAMAccountName=$sam)"
#If account dosen't exist success = true
if(!$exists)
{
Write-Host "[Success] Account does not exist`r"
$success = $True;
}
# Otherwise it does exist so perform string manipulation
Else
{
# new error handing for existing names yet to be implemented
# !!!Caution may cause dupicate accounts for students!!!
$MaxLength = $replaceFN + "." + $replaceLN + "$attempt"
If($MaxLength.length -le 20){}
Else
{
$MaxLength = $replaceFN.substring(0,7) + "." + $replaceLN.substring(0,10) + $attempt
}
# Set $sam as it more accurately descibes the string contents for use
# later in this script.
$sam = $MaxLength
Write-Host "[INFO] Account exists performing string manipulation"
}
}
# catch errors and write to output
catch
{
Write-Host "[INFO]`t Renaming user $($sam)$(+$attempt) failed [Reason]:Exsisting User Found:`r"
}
# If the message succeeded, exit the loop
if($success) { break; }
}
If(!$exists)
{
# Set all variables according to the table names in the Excel
# sheet / import CSV. The names can differ in every project, but
# if the names change, make sure to change it below as well.
$setpass = ConvertTo-SecureString -AsPlainText $_.Password -force
Try
{
Write-Host "[INFO]`t Creating user : $($sam)"
"[INFO]`t Creating user : $($sam)" | Out-File $log -append
New-ADUser $sam -GivenName $_.GivenName -Initials $_.Initials `
-Surname $_.LastName -DisplayName ($_.GivenName + "," + $_.LastName) `
-UserPrincipalName ($sam + "@" + $dnsroot) `
-AccountPassword $setpass `
-PasswordNeverExpires $expires
Write-Host "[INFO]`t Created new user : $($sam)"
"[INFO]`t Created new user : $($sam)" | Out-File $log -append
$dn = (Get-ADUser $sam).DistinguishedName
# Move the user to the OU ($location) you set above. If you don't
# want to move the user(s) and just create them in the global Users
# OU, comment the string below
If ([adsi]::Exists("LDAP://$($location)"))
{
Move-ADObject -Identity $dn -TargetPath $location
Write-Host "[INFO]`t User $sam moved to target OU : $($location)"
"[INFO]`t User $sam moved to target OU : $($location)" | Out-File $log -append
}
Else
{
Write-Host "[ERROR]`t Targeted OU couldn't be found. Newly created user wasn't moved!"
"[ERROR]`t Targeted OU couldn't be found. Newly created user wasn't moved!" | Out-File $log -append
}
# Rename the object to a good looking name (otherwise you see
# the 'ugly' shortened sAMAccountNames as a name in AD. This
# can't be set right away (as sAMAccountName) due to the 20
# character restriction
$newdn = (Get-ADUser $sam).DistinguishedName
Rename-ADObject -Identity $newdn -NewName ($_.GivenName + " " + $_.LastName + $attempt)
Write-Host "[INFO]`t Renamed $($sam) to $($_.GivenName) $($_.LastName)`r"
"[INFO]`t Renamed $($sam) to $($_.GivenName) $($_.LastName)`r`n" | Out-File $log -append
# Add users to Groups
# Written by: Leslie
$add = Add-ADGroupMember ($_.Group) $sam -Confirm:$False
Write-Host "[INFO]`t Added $($sam) to Security Group : $($_.Group)`r`n" | Out-File $log -append
}
Catch
{
Write-Host "[ERROR]`t Oops, something went wrong: $($_.Exception.Message)`r`n"
}
}
Else
{
Write-Host "[SKIP]`t User $($sam) ($($_.GivenName) $($_.LastName)) already exists or returned an error!`r`n"
"[SKIP]`t User $($sam) ($($_.GivenName) $($_.LastName)) already exists or returned an error!" | Out-File $log -append
}
}
}
Else
{
Write-Host "[SKIP]`t User $($sam) ($($_.GivenName) $($_.LastName)) will be skipped for processing!`r`n"
"[SKIP]`t User $($sam) ($($_.GivenName) $($_.LastName)) will be skipped for processing!" | Out-File $log -append
}
$i++
}
"--------------------------------------------" + "`r`n" | Out-File $log -append
}
Write-Host "STARTED SCRIPT`r`n"
Start-Commands
Write-Host "STOPPED SCRIPT"
And this is the PowerShell Script for Removing Users:
###########################################################
# AUTHOR : Leslie https://www.designwright.com.au
# Email : ommited for webpage
# DATE : 09-09-2014
# EDIT : 10-09-2014
# COMMENT : This script removes existing Active Directory
# users based on their group membership.
#
# ~~~~~~~~WARNING~~~~~~
# this will indiscriminately remove a user based on a
# single group membership regardless of what other groups
# they may be a member of!!!!
# ~~~~~~~~~~~~~~~~~~~~~
#
#VERSION : 1.0
#
###########################################################
# CHANGELOG
# None as yet
# ERROR REPORTING ALL
Set-StrictMode -Version latest
#----------------------------------------------------------
# LOAD ASSEMBLIES AND MODULES
#----------------------------------------------------------
Try
{
Import-Module ActiveDirectory -ErrorAction Stop
}
Catch
{
Write-Host "[ERROR]`t ActiveDirectory Module couldn't be loaded. Script will stop!"
Exit 1
}
#----------------------------------------------------------
#STATIC VARIABLES
#----------------------------------------------------------
$path = Split-Path -parent $MyInvocation.MyCommand.Definition
$newpath = $path + "\remove_ad_users.csv"
$log = $path + "\log_remove_ad_users.log"
$date = Get-Date
$i = 1
#----------------------------------------------------------
#START FUNCTIONS
#----------------------------------------------------------
Function Start-Commands
{
Remove-Users
}
Function Remove-Users
{
"Processing started (on " + $date + "): " | Out-File $log -append
"--------------------------------------------" | Out-File $log -append
Import-CSV $newpath | ForEach-Object {
If ($_.Group -eq "")
{
Write-Host "[ERROR]`t Please provide a valid Group to permenantly remove member user accounts. Processing skipped for line $($i)`r`n"
"[ERROR]`t Please provide a valid Group to permenantly remove member user accounts. Processing skipped for line $($i)`r`n" | Out-File $log -append
}
Else
{
$Users = Get-ADGroupMember $_.Group
Foreach ($User in $Users) {
Get-ADUser $User -Properties * | select SamAccountName
Write-Host "[INFO]`t Deleting user : $($User)`r`n"
Remove-ADUser -Identity "$($User)" -Confirm:$false
"[INFO]`t User $($User) has been deleted (on " + $date + "): `r`n" | Out-File $log -append
}
}
$i++
}
"--------------------------------------------" + "`r`n" | Out-File $log -append
}
Write-Host "STARTED SCRIPT`r`n"
Start-Commands
Write-Host "STOPPED SCRIPT"

