The PowerShell script discussed here allows you to create new Active Directory (AD) users, one of the most common tasks that IT admins tend to automate when it comes to employee provisioning.

The reason is that this function meets all of the criteria necessary for automation. It's a task that requires a lot of different, error-prone steps, such as ensuring user accounts meet a particular standard, creating a home folder in a certain way, creating a mailbox, and so on. In addition, it's a task that admins are going to repeat many times, since an organization continually hires new employees. I thought this was a great task to demonstrate typical steps that you might take when embarking on a new script.

To get started, I'm going to assume a few prerequisites. First, I'm going to presume you have at least PowerShell v4 and also have the Active Directory module installed. The module comes as part of the Remote Server Administration Tools pack. I'm also going to assume that the machine ºyou'll be working is a part of a domain, that you have the required permission to create an Active Directory user account, and that the user's home folder resides on a file server somewhere.

Because each organization's process is going to be a little different, I'm also going to keep this as generic as possible by first demonstrating how to create an Active Directory user account based on a company standard and create their home folder somewhere. This is probably the minimum that you'll need to do. However, once you get the basics of script building, you'll see just how easy it is to script other things (adding something to an HR application, creating an Exchange mailbox, etc.).

Planning employee provisioning ^

Let's first break down each component of the goal I want to accomplish and how I intend to make it happen. By the end of script execution, I want to end up with a single AD user account and a separate folder created on a file server with appropriate permissions. To do this, I'll need to define what exactly each of these two tasks looks like.

For example, when creating my AD user account, here are a few questions to ask yourself.

  1. In what organizational unit should it go?
  2. In what (if any) groups should it go?
    1. Is there a standard user group in which all user accounts go?
    2. Are there different groups in which a user account might go, depending on their department?
  3. What attributes need to be set at creation time?
  4. What should the username be? Does it have to follow some company standard?

When creating the home folder, these are some questions you might ask yourself.

  1. Where should the folder be created?
  2. What should the name of the folder be?
  3. What kind of permissions should the folder have?

Breaking down your goals by asking lots of questions beforehand allows you to have a picture of what the script might do before you write a single line of code.

Now that we have some rough intentions outlined, let's answer each question before coding. Don't worry. We'll get to the code in a minute.

  1. In what organizational unit should it go? – Corporate Users
  2. In what (if any) groups should it go?
    1. Is there a standard user group in which all user accounts go? XYZCompany
    2. Are there different groups in which a user account might go, depending on their department? Match group name with the department.
  3. What attributes need to be set at creation time?
    1. First Name
    2. Last Name
    3. Title
    4. Department
    5. Initials
    6. Change Password at Logon
  4. What should the username be? Does it have to follow some company standard? It should be first initial, last name. If that username is already taken, it should be first initial, middle initial, and last name. If that's taken, error out.
  5. Where should the folder be created? \\MEMBERSRV1\Users
  6. What should the name of the folder be? AD username

Now that we have each of our questions answered, let's get down to the code.

Creating new AD users with PowerShell ^

We'll first create the script and call it New-Employee.ps1. Because a lot of information will change for each employee, we need to create some parameters and dynamically pass them to the script whenever it is run. I'll create the following variables as parameters:

  • First Name
  • Last Name
  • Middle Initial
  • Location (for the OU)
  • Department
  • Title
  • Default Group
  • Default Password
  • Base Home Folder Path

These will be represented as script parameters.

param (
[Parameter(Mandatory,ValueFromPipelineByPropertyname)]
	[ValidateNotNullOrEmpty()]
	 [string]$FirstName,
	 [Parameter(Mandatory,ValueFromPipelineByPropertyname)]
	 [ValidateNotNullOrEmpty()]
	 [string]$LastName,
	 [Parameter(Mandatory,ValueFromPipelineByPropertyname)]
	 [ValidateNotNullOrEmpty()]
	 [string]$MiddleInitial,
[Parameter(Mandatory,ValueFromPipelineByPropertyname)]
[ValidateNotNullOrEmpty()]
 [string]$Department,
	
	[Parameter(Mandatory,ValueFromPipelineByPropertyname)]
	[ValidateNotNullOrEmpty()]
	[string]$Title,
	 [Parameter(ValueFromPipelineByPropertyname)]
	 [ValidateNotNullOrEmpty()]
	 [string]$Location = 'OU=Corporate Users',
	
	 [Parameter()]
	 [ValidateNotNullOrEmpty()]
	 [string]$DefaultGroup = 'XYZCompany',
	 [Parameter()]
	 [ValidateNotNullOrEmpty()]
	 [string]$DefaultPassword = 'p@$$w0rd12345', ## Don't do this...really
	 [Parameter()]
	 [ValidateScript({ Test-Path -Path $_ })]
	 [string]$BaseHomeFolderPath = '\\MEMBERSRV1\Users'
)
Next, I'll need to figure out what the username will be based on our defined company standard and verify the home folder doesn't exist yet.
## Find the distinguished name of the domain the current computer is a part of.
$DomainDn = (Get-AdDomain).DistinguishedName
## Define the 'standard' username (first initial and last name)
$Username = "$($FirstName.SubString(0, 1))$LastName"
#region Check if an existing user already has the first initial/last name username taken
Write-Verbose -Message "Checking if [$($Username)] is available"
if (Get-ADUser -Filter "Name -eq '$Username'")
{
	Write-Warning -Message "The username [$($Username)] is not available. Checking alternate..."
	## If so, check to see if the first initial/middle initial/last name is taken.
	$Username = "$($FirstName.SubString(0, 1))$MiddleInitial$LastName"
	if (Get-ADUser -Filter "Name -eq '$Username'")
	{
throw "No acceptable username schema could be created"
	}
	else
	{
Write-Verbose -Message "The alternate username [$($Username)] is available."
	}
}
else
{
	Write-Verbose -Message "The username [$($Username)] is available"
}
#endregion

