Code:
<#
.SYNOPSIS
Import AD Users from a CSV File.
.DESCRIPTION
Import AD Users from a CSV File.
The script will request user input for a password and LOG / CSV file and then just get on with the task at hand.
.NOTES
Authors: © Alex Haines
Modified for use at Millfields First School in Bromsgrove by Alex Haines in December 2010.
Original basic code was from a TechNet forum post - http://social.technet.microsoft.com/Forums/en-US/ITCG/thread/5b0420a6-2ff7-445f-8887-07c295073f45
Some other code was taken from another TechNet post later on to add Home Folder features - can't credit as can't remember - sorry!
Last edited on 09th February 2011.
This script ASSUMES a Domain called "millfields.local" You must edit appropriate spots to reflect the
CORRECT domain name in your environment. Also ensure and test in a TEST domain vs production before unleashing the script.
YOU HAVE BEEN WARNED!!!
.PARAMETER CSVFilePath
Path of CSV file to import
.PARAMETER LOGFilePath
Path of ERROR LOG file if needed during script processing
.EXAMPLE
import_users.ps1 -CSVFilePath C:\Scripts\Users.csv -LOGFilePath C:\Scripts\ErrorLog.txt
#>
# Forcefully request info on where the LOG & CSV file should be created.
param ([parameter(Mandatory=$True,HelpMessage='Path of ERROR LOG file to write to:')]$LOGFilePath, [parameter(Mandatory=$True,HelpMessage='Path of CSV file to import from:')]$CSVFilePath)
# Test for existence of supplied LOG - if not exit.
if (Test-Path $LOGFilePath){
Write-Host ''
Write-Host 'The Path to the ERROR LOG file appears to already exist. APPENDING TO & CONTINUING SCRIPT!'
$(Get-Date -format "dd/MM/yy HH:mm:ss") + ': The chosen LOG file (' + $LOGFilePath + ') already exists! Do not panic, I will just append to it.' | Out-File $LOGFilePath -append
}
else{
Write-Host ''
Write-Host 'The Path to the ERROR LOG file is not valid. CREATING & CONTINUING SCRIPT!'
$(Get-Date -format "dd/MM/yy HH:mm:ss") + ': The chosen LOG file (' + $LOGFilePath + ') was not valid! Do not panic, I will just create it.' | Out-File $LOGFilePath -append
}
# Test for existence of supplied CSV - if not exit.
if (Test-Path $CSVFilePath){
Write-Host 'The Path to the CSV file appears valid. CONTINUING SCRIPT!'
Write-Host ''
$(Get-Date -format "dd/MM/yy HH:mm:ss") + ': The chosen CSV file (' + $CSVFilePath + ') exists so the script continued!' | Out-File $LOGFilePath -append
}
else{
Write-Host 'The Path to the CSV file appears invalid. EXITING SCRIPT!'
Write-Host ''
$(Get-Date -format "dd/MM/yy HH:mm:ss") + ': ERROR 4 - The chosen CSV file (' + $CSVFilePath + ') did not exist so the script had to be terminated as there was no work to do!' | Out-File $LOGFilePath -append
Exit
}
<#
Get a temporary password for the users. If you don't the accounts will create no problem but
they will be "Disabled" accounts. This will mean you have to go through and enable them after the import.
As we don't really want to have to do this, I advise you leave this step in place - you could hardcode
the $Password variable if you wanted as it makes no real difference.
For Secure Mode use -AsSecureString (This blanks out the password as you type and hides it from view
when using 'Up Arrow').
#>
$Password=READ-HOST 'Enter a Temporary Secure Password (eg Golf!911)' -AsSecureString
<#
Go through EACH item in the list (Header row is treated as variable names by default)
#>
$(Get-Date -format "dd/MM/yy HH:mm:ss") + ': Start of the main loop.' | Out-File $LOGFilePath -append
FOREACH ($USER in (IMPORT-CSV $CSVFilePath)) {
<#
I could just Assign straight in from the Cmdlet but I'm putting them into
Individual variables so you can see how the data is referenced (check your
CSV headers, those are the exact names but are NoT cAsE sEnSiTiVe).
A standard csv from county will be given with 6 Headers
givenName | sn | gname | department | uname | ctPassword
#>
$FirstName=$USER.givenName
$LastName=$USER.sn
$JobTitle=$USER.gname
$Department=$USER.department
$Username=$USER.uname
$Password=$USER.ctPassword
<#
You will see that most of the lines below don't have any data in them - this is deliberate
as in most situations, the schools won't need them. If you do, just replace with the correct
header name as your csv file requires in the format =$USER.header
#>
$Title=''
$Office=''
$Email=$Username+'@millfields.worcs.sch.uk'
$Extension=''
$Mobile=''
$Address=''
$City=''
$StateProv=''
$PostalZip=''
$Country=''
$ImmediateSupervisor=''
$HomeDirectory='\\ALABAMA\Homes$\'+$Username
$HomeDrive='Y:'
$ProfilePath='\\ALABAMA\Profiles2010$\'+$Username
$LogonScript='student.bat'
$Domain='millfields.local'
$UPN=$Username+'@'+$Domain
$DisplayName=$Username+' - '+($FirstName+' ').Substring(0,1).Trimend()+'.'+$LastName
$Company='Millfields First School'
$PhoneNumber='01527 831 885 + '+$Extension
$Web='http://millfields.networcs.net'
$Description=$FirstName+' '+$LastName+' belongs to the '+$JobTitle+' group and joined the school in '+$Department+'.'
$Fax=''
<#
SAM USERID cannot be greater than 20 characters so trim away - LEGACY!
#>
$SAM=(($Username+' ').Substring(0,20)).Trimend()
<#
Check to see if the user already exists.
If it does add it to an error log and then continue with the next user.
If it doesn't then add the user and loop.
#>
$count = Get-QADUser –samAccountName $SAM | Measure-Object
if ($count.count –gt 0) {
Write-Host 'The user'$SAM' failed. This is because the user already exists!'
$(Get-Date -format "dd/MM/yy HH:mm:ss") + ': The user ' + $SAM + ' failed. This is because the user already exists!' | Out-File $LOGFilePath -append
} else {
# Create the home folders and assign permissions.
# Checks starting character of accname and load balances to two (or more) servers if desired.
$server1 = 'a','b','c','d','e','f','g','h','i','j','k','l','m','n','o','p','q','r','s','t','u','v','w','x','y','z'
#$server2 = 'o','p','q','r','s','t','u','v','w','x','y','z'
Switch ($SAM.substring(0,1).tolower()) {
{ $server1 –contains $_ }
{ $homeserver = '\\alabama\'; break; }
{ $server2 –contains $_ }
{ $homeserver = '\\alaska\'; break; }
}
# Test for non-existence of created home directory - if not skip creation.
if (Test-Path $homeserver'Homes$\'$SAM){
Write-Host exists? $homeserver'Homes$\'$SAM
$(Get-Date -format "dd/MM/yy HH:mm:ss") + ': ERROR 6 - User ' + $SAM + '.' | Out-File $LOGFilePath -append
}
else {
# Make the directory.
Mkdir ($homeserver + 'Homes$\' + $SAM)
}
# Construct two commands to add Read/Write access to the directory.
$cacls1 = "cacls " + $homeserver + "Homes$\" + $SAM + " /E /G " + $SAM + ":R"
$cacls2 = "cacls " + $homeserver + "Homes$\" + $SAM + " /E /G " + $SAM + ":W"
$cacls3 = "cacls " + $homeserver + "Homes$\" + $SAM + " /E /G " + $SAM + ":F"
$cacls4 = "cacls " + $homeserver + "Homes$\" + $SAM + " /E /G " + $SAM + ":C"
# DEBUG
#Write-Host $cacls1
#Write-Host $cacls2
#Write-Host $cacls3
#Write-Host $cacls4
# Now create the user.
NEW-QADUSER -ParentContainer $Domain'/Imported' -Name $DisplayName -UserPassword $Password -City $City -Company $Company -Department $Department -email $Email -FAX $Fax -Firstname $FirstName -Lastname $LastName -Mobilephone $MobilePhone -Office $Office -Phonenumber $PhoneNumber -Postalcode $PostalZip -samaccountname $SAM -StateorProvince $StateProv -StreetAddress $Address -Title $JobTitle -UserPrincipalName $UPN -webpage $Web -Description $Description -displayname $DisplayName -HomeDirectory $HomeDirectory -HomeDrive $HomeDrive -ProfilePath $ProfilePath -LogonScript $LogonScript
$(Get-Date -format "dd/MM/yy HH:mm:ss") + ': The user ' + $SAM + ' succeeded.' | Out-File $LOGFilePath -append
# Run the two commands.
cmd /c $cacls1
cmd /c $cacls2
cmd /c $cacls3
cmd /c $cacls4
}
}
# Close the log file.
$(Get-Date -format "dd/MM/yy HH:mm:ss") + ': EoF' | Out-File $LOGFilePath -append
' ' | Out-File $LOGFilePath -append The code works well and successfully imported my users into AD with their home folders all correctly assigned. The only thing I had to do afterwards was move the users from the Imported OU to the correct OU and assign them to any groups, but this is very easy to do.