PowerShell: Create Active Directory Users In Bulk (Update 1.5)

For years I’ve had a AD user import VBS script as part of my toolkit, I thought it was about time to update it to PowerShell as well as add a few new features.

My AD User Creation script can be downloaded from the Microsoft TechNet Script Cente.

Features and Requirements

This script requires the Active Directory PowerShell module be installed, which is a part of the Remote Server Administration Tools (RSAT) for client editions of Windows. This script has been tested running on Windows Server 2016 and Windows Server 2012 R2 Domain Controller’s and on a Windows 10 client.

This script will create users based on basic information provided by a CSV file. All other options are added via command line options. Options include:

  • Organisation Unit in which to create the users.
  • The UPN that users should have
  • Home Drive location
  • Home Drive Letter
  • Membership of an Active Directory Group
  • Account Expiry Date

The -file Parameter

As with my other scripts, it can optionally generate a log and email the log if configured to do so, and I’ve implemented options via command line switches. When running the script via Schedule Tasks or the command prompt be sure to use the -file parameter before specifying the script, so you can use “double quotes” for the command line switches that need them, if you do not use -file, then you should use ‘single quotes’.

CSV File Formatting

The first line of the CSV file should be the field names so the script (and you) knows what each field is for.

The CSV file should have the following structure: Firstname,Lastname,SAM,Password

Generating an encrypted password file

If you’ve used a previous version I’ve changed how the script handles configuring a password for the log notification e-mail. Specifically the password must now be in an encrypted text file. The advantage of this is that the password will no longer be in plain text, which is a security risk. The downside is that you will now need to generate a password file. The command to do this is pretty simple, but it must be generated on the computer the script will be running on, and as the user used to run the script.

To generate the password file, run the following command in PowerShell. When running the command you will be prompted for a username and password. The username doesn’t matter and can be anything, but the password must be the password you want to use to authenticate to your SMTP server.

$creds = Get-Credential
$creds.Password | ConvertFrom-SecureString | Set-Content c:\scripts\ps-script-pwd.txt

After running the commands, you should have a text file contained the encrypted password. Enter the path and filename for the -pwd switch to configure authenticated e-mail notification.


Here are the command line options available to you, with some examples of how to use them.

Command Line Switch Mandatory Description Example
-csv Yes Location and name of the csv file containing the user accounts to be created. E:\scripts\new-users.csv
-ou Yes Enter the DN (Distinguished Name) of the OU that you wish to put the new users in. The DN must be surrounded by “double quotes.” “ou=Imported_Accounts,dc=contoso,dc=com”
-upn Yes Enter the string you wish to use for the users UPN. contoso.com
-homeletter No* Enter the drive letter to use for the Home Drive. *This setting must be set along with the -homepath. H:
-homepath No* Enter the unc path to use for the location of the home drive. The users folder will be created automatically. *This setting must be set along with the -homeletter. \\filesrv01\share
-group No Enter the DN (Distinguished Name) of a group that the users should be added to, if required. “cn=Marketing,ou=UserGroups,dc=contoso,dc=com”
-expire No Enter the date the accounts should expire if required. The date format should be the same as the local systems format. 31/12/2018
-l No Location to store the optional log file. The name of the log file is automatically generated. E:\scripts\log
-sendto No The email address to send the log file to. me@contoso.com
-from No* The email address that the log file should be sent from.

*This switch isn’t mandatory but is required if you wish to email the log file.

-smtp No* SMTP server address to use for the email functionality.

*This switch isn’t mandatory but is required if you wish to email the log file.






-user No* The username of the account to use for SMTP authentication.

*This switch isn’t mandatory but may be required depending on the configuration of the SMTP server.

-pwd No* The location of the file containing the encrypted password of the account to use for SMTP authentication.

*This switch isn’t mandatory but may be required depending on your SMTP server.

-usessl No* Add this option if you wish to use SSL with the configured SMTP server.

Tip: If you wish to send email to outlook.com or office365.com you will need this.

*This switch isn’t mandatory but may be required depending on the configuration of the SMTP server.


Change Log

16/10/2017 1.5

  • Changed SMTP authentication to require an encrypted password file.
  • Added instructions on how to generate an encrypted password file.