This part is nice because it will automatically figure out the username to use.

Script output

Script output

Next, we'll ensure the OU and group that we'll be using exist.

#region Ensure the OU the user's going into exists
$ouDN = "$Location,$DomainDn"
if (-not (Get-ADOrganizationalUnit -Filter "DistinguishedName -eq '$ouDN'"))
{
	throw "The user OU [$($ouDN)] does not exist. Can't add a user there"	
}
#endregion
I'll also verify the groups exists.
#region Ensure the group the user's going into exists
if (-not (Get-ADGroup -Filter "Name -eq '$DefaultGroup'"))
{
	throw "The group [$($DefaultGroup)] does not exist. Can't add the user into this group."	
}
if (-not (Get-ADGroup -Filter "Name -eq '$Department'"))
{
	throw "The group [$($Department)] does not exist. Can't add the user to this group."	
}
#endregion
And for the end of the validation phase, ensure the home folder doesn't already exist.
#region Ensure the home folder to create doesn't already exist
$homeFolderPath = "$BaseHomeFolderPath\$UserName"
if (Test-Path -Path $homeFolderPath) {
    throw "The home folder path [$homeFolderPath] already exists."
}
#endregion

We can now create the user account per company standards, add it to the group, and create the home folder.

#region Create the new user
$NewUserParams = @{
	'UserPrincipalName' = $Username
	'Name' = $Username
	'GivenName' = $FirstName
	'Surname' = $LastName
	'Title' = $Title
            'Department' = $Department
	'SamAccountName' = $Username
	'AccountPassword' = (ConvertTo-SecureString $DefaultPassword -AsPlainText -Force)
	'Enabled' = $true
	'Initials' = $MiddleInitial
	'Path' = "$Location,$DomainDn"
	'ChangePasswordAtLogon' = $true
}
Write-Verbose -Message "Creating the new user account [$($Username)] in OU [$($ouDN)]"
New-AdUser @NewUserParams
#endregion
#region Add user to groups
Write-Verbose -Message "Adding the user account [$($Username)] to the group [$($DefaultGroup)]"
Add-ADGroupMember -Members $Username -Identity $DefaultGroup
Write-Verbose -Message "Adding the user account [$($Username)] to the group [$($Department)]"
Add-ADGroupMember -Members $Username -Identity $Department
#endregion
#region Create the home folder and set permissions
Write-Verbose -message "Creating the home folder [$homeFolderPath]..."
$null = mkdir $homeFolderPath

Notice throughout this sample script that I was breaking things down into regions. Using regions is an excellent way to separate out high level tasks in a large script.

Subscribe to 4sysops newsletter!

Now that you've done all the hard work and defined the rules, the rest is easy. You can now create as many users as you'd like that all follow the exact same pattern.

