Active Directory (AD) administrators often need to create multiple user accounts at once. Doing this manually for a large number of users can be time-consuming and error-prone. In this article, we review two methods for bulk user creation using PowerShell, updated to reflect best practices. All techniques leverage the standard ActiveDirectory PowerShell module, which is fully supported on modern Windows Server versions (including Windows Server 2022) and in Windows PowerShell 5.1 or PowerShell 7+. The primary cmdlets used are New-ADUser, Get-ADUser, Remove-ADUser, Export-CSV, and Import-CSV – all of which remain available and function the same in current environments. We will also use Microsoft Excel as a convenient tool for editing CSV files, though any spreadsheet or text editor could be used.
Overview: We’ll demonstrate two scenarios for bulk account creation:
- Scenario 1 – Uniform Accounts: Creating multiple AD user accounts that share a common naming pattern and similar parameters (e.g., User1, User2, … all with a default password). This is useful for test accounts or temporary access accounts that have minimal required attributes.
- Scenario 2 – Customized Accounts: Creating multiple AD user accounts with individual attributes by importing details from a CSV file. This approach is suited for onboarding many new employees or any situation where each account has distinct information (name, department, etc.).
Important: These operations directly modify AD. Ensure you have the ActiveDirectory module installed (on a Domain Controller or via RSAT on a workstation) and appropriate permissions to create users. It’s recommended to practice in a test environment or have a current backup of AD, as bulk changes can be destructive if something is misconfigured. The examples below assume a domain Test.local and an OU named Users_New where new accounts will be created.
Bulk AD Account Creation with Typical Settings (Uniform Accounts)
First, we’ll create a batch of AD user accounts that have a consistent name format and identical settings. In this example, we create 15 users named Client1 through Client15, all in the OU Users_New in the Test.local domain. Each account will be enabled with a default password that varies by user (e.g., Password1 for Client1, Password2 for Client2, etc.). We will use the New-ADUser cmdlet in a loop to achieve this.
1. Verify no conflicting accounts exist: Before creating new accounts, it’s wise to check that accounts with the intended naming pattern don’t already exist, to avoid duplicates. We use Get-ADUser with an LDAP filter to search for any existing users whose name starts with “Client”:
Get-ADUser -Filter 'name -Like "Client*"'
Output: If no such users exist, this command returns nothing (an empty result confirms we’re clear to proceed).
2. Create the new user accounts: We can create multiple users in one go using a PowerShell range and the ForEach-Object loop (aliased as %). The following command will iterate from 1 to 15 and create a user for each number:
1..15 | ForEach-Object {
New-ADUser -Name "Client$_" -SamAccountName "Client$_" `
-AccountPassword (ConvertTo-SecureString "Password$_" -AsPlainText -Force) `
-Enabled $true -Path "OU=Users_New,DC=Test,DC=local"
}
3. In this command, the placeholder $_ represents the current number in the loop. For each iteration, New-ADUser is called with a unique Name and SamAccountName (Client1, Client2, …), and a secure string password is created from the text “Password<Number>”. We specify -Enabled $true to activate the account upon creation, and -Path to target the Users_New OU. (By default, if -Path is not given, accounts would be created in the domain’s default container, but it’s best practice to specify the OU explicitly.)
Note: In modern usage, the SamAccountName (the user’s logon name* in pre-Windows 2000 format) should always be provided when creating a user. In our example, we set SamAccountName equal to the Name for simplicity. If this parameter is omitted, the New-ADUser cmdlet will try to use the Name as the SamAccountName by default; however, it’s recommended to specify it to avoid any ambiguity or length issues. We also ensure an AccountPassword is set because enabling an account at creation time requires a password.
4. Confirm the accounts were created: After running the above, we can query AD again to list the new users and verify their status:
Get-ADUser -Filter 'name -Like "Client*"' -SearchBase "OU=Users_New,DC=Test,DC=local" |
Format-Table Name, Enabled, DistinguishedName
Output showing the newly created users Client1–Client15, all Enabled, under the specified OU. As expected, all 15 accounts have been created with the default settings we provided (enabled and with the given password). Each account’s DistinguishedName confirms the location in the Users_New OU.
5. Cleanup (if necessary): If these accounts were created for testing or temporary use, you may eventually want to remove them. The Remove-ADUser cmdlet deletes a user account. For example, to remove all 15 test accounts without confirmation prompts, you can run:
1..15 | ForEach-Object { Remove-ADUser "Client$_" -Confirm:$false }
This loops through the same range and deletes Client1 … Client15. We include the parameter -Confirm:$false to suppress the interactive confirmation for each deletion (which is useful when deleting many objects at once). Always use caution with bulk deletion – you can omit -Confirm:$false to be prompted for each removal, or run a filtered Get-ADUser piped to Remove-ADUser for more control (e.g., Get-ADUser -Filter ‘Name -like “Client*”‘ | Remove-ADUser).
At this point, we have demonstrated creating multiple AD users with uniform settings using a single PowerShell one-liner. This method is efficient for generating accounts that follow a simple pattern. Next, we will explore a more complex scenario where each account has individual attributes, and we’ll leverage a CSV file to import those details.
Bulk AD Account Creation with Individual Settings (CSV Import)
In the second scenario, each new user account will have distinct properties (name, department, etc.). Automating this requires a bit of one-time setup: preparing a CSV file with all the desired user attributes, and then using PowerShell to import that data and create accounts. While this approach involves some manual preparation, it significantly reduces repetitive input for large numbers of users.
Overview of steps: We will export a “template” user’s attributes to a CSV to get the correct column structure, edit that CSV (using Excel for convenience) to add our new users’ details, save it, then run an Import-CSV + New-ADUser script to create all the accounts in one go.
1. Export a Template User to CSV
First, decide on a template user account that has many of the fields filled in that you want to replicate (e.g., a dummy account or an existing account with representative attributes). This will help generate the CSV with proper headers. In this example, we use a test account John Doe as the template.
Use Get-ADUser to retrieve the template user and Export-CSV to save all its properties to a CSV file. We include the -Properties * flag to get all possible attributes of the user:
Get-ADUser -Filter 'name -Like "John*"' -Properties * | Export-CSV C:\Temp\exp.csv
This command exports John Doe’s AD user object to C:\Temp\exp.csv. If it runs successfully, it will produce no output (aside from creating the file). We recommend adding the -NoTypeInformation switch to Export-CSV in modern PowerShell, which omits the type header line (#TYPE …) from the CSV.
2. Prepare and Edit the CSV in Excel
Now we’ll use Excel to edit exp.csv – removing unnecessary columns and adding new user rows:
a. Open the CSV in Excel: Launch Excel and go to the Data tab. Click Get Data → From Text/CSV. Navigate to the C:\Temp directory and select exp.csv, then click Import.
Excel will open the Text Import Wizard to guide importing the CSV. Use the following settings in the wizard:
Step 1: Choose Delimited as the data type, and set Start import at row to 2 (to skip the #TYPE header line, if present). Ensure the file origin/encoding is correct (e.g., 437 for OEM US). Then click Next.
Step 2: Under Delimiters, uncheck Tab and check Comma (the CSV is comma-separated). You should see the preview split into columns after doing this. Click Next.
Step 3: For our purposes, we can accept all columns as General data type. (If any column should be treated as text or date specifically, you could set it here, or choose to skip certain columns directly in the import. We will instead remove unwanted columns after import.) Click Finish.
When prompted, choose to put the data in the Existing worksheet (e.g., starting at cell $A$1) and click OK to import. The CSV content will now populate the Excel sheet.
At this stage, you will see a sheet with a header row containing every possible AD attribute (as columns), and below it the data from the template user (John Doe). There will likely be dozens of columns, many of which you won’t need to set for new users.
b. Remove unnecessary columns: Identify which attributes are not needed or will not be managed for the new accounts, and delete those columns to simplify the file. For example, you might remove attributes like ObjectGUID, LastLogonDate, etc., that should not be manually specified for new accounts. Focus on keeping the columns that you plan to define (such as Name, SamAccountName, GivenName, Surname, Department, EmailAddress, etc.).
To delete columns in Excel: select the column(s), right-click and choose Delete. Repeat as needed. In our example, we removed dozens of columns and kept a core set of attributes.
Which columns to keep depends on your requirements. At minimum, ensure you keep Name and SamAccountName (and ideally UserPrincipalName) since these are critical for user creation. Also keep AccountPassword (we will fill in plaintext passwords here for each user, which the script will convert to secure strings) and any profile fields you want to set (e.g., department, title, etc.). You should also keep the Enabled column (set to TRUE/FALSE) and ChangePasswordAtLogon if you want to enforce password change on first login. In our example, we retained columns for Name, Enabled, ChangePasswordAtLogon, GivenName, ObjectClass, SamAccountName, Surname, UserPrincipalName, AccountPassword, EmailAddress, etc.
c. Add new user rows: Below the template row (or replacing the template row), enter the details for each new user account you want to create, under the appropriate columns. Each row will represent a new user object. For instance, we add users James Hunter, William Nelson, Olivia Moore, Heather Murphy, Ryen Jackson, and Katie Griffin in our sheet, each with their own attributes (see image below). For Boolean fields like Enabled or ChangePasswordAtLogon, use TRUE or FALSE. For AccountPassword, enter a default password in plain text for each user (the script will convert it securely). Make sure values like SamAccountName are unique in the domain and conform to username rules (≤20 characters for SamAccountName). Also double-check the ObjectClass/Type column: it should be “user” for all new entries (this was inherited from John Doe’s object class).
d. Save the edited CSV: Once all new user rows are added and you are satisfied with the data, save the file as a new CSV. Go to File -> Save As, choose CSV (Comma delimited) as the format, and name the file (e.g., imp.csv in C:\Temp). If Excel warns about features not supported in CSV (this is normal), confirm that you want to keep using that format (click Yes). The file C:\Temp\imp.csv now contains the headers and data for the users to import.
3. Import the CSV and Create Users with PowerShell
With imp.csv ready, the final step is to write a PowerShell script that reads each row of the CSV and calls New-ADUser with those parameters. Below is a PowerShell script (which we’ll call Import.ps1) to perform the bulk import:
# Import the CSV data into a PowerShell array of objects
$CSVData = Import-Csv "C:\Temp\imp.csv"
# Define the target OU (distinguished name format)
$TargetOU = "OU=Users_New,DC=Test,DC=local"
# Loop through each record (user) in the CSV data
foreach ($Rec in $CSVData) {
New-ADUser `
-Name $Rec.Name `
-Path $TargetOU `
-Enabled ([bool]$Rec.Enabled) `
-ChangePasswordAtLogon ([bool]$Rec.ChangePasswordAtLogon) `
-AccountExpirationDate $Rec.AccountExpirationDate `
-AccountPassword (ConvertTo-SecureString $Rec.AccountPassword -AsPlainText -Force) `
-City $Rec.City `
-Company $Rec.Company `
-Country $Rec.Country `
-Department $Rec.Department `
-Description $Rec.Description `
-DisplayName $Rec.DisplayName `
-Division $Rec.Division `
-EmailAddress $Rec.EmailAddress `
-EmployeeID $Rec.EmployeeID `
-EmployeeNumber $Rec.EmployeeNumber `
-Fax $Rec.Fax `
-GivenName $Rec.GivenName `
-HomeDirectory $Rec.HomeDirectory `
-HomeDrive $Rec.HomeDrive `
-HomePage $Rec.HomePage `
-HomePhone $Rec.HomePhone `
-Initials $Rec.Initials `
-LogonWorkstations $Rec.LogonWorkstations `
-Manager $Rec.Manager `
-MobilePhone $Rec.MobilePhone `
-Office $Rec.Office `
-OfficePhone $Rec.OfficePhone `
-Organization $Rec.Organization `
-OtherName $Rec.OtherName `
-POBox $Rec.POBox `
-PostalCode $Rec.PostalCode `
-ProfilePath $Rec.ProfilePath `
-SamAccountName $Rec.SamAccountName `
-ScriptPath $Rec.ScriptPath `
-ServicePrincipalNames $Rec.ServicePrincipalNames `
-State $Rec.State `
-StreetAddress $Rec.StreetAddress `
-Surname $Rec.Surname `
-Title $Rec.Title `
-Type $Rec.Type `
-UserPrincipalName $Rec.UserPrincipalName
}
A few things to note in this script:
- We import the CSV into $CSVData. Each row from the CSV becomes an object in this array, with properties corresponding to the column headers.
- We set the target OU in $TargetOU for convenience. All new users will be created in Users_New, Test.local (modify this string for your domain/OU as needed).
- In the foreach loop, we use $Rec to represent each user record. For each one, we call New-ADUser with the various parameters. We map each AD user attribute to the corresponding $Rec.<Property> from the CSV. For boolean values like Enabled and ChangePasswordAtLogon, we cast the CSV string (“TRUE”/”FALSE”) to boolean [bool] so that New-ADUser receives a proper boolean type (creating-bulk-user-accounts-ad-via-powershell.docx). For the password, we convert the plaintext string from CSV into a secure string on the fly using ConvertTo-SecureString … -AsPlainText -Force.
- Not every parameter needs to be included. We included many commonly used attributes for demonstration, but you can simplify the script to include only the fields you kept in the CSV. (Any parameters not supplied will take AD defaults or remain blank. For example, if ProfilePath is not needed, it can be omitted from both the CSV and the script.)
- The -Type parameter is shown using $Rec.Type. This corresponds to the object class of the account. In most cases this will be “user” for standard AD user accounts. If the CSV doesn’t have a Type column, or it’s blank, New-ADUser will default to creating a normal user object.
Save this script (Import.ps1) and then execute it in PowerShell:
C:\Temp\Import.ps1
If everything is set up correctly, the script will run without errors and produce no output. It silently creates each user in AD. (We did not include error-handling or output messages for brevity, but in a production script you might add logging or error capture.)
4. Verify the New Accounts in AD
Finally, we confirm that the new accounts have been created in the target OU with the desired settings:
Get-ADUser -SearchBase "OU=Users_New,DC=Test,DC=local" -Filter * | Format-Table Name, Enabled, DistinguishedName
This command lists all user accounts in the Users_New OU. It should include the users we added from the CSV, along with their Enabled status.
Each account’s Distinguished Name is shown, confirming they were created in the correct OU. At this point, the accounts are ready to use. Each user can log in with the password set in the CSV (unless ChangePasswordAtLogon was TRUE, in which case they’ll be prompted to change it on first login).
Conclusion
We have explored two ways to automate bulk user creation in Active Directory using PowerShell. The first method quickly generates many similar accounts using a simple script, and the second method leverages CSV import to create multiple accounts with individual attributes. Both approaches use the standard ActiveDirectory PowerShell module cmdlets (New-ADUser, Get-ADUser, Remove-ADUser, etc.). Using these techniques can save significant time and reduce errors, especially in large-scale user provisioning tasks. Always remember to double-check your scripts and data (such as CSV entries) in a test environment before running them in production.