Skip to main content

How to Create Bulk Users from a CSV File in Batch Script

Creating user accounts one by one is fine for small businesses, but in a large school, enterprise, or training environment, you often need to onboard 50, 100, or even 1,000 users at once. Manually clicking through "New User" wizards is not an option. Instead, IT professionals use a Batch script to read a structured CSV (Comma Separated Values) file and feed the data directly into the net user command. This guide explains how to automate bulk user creation.

Why Automate User Creation?

  • Standardization: Ensuring that every user follows the same naming convention (FirstLast) and has the same temporary password policy.
  • Speed: Reducing an onboarding task that would take days into a script that runs in 2 minutes.
  • Accuracy: Eliminating typos in usernames and passwords by importing directly from HR's export file.
CSV Format

Your input file should be a standard text file where each line represents a new user, separated by commas. Example: username,Full Name,Department.

Method 1: The Basic 'For /F' Loop

The core command for reading files in Batch is FOR /F. We tell it to use a comma as the delimiter (delims=,).

users.csv:

jdoe,John Doe
asmith,Alice Smith

script.bat:

@echo off
setlocal EnableDelayedExpansion

:: Check for admin rights
net session >nul 2>&1
if %errorlevel% neq 0 (
echo [ERROR] Administrator privileges are required.
pause
exit /b 1
)

set "CSV=%~dp0users.csv"

if not exist "%CSV%" (
echo [ERROR] CSV file not found: %CSV%
pause
exit /b 1
)

echo [PROCESS] Reading user list from %CSV%...
echo.

:: Loop through each line. Token 1 is username, Token 2 is Full Name.
for /f "usebackq tokens=1,2 delims=," %%a in ("%CSV%") do (
echo Creating account for: %%a (%%b^)
net user "%%a" "TempP@ssw0rd" /add /fullname:"%%b" /active:yes >nul 2>&1

if !errorlevel! equ 0 (
:: Force password change at first login
net user "%%a" /logonpasswordchg:yes >nul 2>&1
echo [OK] Created.
) else (
echo [FAIL] Could not create (may already exist or password too weak^).
)
)

echo.
echo [DONE] User creation complete.
pause

Method 2: Advanced CSV Parsing with Header Skip

Real CSVs often have a header row (User,Name,Dept). We need to skip this row using the skip=1 option in our loop.

new_hires.csv:

Username,FullName,Department
jdoe,John Doe,Engineering
asmith,Alice Smith,Marketing
bwilson,Bob Wilson,Finance
@echo off
setlocal EnableDelayedExpansion

set "INPUT=%~dp0new_hires.csv"
set "LOG_DIR=%~dp0ProvisioningLogs"
if not exist "!LOG_DIR!" mkdir "!LOG_DIR!"
set "LOG=!LOG_DIR!\creation_log_%date:~-4%%date:~-10,2%%date:~-7,2%.txt"

echo [PROCESS] Bulk User Creation Tool
echo -----------------------------------

:: Check for admin rights
net session >nul 2>&1
if %errorlevel% neq 0 (
echo [ERROR] Administrator privileges are required.
pause
exit /b 1
)

if not exist "%INPUT%" (
echo [ERROR] Input file not found: %INPUT%
echo [ACTION] Create a CSV with: Username,FullName,Department
pause
exit /b 1
)

:: Initialize counters
set "CREATED=0"
set "FAILED=0"
set "TOTAL=0"

:: Report header
(
echo === BULK USER CREATION LOG ===
echo Computer: %COMPUTERNAME%
echo Date: %DATE% %TIME%
echo Input: %INPUT%
echo.
) > "!LOG!"

:: Process the file, skipping the first line (Header)
echo.
for /f "usebackq skip=1 tokens=1,2,3 delims=," %%A in ("%INPUT%") do (
set /a "TOTAL+=1"
set "USN=%%A"
set "REALNAME=%%B"
set "DEPT=%%C"

echo [!TOTAL!] Provisioning "!USN!"...
net user "!USN!" "P@ssword99" /add /fullname:"!REALNAME!" /comment:"Dept: !DEPT!" /active:yes >nul 2>&1

if !errorlevel! equ 0 (
net user "!USN!" /logonpasswordchg:yes >nul 2>&1
echo [OK] Created. Must change password at first login.
echo [OK] !USN! - !REALNAME! - !DEPT! >> "!LOG!"
set /a "CREATED+=1"
) else (
echo [FAIL] Error creating "!USN!" (exists or password policy^).
echo [FAIL] !USN! - !REALNAME! - !DEPT! >> "!LOG!"
set /a "FAILED+=1"
)
)