avataravatar
9 Comments
  1. Pavan 5 years ago

    Hello Adam,

    Thanks for the article.

    Are you using a CSV file to create users using powershell? Where can i download the full script which was broken into pieces.

    Thanks,

    Pavan

    • Author

      Here's the full script: https://github.com/adbertram/Random-PowerShell-Work/blob/master/ActiveDirectory/New-AdUserProvision.ps1

      You can use a CSV. You'd just need to pass the proper parameter into this script. Something like this would work if you have a CSV with FirstName,LastName,MiddleInitial,Department and Title columns.

      Import-Csv C:\users.csv | foreach { ThisScript.ps1 -FirstName $_.FirstName -LastName $_.LastName -MiddleInitial $_.MiddleInitial -Department $_.Department }

      avatar
  2. Pavan 5 years ago

    Thanks Adam. Appreciate your response.

  3. anthony brown 4 years ago

    Adam awesome script. How would I modify this script to include passwords from csv file?

     

  4. Claus Bøhm 3 years ago

    Nice script.

    I would like help to create the username as 4 chars, from one of the below listed:

    From user: Hans Christian Andersen - $user_fn = "Hans" - $user_mn = "Christian" - $user_ln = "Andersen"

    haan, haca, hach, hana, hanc, hcan, hcha, hand, hchr - combinations from all 3 names and check each of them against AD. If not possible, use the first  and add a number (01-99) - also check if it exists and add +1

    Any solutions?

  5. Santhosh Pani 3 years ago

    Hi

    we have more than 50 Active Directory , how to create script for this

    OUs are same in all ADs

    and Groups also same in all ADs

    All are 2012 windows OS

    we can connect all ADs from one server

    we have common account for All ADs to login

     

  6. Steve 3 years ago

    I modified and added a few lines to this to help with on-prem AD users that are synced to Azure AD for O365.

    First change is when checking the domain and finding the UPN Suffix (I had to change my UPN Suffix when on boarding to O365 so I could use our domain name instead of the tenant name Microsoft gives you): Modified Lines 27-30

    ## Find the distinguished name of the domain the current computer is a part of.
    $domain = Get-ADDomain
    ## Find UPN Suffixes
    $UPNsuffix = Get-ADforest $domain.dnsroot | select UPNSuffixes

    Modified Line 58

    #region Ensure the OU the user's going into exists
    $ouDN = "$Location,$Domain"

    Modified Line 86

    	'Path' = "$Location,$domain"

    Added Lines 93-94

    Define UPNsuffix
    Set-ADUser $Username -UserPrincipalName "$($Username)@yourdomain.com$newUPN"
    

    Added Lines 103-111 (Sets mail and ProxyAddresses attributes which are required for proper synchronization with Azure AD/O365 Portal)

    #region set user attributes
    Get-ADUser $Username | Foreach {
    $UPN = $_.UserPrincipalName
    $ProxyAddrs = "SMTP:$UPN"
    $mail = $_.mail
    Set-ADUser -Identity $_.SamAccountName -Replace @{proxyAddresses = $proxyAddrs}
    Set-ADUser -Identity $_.SamAccountName -Replace @{mail = $UPN}
    }
    #endregion

    If you have exisiting users in AD that you are syncing to O365 but need attributes added in bulk you can run this as a separate script against a CSV file using only the SamAccountName in the CSV.

    $sInputFile = "C:\Users\user\Desktop\ADUsers.csv"  
    $sColumnName = "SamAccountName"  
    $tblDatos = Import-CSV $sInputFile  
    foreach($fila in $tblDatos)   
    {
    	Write-Host -ForegroundColor Yellow "Adding ProxyAddress and Mail attributes " + $fila.$sColumnName.ToString()  
        Write-Host -ForegroundColor Yellow "Staring to add attributes "  
        $fila.$sColumnName
    	Get-ADUser $fila.$sColumnName | foreach {
    	$UPN = $_.UserPrincipalName
    	$ExchangeHome = "<not set>"
    	$LegacyExchange = "<not set>"
    	$ProxyAddrs = "SMTP:$UPN"
    	$mail = $_.mail }
    ##	Set-ADUser $fila.$sColumnName -Replace @{legacyExchangeDN = $LegacyExchange}
    ##	Set-ADUser $fila.$sColumnName -Replace @{msExchHomeServerName = $ExchangeHome}
    	Set-ADUser $fila.$sColumnName -Replace @{proxyAddresses = $ProxyAddrs}
    	Set-ADUser $fila.$sColumnName -Replace @{mail = $UPN}
    	Write-Host -ForegroundColor Yellow $fila.$sColumnName " msExchHomeServerName removed. proxyAddresses and mail added " 
    	$fila.
    	$sColumnName 
    }

  7. Jamie 2 years ago

    What would I need to add an email address for the users based on firstname.lastname@domain.local. Also would like to add prompts for user account name, first Name, last name, Description, groups to add account to etc.. 

    • Add email address with @domain.local? What is that good for? 🙂

      What do you mean by prompts? For each parameter that is mandatory, if you do not enter it in the script call line, you will be prompted to enter it once you start the script.

Leave a reply

Please enclose code in pre tags

Your email address will not be published. Required fields are marked *

*

© 4sysops 2006 - 2021

CONTACT US

Please ask IT administration questions in the forums. Any other messages are welcome.

Sending

Log in with your credentials

or    

Forgot your details?

Create Account