07/10/2017 1.4

  • Added necessary information to add the script to the PowerShell Gallery.

13/09/2017 1.3

  • Added check for existence of user before attempting to create user.
  • Improved logging to handle the above change.

22/07/2017 1.2

  • Improved code commenting for documentation purposes.
  • Added authentication and SSL options for e-mail notification.

PowerShell Code

<#PSScriptInfo .VERSION 1.5 .GUID eaaca86c-2a1f-4caf-b2f9-05868186d162 .AUTHOR Mike Galvin twitter.com/digressive .COMPANYNAME .COPYRIGHT (C) Mike Galvin. All rights reserved. .TAGS Active Directory User Creation CSV File Import .LICENSEURI .PROJECTURI https://gal.vin/2017/09/13/powershell-create-ad-users-from-csv/ .ICONURI .EXTERNALMODULEDEPENDENCIES Active Directory Management PowerShell module. .REQUIREDSCRIPTS .EXTERNALSCRIPTDEPENDENCIES .RELEASENOTES #>

<# .SYNOPSIS Creates Active Directory user accounts from a CSV file. .DESCRIPTION Creates Active Directory user accounts from a CSV file. This script will: Create users based on information provided by a CSV file. All other options are added via command line switches. The command line switches provide configuration for: Organisational Unit in which to create the users. The user's UPN. Home Drive location. Home Drive Letter. Membership of an Active Directory Group. Account Expiry Date. Please note: to send a log file using ssl and an SMTP password you must generate an encrypted password file. The password file is unique to both the user and machine. The command is as follows: $creds = Get-Credential $creds.Password | ConvertFrom-SecureString | Set-Content c:\foo\ps-script-pwd.txt .PARAMETER Csv The path and filename of the csv file containing the user information to create users from. .PARAMETER Ou The Organisational Unit to create the users in. .PARAMETER Upn The Universal Principal Name the users should be configured with. .PARAMETER HomeLetter The drive letter to use for the home drive path. .PARAMETER HomePath The path where the location of the home drive should reside. .PARAMETER Group The DN of a group that all the new users should be made a member of. .PARAMETER Expire The expiry date of the new users. .PARAMETER L The path to output the log file to. The file name will be AD-Account-Creation-YYYY-MM-dd-HH-mm-ss.log .PARAMETER SendTo The e-mail address the log should be sent to. .PARAMETER From The from address the log should be sent from. .PARAMETER Smtp The DNS or IP address of the SMTP server. .PARAMETER User The user account to connect to the SMTP server. .PARAMETER Pwd The password for the user account. .PARAMETER UseSsl Connect to the SMTP server using SSL. .EXAMPLE Create-Accounts-CSV.ps1 -Csv E:\foo\users.csv -Ou 'ou=Imported_Accounts,ou=MyUsers,dc=contoso,dc=com' -HomeLetter W: -HomePath \\filesrvr01\UserHomes -Group 'cn=All_Users,ou=Groups_Security,dc=contoso,dc=com' -Expire 31/07/2018 -Upn contoso.com -L E:\logs -SendTo me@contoso.com -From AD-Account-Creation@contoso.com -Mail exch01.contoso.com This will take information from the users.csv file and create the users in the Imported_Accounts OU. The users home drive will be mapped to W: and be located under \\filesrvr01\UserHomes. The users will be a memeber of the All_Users AD group, will expire 31/07/2018 and will have the UPN of contoso.com. The log will be output to E:\logs and e-mailed. #>