:: Summary
(
echo.
echo === SUMMARY ===
echo Total: !TOTAL! Created: !CREATED! Failed: !FAILED!
) >> "!LOG!"

echo.
echo [RESULT] Created: !CREATED! ^| Failed: !FAILED! ^| Total: !TOTAL!
echo [LOG] Saved to: !LOG!
pause

Creating a Robust Onboarding Script

This script adds comprehensive validation, sets accounts for password change at first login, and produces a detailed report.

@echo off
setlocal EnableDelayedExpansion

echo ============================================================
echo Mass Account Generator
echo ============================================================

set "FILE=%~dp0students.csv"

:: 1. Verify Admin Rights
net session >nul 2>&1
if %errorlevel% neq 0 (
echo [ERROR] Administrator privileges are required.
pause
exit /b 1
)

:: 2. Verify input file
if not exist "%FILE%" (
echo [ERROR] CSV file not found: %FILE%
echo.
echo [INFO] Expected format (one per line^):
echo username,TemporaryPassword
pause
exit /b 1
)

:: 3. Count lines for progress
set "LINE_COUNT=0"
for /f "usebackq tokens=*" %%x in ("%FILE%") do set /a "LINE_COUNT+=1"
echo [INFO] Found !LINE_COUNT! entries in CSV.
echo.

set /p "CONFIRM=Create !LINE_COUNT! user accounts? (Y/N): "
if /i not "!CONFIRM!"=="Y" (
echo [INFO] Cancelled.
pause
exit /b 0
)

:: 4. Process users
echo.
set "NUM=0"
set "OK=0"
set "ERR=0"

for /f "usebackq tokens=1,2 delims=," %%i in ("%FILE%") do (
set /a "NUM+=1"
set "U=%%i"
set "P=%%j"

:: Skip empty lines
if not "!U!"=="" (
:: Check if user already exists
net user "!U!" >nul 2>&1
if !errorlevel! equ 0 (
echo [!NUM!/!LINE_COUNT!] SKIP "!U!" - already exists
) else (
:: Create User
net user "!U!" "!P!" /add >nul 2>&1
if !errorlevel! equ 0 (
:: Force password change at next logon
net user "!U!" /logonpasswordchg:yes >nul 2>&1
echo [!NUM!/!LINE_COUNT!] OK "!U!" - created
set /a "OK+=1"
) else (
echo [!NUM!/!LINE_COUNT!] FAIL "!U!" - check password complexity
set /a "ERR+=1"
)
)
)
)

echo.
echo [RESULT] Created: !OK! ^| Failed: !ERR! ^| Total: !NUM!
echo ============================================================
pause

Common Pitfalls and How to Avoid Them

CSV Delimiters

If a user's name contains a comma (e.g., "Doe, John"), the standard comma delimiter will break the script.

Solution: Use a different delimiter if possible (like a pipe | or semicolon ;) and update your script: delims=|.

Password Complexity

If your server has strict password requirements enforced by GPO (e.g., must be 12 chars), running net user with a simple password like "Start123" will fail with "The password does not meet the password policy requirements."

SEO and UX Tip

Advise your users to generate a complex random password for each user in the CSV, or update the local policy to allow the temporary password and force a change at first login.

Best Practices for Bulk Creation

  1. Test with One User: Before running a script against 1,000 names, create a test CSV with just one line to ensure the syntax and permissions work perfectly.
  2. Use /active:no Initially: For security, create the accounts as disabled first. Once the script finishes and you verify the log file is error-free, run a second loop to enable them.
  3. Force Password Change: Always add /logonpasswordchg:yes after creation so the temporary password is replaced at first login.
Quoting

If your CSV values have spaces (e.g., "John Doe"), ensure your net user command wraps the variable in quotes: /fullname:"%%b".

Conclusion

Bulk creating users from a CSV file via Batch script is a quintessential skill for scaling your IT operations. By turning a repetitive, manual task into an automated, loggable process, you save hours of work and ensure 100% consistency in your user directory. This professional approach to provisioning empowers you to handle new school years, corporate mergers, or large project teams effortlessly, keeping your administration agile and error-free.