Bulk Enrolling Users in Moodle via CSV: A Practical Guide
Learn how to structure a CSV file, run Moodle's bulk user enrolment via the enrol API, and verify successful imports while avoiding common pitfalls.
19 Nov 2025, 12:35 UTC

The Problem with Manual Enrolment
Adding learners to a course one‑by‑one works for a small class, but it quickly becomes a bottleneck when you need to onboard dozens or hundreds of users. Manual entry is slow, prone to typos, and makes it hard to audit who actually received which role.
How Moodle’s CSV Enrol API Works
Moodle does not simply dump CSV rows into a table. The data first passes through the enrol API, which validates each record against the rules defined in enrol/options.php. The API checks that the user exists (or can be created), that the course shortname is valid, and that the requested role is allowed for the selected enrolment plugin. Invalid rows are rejected while the rest of the file continues to process, and errors are recorded in the admin logs.
Structuring the CSV File
For a standard bulk enrolment the file must be UTF‑8 encoded and include the following columns (headers are case‑sensitive):
- username – unique identifier for the user.
- firstname and lastname – basic identity fields.
- email – used for account verification and notifications.
- course1, role1 – first course and the role to assign.
- course2, role2 – optional additional course/role pairs.
If a column is left blank for a particular row, Moodle treats it as “no enrolment” for that slot.
Worked Example: Enrolling Three Users Across Two Courses
Suppose you need to enrol the following users:
- Jane Doe – student in both
py101(Intro to Python) andeth202(Data Ethics). - Alan Smith – teacher in
py101and student ineth202. - Ray Lee – student only in
py101.
Create a CSV file named enrolments.csv with this content:
username,firstname,lastname,email,course1,role1,course2,role2
jdoe,Jane,Doe,[contact removed],py101,student,eth202,student
asmith,Alan,Smith,[contact removed],py101,teacher,eth202,student
rlee,Ray,Lee,[contact removed],py101,student,
Execution steps (run as an administrator):
- Go to Site administration → Users → Accounts → Upload users.
- Upload
enrolments.csv. - Set Upload type to Add new and update existing users.
- On the preview screen confirm that each column maps to the correct Moodle field.
- Click Upload users.
Verification: After the upload finishes, open the Course participants page for py101. You should see Alan Smith listed as a Teacher and both Jane Doe and Ray Lee as Students. For eth202, Jane Doe and Alan Smith should appear as Students. If any user is missing, review the summary report shown at the end of the upload process; it lists error codes for each rejected row.
Trade‑offs and Limitations
While the CSV enrolment flow is powerful, there are two important constraints to keep in mind:
- Password handling – The API does not hash or set passwords for newly created users. You must either pre‑populate passwords in the CSV (using the
passwordcolumn) or force a password reset on first login. - Silent failures – If a CSV header does not exactly match an expected API key, Moodle will ignore that column without raising an error. This can lead to users being created in the system but not enrolled in any course, a mistake that is easy to miss unless you check the enrolment logs.
Actionable Closing
Always start with a small test file (3‑5 rows) to confirm column mapping and to inspect the admin log for any warnings. After a successful test, proceed with the full import, then verify enrolments via the Course participants pages and the error report. Keeping a recent database backup before large imports provides a safety net should you need to roll back incorrect enrolments.
0 replies
A thoughtful contribution can make all the difference. Be the first to share one.