## If users list csv file exists then run the script
If (Test-Path $UsersList)

    ## If logging is configured, start log
    If ($LogPath)
        $LogFile = ("AD-Account-Creation-{0:yyyy-MM-dd-HH-mm-ss}.log" -f (Get-Date))
        $Log = "$LogPath\$LogFile"

    If (Test-Path $UsersList)
        ## Start Log
        If ($LogPath)
            Start-Transcript $Log

    $UserCsv = Import-Csv -Path "$UsersList"

    ForEach ($User In $UserCsv)
        $DisplayName = $User.Firstname + " " + $User.Lastname
        $UserFirstName = $User.Firstname
        $UserLastName = $User.Lastname
        $Sam = $User.SAM
        $Upn = $Sam + "@$AdUpn"
        $Description = $DisplayName
        $Password = $User.Password

        $UserExist = Get-ADUser -Filter "SamAccountName -eq '$Sam'"

        If ($UserExist -eq $null)
            New-ADUser -Name $Sam -DisplayName "$DisplayName" -SamAccountName $Sam -UserPrincipalName $Upn -GivenName "$UserFirstName" -Surname "$UserLastName" -Description "$Description" -AccountPassword (ConvertTo-SecureString $Password -AsPlainText -Force) -Enabled $True -Path "$OrganisationalUnit" -ChangePasswordAtLogon $True –PasswordNeverExpires $False -AccountExpirationDate $AdExpire -Verbose
            If ($HomeDrive)
                Set-ADUser $Sam -HomeDirectory $HomeUnc\$Sam -HomeDrive $HomeDrive -Verbose

            If ($AdGroup)
                Add-ADGroupMember "$AdGroup" $Sam -Verbose

            Write-Host "User with SAM:$Sam already exists"

    ## If log was configured stop the log
    If ($LogPath)

        ## If email was configured, set the variables for the email subject and body
        If ($SmtpServer)
            $MailSubject = "AD Account Creation Log"
            $MailBody = Get-Content -Path $Log | Out-String

            ## If an email password was configured, create a variable with the username and password
            If ($SmtpPwd)
                $SmtpPwdEncrypt = Get-Content $SmtpPwd | ConvertTo-SecureString
                $SmtpCreds = New-Object System.Management.Automation.PSCredential -ArgumentList ($SmtpUser, $SmtpPwdEncrypt)

                ## If ssl was configured, send the email with ssl
                If ($UseSsl)
                    Send-MailMessage -To $MailTo -From $MailFrom -Subject $MailSubject -Body $MailBody -SmtpServer $SmtpServer -UseSsl -Credential $SmtpCreds

                ## If ssl wasn't configured, send the email without ssl
                    Send-MailMessage -To $MailTo -From $MailFrom -Subject $MailSubject -Body $MailBody -SmtpServer $SmtpServer -Credential $SmtpCreds

            ## If an email username and password were not configured, send the email without authentication
                Send-MailMessage -To $MailTo -From $MailFrom -Subject $MailSubject -Body $MailBody -SmtpServer $SmtpServer

    Write-Host ""
    Write-Host "There's no user list to work with."
    Write-Host ""

## End

As always I hope this helps in some way. If you’d like to get in touch with me please leave a comment or tweet me.


Follow Mike on Twitter: @Digressive

3 Comments Add yours

  1. Georg says:

    Good Job with the Script!
    But it dont want to work for me, maybe because of the Windowsupdate last Weekend.
    Trying to get it to work with Windows Server 2012r2 but geting this error every time:

    AUSFÜHRLICH: Ausführen des Vorgangs “New” für das Ziel “CN=srogers0203,Teilnehmer”.
    New-ADUser : Die Syntax des Objektnamens ist ungültig
    In C:\Users\Administrator\Desktop\Unbenannt2.ps1:64 Zeichen:9
    + New-ADUser -Name $sam -DisplayName “$displayname” -SamAccountName $sam – …
    + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    + CategoryInfo : NotSpecified: (CN=srogers0203,Teilnehmer:String) [New-ADUser], ADException
    + FullyQualifiedErrorId : ActiveDirectoryServer:8335,Microsoft.ActiveDirectory.Management.Commands.NewADUser


    1. Mike Galvin says:

      Hi Georg, I’ll try to help. I don’t think it’s due to a Windows Update, as I last tested it on the weekend. I could do with a bit more information but based on what you’ve posted it looks like that the script is stopping at the point where it creates the user. Does the CSV file have any extra characters that might be stopping it from completing, or perhaps the CSV file doesn’t have the correct formatting. The CSV file should be laid out like this: Firstname,Lastname,SAM,Password.

      Hope that helps, but let me know more information if you can.


Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Google+ photo

You are commenting using your Google+ account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )


Connecting to %s

This site uses Akismet to reduce spam. Learn how your comment data is processed.