diff --git a/lib/WeBWorK/ContentGenerator/CourseAdmin.pm b/lib/WeBWorK/ContentGenerator/CourseAdmin.pm
index a217800615..d0e9bab017 100644
--- a/lib/WeBWorK/ContentGenerator/CourseAdmin.pm
+++ b/lib/WeBWorK/ContentGenerator/CourseAdmin.pm
@@ -230,17 +230,18 @@ sub pre_header_initialize ($c) {
 }
 
 sub add_course_form ($c) {
+	$c->param('number_of_additional_users', ($c->param('number_of_additional_users') // 0) + 1)
+		if $c->param('add_another_instructor');
+
 	return $c->include('ContentGenerator/CourseAdmin/add_course_form');
 }
 
 sub add_course_validate ($c) {
 	my $ce = $c->ce;
 
-	my $add_courseID                = trim_spaces($c->param('new_courseID'))                || '';
-	my $add_initial_userID          = trim_spaces($c->param('add_initial_userID'))          || '';
-	my $add_initial_password        = trim_spaces($c->param('add_initial_password'))        || '';
-	my $add_initial_confirmPassword = trim_spaces($c->param('add_initial_confirmPassword')) || '';
-	my $add_dbLayout                = trim_spaces($c->param('add_dbLayout'))                || '';
+	my $add_courseID               = trim_spaces($c->param('new_courseID'))  || '';
+	my $number_of_additional_users = $c->param('number_of_additional_users') || 0;
+	my $add_dbLayout               = trim_spaces($c->param('add_dbLayout'))  || '';
 
 	my @errors;
 
@@ -257,11 +258,24 @@ sub add_course_validate ($c) {
 		push @errors, $c->maketext('Course ID cannot exceed [_1] characters.', $ce->{maxCourseIdLength});
 	}
 
-	if ($add_initial_userID ne ''
-		&& $add_initial_password ne ''
-		&& $add_initial_password ne $add_initial_confirmPassword)
-	{
-		push @errors, $c->maketext('The password and password confirmation for the instructor must match.');
+	for (1 .. $number_of_additional_users) {
+		my $userID          = trim_spaces($c->param("add_initial_userID_$_"))          || '';
+		my $password        = trim_spaces($c->param("add_initial_password_$_"))        || '';
+		my $confirmPassword = trim_spaces($c->param("add_initial_confirmPassword_$_")) || '';
+
+		if ($userID ne '') {
+			unless ($userID =~ /^[\w-.,]*$/) {
+				push @errors,
+					$c->maketext(
+						'User ID number [_1] may only contain letters, numbers, hyphens, periods, commas, '
+						. 'and underscores.',
+						$_
+					);
+			}
+			if ($password ne '' && $password ne $confirmPassword) {
+				push @errors, $c->maketext('Pasword number [_1] and its password confirmation must match.', $_);
+			}
+		}
 	}
 
 	if ($add_dbLayout eq '') {
@@ -283,17 +297,10 @@ sub do_add_course ($c) {
 	my $db    = $c->db;
 	my $authz = $c->authz;
 
-	my $add_courseID          = trim_spaces($c->param('new_courseID')) // '';
-	my $add_courseTitle       = ($c->param('add_courseTitle')       // '') =~ s/^\s*|\s*$//gr;
-	my $add_courseInstitution = ($c->param('add_courseInstitution') // '') =~ s/^\s*|\s\*$//gr;
-
-	my $add_initial_userID          = trim_spaces($c->param('add_initial_userID'))          // '';
-	my $add_initial_password        = trim_spaces($c->param('add_initial_password'))        // '';
-	my $add_initial_confirmPassword = trim_spaces($c->param('add_initial_confirmPassword')) // '';
-	my $add_initial_firstName       = trim_spaces($c->param('add_initial_firstName'))       // '';
-	my $add_initial_lastName        = trim_spaces($c->param('add_initial_lastName'))        // '';
-	my $add_initial_email           = trim_spaces($c->param('add_initial_email'))           // '';
-	my $add_initial_user            = $c->param('add_initial_user')                         // 0;
+	my $add_courseID               = trim_spaces($c->param('new_courseID')) // '';
+	my $add_courseTitle            = ($c->param('add_courseTitle')       // '') =~ s/^\s*|\s*$//gr;
+	my $add_courseInstitution      = ($c->param('add_courseInstitution') // '') =~ s/^\s*|\s\*$//gr;
+	my $number_of_additional_users = $c->param('number_of_additional_users') || 0;
 
 	my $copy_from_course = trim_spaces($c->param('copy_from_course')) // '';
 
@@ -314,12 +321,17 @@ sub do_add_course ($c) {
 			));
 			next;
 		}
-		if ($userID eq $add_initial_userID) {
-			$c->addbadmessage($c->maketext(
-				'User "[_1]" will not be copied from the [_2] course as it is the initial instructor.', $userID,
-				$ce->{admin_course_id}
-			));
-			next;
+		for (1 .. $number_of_additional_users) {
+			my $add_initial_userID = trim_spaces($c->param("add_initial_userID_$_")) // '';
+
+			if ($userID eq $add_initial_userID) {
+				$c->addbadmessage($c->maketext(
+					'User "[_1]" will not be copied from the [_2] course as it is the same as additional user '
+						. 'number [_3].',
+					$userID, $ce->{admin_course_id}, $_
+				));
+				next;
+			}
 		}
 
 		my $PermissionLevel = $db->getPermissionLevel($userID);
@@ -330,43 +342,56 @@ sub do_add_course ($c) {
 		push @users, [ $User, $Password, $PermissionLevel ];
 	}
 
-	# add initial instructor if desired
-	if ($add_initial_userID =~ /\S/) {
-		my $User = $db->newUser(
-			user_id       => $add_initial_userID,
-			first_name    => $add_initial_firstName,
-			last_name     => $add_initial_lastName,
-			email_address => $add_initial_email,
-			status        => 'O',
-		);
-		my $Password = $db->newPassword(
-			user_id  => $add_initial_userID,
-			password => $add_initial_password ? cryptPassword($add_initial_password) : '',
-		);
-		my $PermissionLevel = $db->newPermissionLevel(
-			user_id    => $add_initial_userID,
-			permission => '10',
-		);
-		push @users, [ $User, $Password, $PermissionLevel ];
-
-		# Add initial user to admin course if asked.
-		if ($add_initial_user) {
-			if ($db->existsUser($add_initial_userID)) {
-				$c->addbadmessage($c->maketext(
-					'User "[_1]" will not be added to the [_2] course as it already exists.', $add_initial_userID,
-					$ce->{admin_course_id}
-				));
-			} else {
-				$User->status('D');    # By default don't allow user to login.
-				$db->addUser($User);
-				$db->addPassword($Password);
-				$db->addPermissionLevel($PermissionLevel);
-				$User->status('O');
+	# add additional instructors if desired
+	for (1 .. $number_of_additional_users) {
+		my $userID          = trim_spaces($c->param("add_initial_userID_$_"))          // '';
+		my $password        = trim_spaces($c->param("add_initial_password_$_"))        // '';
+		my $confirmPassword = trim_spaces($c->param("add_initial_confirmPassword_$_")) // '';
+		my $firstName       = trim_spaces($c->param("add_initial_firstName_$_"))       // '';
+		my $lastName        = trim_spaces($c->param("add_initial_lastName_$_"))        // '';
+		my $email           = trim_spaces($c->param("add_initial_email_$_"))           // '';
+		my $studentID       = trim_spaces($c->param("add_initial_studentID_$_"))       // '';
+		my $permissionLevel = trim_spaces($c->param("add_initial_permission_$_"));
+		my $add_user        = $c->param("add_initial_user_$_") // 0;
+
+		if ($userID =~ /\S/) {
+			my $User = $db->newUser(
+				user_id       => $userID,
+				first_name    => $firstName,
+				last_name     => $lastName,
+				email_address => $email,
+				student_id    => $studentID,
+				status        => 'O',
+			);
+			my $Password = $db->newPassword(
+				user_id  => $userID,
+				password => $password ? cryptPassword($password) : '',
+			);
+			my $PermissionLevel = $db->newPermissionLevel(
+				user_id    => $userID,
+				permission => $permissionLevel,
+			);
+			push @users, [ $User, $Password, $PermissionLevel ];
+
+			# Add initial user to admin course if asked.
+			if ($add_user) {
+				if ($db->existsUser($userID)) {
+					$c->addbadmessage($c->maketext(
+						'User "[_1]" will not be added to the [_2] course as it already exists.', $userID,
+						$ce->{admin_course_id}
+					));
+				} else {
+					$User->status('D');    # By default don't allow user to login.
+					$db->addUser($User);
+					$db->addPassword($Password);
+					$db->addPermissionLevel($PermissionLevel);
+					$User->status('O');
+				}
 			}
 		}
 	}
 
-	push @{ $courseOptions{PRINT_FILE_NAMES_FOR} }, map { $_->[0]->user_id } @users;
+	push @{ $courseOptions{PRINT_FILE_NAMES_FOR} }, map { $_->[0]->user_id } grep { $_->[2]->permission >= 10 } @users;
 
 	# Include any optional arguments, including a template course and the course title and course institution.
 	my %optional_arguments;
@@ -386,11 +411,10 @@ sub do_add_course ($c) {
 
 	eval {
 		addCourse(
-			courseID       => $add_courseID,
-			ce             => $ce2,
-			courseOptions  => \%courseOptions,
-			users          => \@users,
-			initial_userID => $add_initial_userID,
+			courseID      => $add_courseID,
+			ce            => $ce2,
+			courseOptions => \%courseOptions,
+			users         => \@users,
 			%optional_arguments,
 		);
 	};
@@ -419,11 +443,7 @@ sub do_add_course ($c) {
 				"\tAdded",
 				(defined $add_courseInstitution ? $add_courseInstitution : '(no institution specified)'),
 				(defined $add_courseTitle       ? $add_courseTitle       : '(no title specified)'),
-				$add_courseID,
-				$add_initial_firstName,
-				$add_initial_lastName,
-				$add_initial_email,
-			)
+				$add_courseID)
 		);
 		push(
 			@$output,
diff --git a/lib/WeBWorK/Utils/CourseManagement.pm b/lib/WeBWorK/Utils/CourseManagement.pm
index f8f6450ef9..6ea4eac5db 100644
--- a/lib/WeBWorK/Utils/CourseManagement.pm
+++ b/lib/WeBWorK/Utils/CourseManagement.pm
@@ -201,7 +201,7 @@ boolean options:
 =cut
 
 sub addCourse {
-	my (%options) = (initial_userID => '', @_);
+	my (%options) = @_;
 
 	for my $key (keys(%options)) {
 		my $value = '####UNDEF###';
@@ -217,7 +217,7 @@ sub addCourse {
 
 	debug \@users;
 
-	my ($initialUser) = grep { $_->[0]{user_id} eq $options{initial_userID} } @users;
+	my @initialUsers = grep { $_->[2]->permission < $ce->{userRoles}{admin} } @users;
 
 	# get the database layout out of the options hash
 	my $dbLayoutName = $courseOptions{dbLayoutName};
@@ -407,7 +407,7 @@ sub addCourse {
 				assignSetsToUsers($db, $ce, \@user_sets, [$user_id]);
 			}
 		}
-		assignSetsToUsers($db, $ce, \@set_ids, [ $initialUser->[0]{user_id} ]) if $initialUser;
+		assignSetsToUsers($db, $ce, \@set_ids, [ map { $_->[0]{user_id} } @initialUsers ]) if @initialUsers;
 	}
 
 	# add achievements
@@ -416,9 +416,9 @@ sub addCourse {
 		for my $achievement_id (@achievement_ids) {
 			eval { $db->addAchievement($db0->getAchievement($achievement_id)) };
 			warn $@ if $@;
-			if ($initialUser) {
+			for (@initialUsers) {
 				my $userAchievement = $db->newUserAchievement();
-				$userAchievement->user_id($initialUser->[0]{user_id});
+				$userAchievement->user_id($_->[0]{user_id});
 				$userAchievement->achievement_id($achievement_id);
 				$db->addUserAchievement($userAchievement);
 			}
diff --git a/templates/ContentGenerator/CourseAdmin/add_course_form.html.ep b/templates/ContentGenerator/CourseAdmin/add_course_form.html.ep
index fab6ac3c91..3e37f0de09 100644
--- a/templates/ContentGenerator/CourseAdmin/add_course_form.html.ep
+++ b/templates/ContentGenerator/CourseAdmin/add_course_form.html.ep
@@ -1,5 +1,19 @@
 % use WeBWorK::Utils::CourseManagement qw(listCourses);
 %
+% # Create an array of permission values for the permission selects.
+% my $permissionLevels = [];
+% for my $role (sort { $ce->{userRoles}{$a} <=> $ce->{userRoles}{$b} } keys %{ $ce->{userRoles} }) {
+	% next if $role eq 'nobody';
+	% push(
+		% @$permissionLevels,
+		% [
+			% $c->maketext($role) => $ce->{userRoles}{$role},
+			% $ce->{userRoles}{$role} == 10 ? (selected => undef) : ()
+		% ]
+	% );
+% }
+% my $number_of_additional_users = $c->param('number_of_additional_users') || 0;
+%
 <h2><%= maketext('Add Course') %> <%= $c->helpMacro('AdminAddCourse') %></h2>
 %
 <%= form_for current_route, method => 'POST', begin =%>
@@ -60,64 +74,85 @@
 	</div>
 	<div class="mb-2">
 		<%= maketext(
-			'To add an additional instructor to the new course, specify user information below. '
-				. 'The user ID may contain only numbers, letters, hyphens, periods (dots), commas,and underscores.'
+			'To add additional instructor(s) to the new course, specify user information below. '
+				. 'The user ID may contain only numbers, letters, hyphens, periods (dots), commas, and underscores.'
 		) =%>
 	</div>
-	<div class="row mb-1">
-		<div class="col-lg-4 col-md-5 col-sm-6">
-			<div class="form-floating mb-1">
-				<%= text_field add_initial_userID => '',
-					id          => 'add_initial_userID',
-					placeholder => '',
-					class       => 'form-control' =%>
-				<%= label_for add_initial_userID => maketext('User ID') =%>
-			</div>
-			<div class="form-floating mb-1">
-				<%= password_field 'add_initial_password',
-					id           => 'add_initial_password',
-					placeholder  => '',
-					class        => 'form-control',
-					autocomplete => 'new-password' =%>
-				<%= label_for add_initial_password => maketext('Password') =%>
+	<div class="mb-1">
+	% for (1 .. $number_of_additional_users) {
+		<div class="row mb-1">
+			<div class="col-lg-4 col-md-5 col-sm-6">
+				<div class="form-floating mb-1">
+					<%= text_field "add_initial_userID_$_" => '',
+						id          => "add_initial_userID_$_",
+						placeholder => '',
+						class       => 'form-control' =%>
+					<%= label_for "add_initial_userID_$_" => maketext('User ID') =%>
+				</div>
+				<div class="form-floating mb-1">
+					<%= password_field "add_initial_password_$_",
+						id           => "add_initial_password_$_",
+						placeholder  => '',
+						class        => 'form-control',
+						autocomplete => 'new-password' =%>
+					<%= label_for "add_initial_password_$_" => maketext('Password') =%>
+				</div>
+				<div class="form-floating mb-1">
+					<%= password_field "add_initial_confirmPassword_$_",
+						id          => "add_initial_confirmPassword_$_",
+						placeholder => '',
+						class       => 'form-control' =%>
+					<%= label_for "add_initial_confirmPassword_$_" => maketext('Confirm Password') =%>
+				</div>
+				<div class="form-floating mb-1">
+					<%= select_field "add_initial_permission_$_" => $permissionLevels,
+						id      => "add_initial_role_$_",
+						class   => 'form-select' =%>
+					<%= label_for "add_initial_permission_$_" => maketext('Permission Level') =%>
+				</div>
 			</div>
-			<div class="form-floating mb-1">
-				<%= password_field 'add_initial_confirmPassword',
-					id          => 'add_initial_confirmPassword',
-					placeholder => '',
-					class       => 'form-control' =%>
-				<%= label_for add_initial_confirmPassword => maketext('Confirm Password') =%>
+			<div class="col-lg-4 col-md-5 col-sm-6">
+				<div class="form-floating mb-1">
+					<%= text_field "add_initial_firstName_$_" => '',
+						id          => "add_initial_firstName_$_",
+						placeholder => '',
+						class       => 'form-control' =%>
+					<%= label_for "add_initial_firstName_$_" => maketext('First Name') =%>
+				</div>
+				<div class="form-floating mb-1">
+					<%= text_field "add_initial_lastName_$_" => '',
+						id          => "add_initial_lastName_$_",
+						placeholder => '',
+						class       => 'form-control' =%>
+					<%= label_for "add_initial_lastName_$_" => maketext('Last Name') %>
+				</div>
+				<div class="form-floating mb-1">
+					<%= text_field "add_initial_email_$_" => '',
+						id          => "add_initial_email_$_",
+						placeholder => '',
+						class       => 'form-control' =%>
+					<%= label_for "add_initial_email_$_" => maketext('Email Address') =%>
+				</div>
+				<div class="form-floating mb-1">
+					<%= text_field "add_initial_studentID_$_" => '',
+						id          => "add_initial_studentID_$_",
+						placeholder => '',
+						class       => 'form-control' =%>
+					<%= label_for "add_initial_studentID_$_" => maketext('Student ID') =%>
+				</div>
 			</div>
 		</div>
-		<div class="col-lg-4 col-md-5 col-sm-6">
-			<div class="form-floating mb-1">
-				<%= text_field add_initial_firstName => '',
-					id          => 'add_initial_firstName',
-					placeholder => '',
-					class       => 'form-control' =%>
-				<%= label_for add_initial_firstName => maketext('First Name') =%>
-			</div>
-			<div class="form-floating mb-1">
-				<%= text_field add_initial_lastName => '',
-					id          => 'add_initial_lastName',
-					placeholder => '',
-					class       => 'form-control' =%>
-				<%= label_for add_initial_lastName => maketext('Last Name') %>
-			</div>
-			<div class="form-floating mb-1">
-				<%= text_field add_initial_email => '',
-					id          => 'add_initial_email',
-					placeholder => '',
-					class       => 'form-control' =%>
-				<%= label_for add_initial_email => maketext('Email Address') =%>
-			</div>
+		<div class="form-check mb-3">
+			<label class="form-check-label">
+				<%= check_box "add_initial_user_$_" => 1, class => 'form-check-input' =%>
+				<%= maketext('Also add this user to the [_1] course.', $ce->{admin_course_id}) =%>
+			</label>
 		</div>
+	% }
 	</div>
-	<div class="form-check mb-3">
-		<label class="form-check-label">
-			<%= check_box 'add_initial_user' => 1, class => 'form-check-input' =%>
-			<%= maketext('Also add this user to the [_1] course.', $ce->{admin_course_id}) =%>
-		</label>
+	<div class="mb-3">
+		<%= submit_button maketext('Add Another Instructor'), name => 'add_another_instructor',
+			class => 'btn btn-primary' =%>
 	</div>
 	<div class="mb-1">
 		<%= maketext('To copy components from an existing course, '
@@ -208,5 +243,6 @@
 	</fieldset>
 	<%= hidden_field add_dbLayout             => 'sql_single' =%>
 	<%= hidden_field last_page_was_add_course => 1 =%>
+	<%= $c->hidden_fields('number_of_additional_users') =%>
 	<%= submit_button maketext('Add Course'), name => 'add_course', class => 'btn btn-primary' =%>
 <% end =%>
diff --git a/templates/HelpFiles/AdminAddCourse.html.ep b/templates/HelpFiles/AdminAddCourse.html.ep
index c01fc1e330..734ecae554 100644
--- a/templates/HelpFiles/AdminAddCourse.html.ep
+++ b/templates/HelpFiles/AdminAddCourse.html.ep
@@ -28,12 +28,14 @@
 		$ce->{admin_course_id}) =%>
 </p>
 <p>
-	<%= maketext('Enter the details of a new course instructor to be added when the course is created.  The only '
-		. 'required field is the user ID of the this user.  Optionally, you can add this user to the [_1] course, '
-		. 'so you can copy this user when creating future courses, or manage and email course instructors.  Note, '
-		. 'by default these new users will be "Dropped" and unable to login to the [_1] course.  You can change '
-		. 'this on the "Accounts Manager" page. Additionally you can control access to the [_1] course by setting '
-		. q/$permissionLevels{login}='admin' in course.conf./, $ce->{admin_course_id}) =%>
+	<%= maketext('Optionally, to add additional instructors click the "Add Another Instructor" button, then enter '
+		. 'the details of a new course instructor to be added when the course is created.  The only required field '
+		. 'is the user ID of the this user.  Optionally, you can add this user to the [_1] course, so you can copy '
+		. 'this user when creating future courses, or manage and email course instructors.  Click the "Add Another '
+		. 'Instructor" button again to add multiple additional users.  Note, by default these new users will be '
+		. '"Dropped" and unable to login to the [_1] course.  You can change this on the "Accounts Manager" page. '
+		. q/Additionally you can control access to the [_1] course by setting $permissionLevels{login}='admin' in /
+		. 'course.conf.', $ce->{admin_course_id}) =%>
 </p>
 <p class="mb-0">
 	<%= maketext('You may choose a course to copy components from. Select the course and which components to copy.  '