Allowing non-privileged users to cause privileged code to run
perhaps a signed stored procedure would work? I'm looking for the simplest, sanest options here, thinking forwards to whoever winds up looking after this server after me and looking for solutions that will be understandable and maintainable.


Yes. A signed stored procedure absolutely would work, and would work well. As individual requirements go, "simplest" is not always overlapping with "sanest"; all too often people choose the simplest approach, giving up far too much sanity (which is understandable given that the simplest approach is, by definition, the easiest to understand, and the "saner" approach isn't obviously saner (at least not at first)). This is where Module Signing comes in. While not being the simplest approach, it is by far the sanest, all things considered. Unfortunately, it is also not well understood, and so appears to be more confusing / difficult than it really is.



The general concept is:


Create the stored procedure (in the "management" DB) that creates the student's database:


Have a parameter for the project name (remember: max DB name can be 128 characters, and you need to reserve some number of those for the students logon name as a prefix of the DB name, so depending on how long those get, size this appropriately, maybe 20 - 30 characters max, hence NVARCHAR(20ish))
Create the database with the desired naming convention (including project name). You can get their logon name from a variety of system variables and built-in functions, though ORIGINAL_LOGIN() might be the best option. You might need to do simple string manipulation as the name will be prefixed with the machine/domain name.
USE the new DB
Create a user for that student's account:

DECLARE @User NVARCHAR(258) = ORIGINAL_LOGIN();
SET @User = QUOTENAME(manipulated_@User);
EXEC (N'CREATE USER ' + @User);

Add permissions / roles for student's account:

EXEC (N'ALTER ROLE [db_datareader] ADD MEMBER ' + @User);
...


Create the stored procedure (in the "management" DB) that drops the student's database:


Have a parameter for the project name (remember: max DB name can be 128 characters, and you need to reserve some number of those for the students logon name as a prefix of the DB name, so depending on how long those get, size this appropriately, maybe 20 - 30 characters max, hence NVARCHAR(20ish))
Drop the database having the desired naming convention (including project name). 1. Grant EXECUTE on these modules to whatever user and/or roles need to perform these actions (could be "student" AD group, or [public] as noted in the chat room

Create a certificate (in the "management" DB)
Sign the stored procedures using that certificate (using ADD SIGNATURE)
Copy the certificate to the [master] database (i.e. create a certificate in [master] using the public key of the certificate used to sign the stored procedures).
Create a login from the certificate copied to [master]
Grant whatever instance-level permissions are necessary to that certificate-based login (which can include adding it to instance-level roles).


For some examples, please see:


How to maintain database ownership restoring across domains?
Safely and Easily Use High-Level Permissions Without Granting Them to Anyone: Server-level