Figment.so
Mac hostingWebsite hostingGuidesHow to usePricing

Provision Remote Macs for a Student Cohort

Creating 20 student accounts on rented Macs by hand — one user at a time, then installing tools, distributing passwords, and cleaning up in week 15 — fills a working day and invites copy-paste mistakes. A single bash script driven by a CSV reduces that to under an hour, produces a consistent environment per student, and leaves you a reusable cleanup script for the end of term.

Direct recommendation. For a general CS cohort doing Python, web, or shell work, start with one $29 virtual Intel macOS instance per concurrent student (2 vCPU, 8 GiB RAM, 80 GiB disk). Each VM is accessed through its own owner-bound browser console, so running 20 students on one shared host is not the model — you request 20 VMs and hand each student the login to their own. For Swift/iOS courses or Apple-silicon-only tooling, request the M-series tier from $95/month; the exact chip, RAM, disk and multi-user access path are confirmed in the quote. Physical plans collect requests until supply is confirmed, so place the semester order a few weeks before the first class.

User-account types and the graphical setup path are documented in Apple's Users, Guests & Groups guide. Confirm the authoritative flag list for the command-line tool on your host with sysadminctl -h — flag names have shifted across macOS versions.

Planning: How Many Macs, How Many Students per Host

Decide on the hardware before you script anything. The right choice depends on the course:

Course typeMac tierStudents per hostMonthly starting cost
General CS — Python, web, shell$29 Intel VM1 per VM (owner-bound console)$29 × 20 = $580 for 20 concurrent VMs
Swift / iOS — recent Xcode on Apple siliconM-series from $951–4 per host, confirmed in quote$95 × N hosts
Mixed cohort with some GPU/arm64 executionM-series from $951–4 per host, confirmed in quotevaries with quote

A 15-week semester is roughly 3.5 months, so multiply the monthly figure by 4 to cover enrolment windows and a buffer week. Time-slotted access (morning / afternoon groups) can cut host count in half at the cost of scheduling.

Intel Xcode 26 or earlier can cross-compile and sign arm64 apps as universal binaries, per Apple's Porting your macOS apps to Apple silicon guidance, but executing arm64-only binaries, running Xcode 27, or working on visionOS requires Apple silicon. For an iOS curriculum that relies on current simulators, request M-series; verify the exact Xcode and macOS pair against your syllabus.

Request availability with Figment — the $95 M-series price is the starting line for a configuration request, not a fixed chip spec.

CSV Format: Required Fields

Create students.csv with these columns. Use lowercase usernames without spaces or special characters:

fullname,username,email
Alice Chen,achen,achen@university.edu
Bob Okafor,bokafor,bokafor@university.edu
Cleo Vasquez,cvasquez,cvasquez@university.edu

Export from your student information system or registration spreadsheet. The provisioning script reads it one row at a time.

Bulk Account Creation with sysadminctl

sysadminctl creates local accounts on recent macOS versions and allocates the UID for you. Run the script below as root on each M-series host where you have administrator access (confirmed in your quote), or inside each $29 VM through its browser-console terminal if you are provisioning one VM per student:

#!/usr/bin/env bash
# provision-students.sh — run as root on each Mac host
# Usage: sudo ./provision-students.sh students.csv smtp-relay.yourschool.edu

set -euo pipefail

CSV="${1:?Usage: sudo $0 students.csv smtp-relay.yourschool.edu}"
RELAY="${2:?provide smtp relay hostname}"
export RELAY

umask 077
CREDS_LOG="$(mktemp -t creds.XXXXXX)"
trap 'rm -f "$CREDS_LOG"' EXIT

# Skip header row
tail -n +2 "$CSV" | while IFS=',' read -r fullname username email; do
  tmppass="$(LC_ALL=C tr -dc 'A-Za-z0-9' </dev/urandom | head -c 16)"

  if sysadminctl -addUser "$username" \
      -fullName "$fullname" \
      -password "$tmppass" \
      -home "/Users/$username" \
      -shell /bin/zsh 2>/dev/null; then
    createhomedir -cu "$username" >/dev/null 2>&1 || true
    echo "Created: $username"
  else
    echo "SKIP (exists or failed): $username"
    continue
  fi

  printf '%s,%s,%s,%s\n' "$fullname" "$username" "$email" "$tmppass" >> "$CREDS_LOG"
done

# Hand credentials to the mail step before the trap removes the file
cp "$CREDS_LOG" ./creds.current && chmod 600 ./creds.current
echo "Accounts complete. Credentials staged at ./creds.current"
echo "Run the email step next, then: rm -P ./creds.current"

The umask 077 sets restrictive permissions before mktemp writes, the trap removes the temp file on exit, and ./creds.current is the single copy you consume in the next step. Delete it with rm -P as soon as the emails are sent. If your institution has a secure credential portal, use that instead and treat the mail step as a one-time reset link.

Bootstrap Script: Install Homebrew, git, and Runtimes

Run this once per student user, right after account creation, for a consistent toolchain:

#!/usr/bin/env bash
# bootstrap-student.sh — run as the target student user
set -euo pipefail

if ! command -v brew >/dev/null 2>&1; then
  NONINTERACTIVE=1 /bin/bash -c \
    "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)"
fi

# Apple silicon installs under /opt/homebrew; Intel under /usr/local
if [ -x /opt/homebrew/bin/brew ]; then
  eval "$(/opt/homebrew/bin/brew shellenv)"
else
  eval "$(/usr/local/bin/brew shellenv)"
fi

brew install git node python

# Course-specific additions — edit to match your syllabus
# brew install go
echo "Bootstrap complete for $(whoami)"

Invoke it from the provisioning script with sudo -u "$username" bash /path/to/bootstrap-student.sh. The clean VM and a clean physical host ship with macOS only; everything else you see here is installed by this script, so budget the first run (Homebrew plus three formulae) at roughly 10–20 minutes depending on network.

Distributing Credentials via the Institution Mail Relay

Send each student their username and temporary password from ./creds.current, using your institutional SMTP relay so the message arrives from a trusted domain:

#!/usr/bin/env bash
set -euo pipefail
: "${RELAY:?set RELAY to your SMTP relay hostname}"

while IFS=',' read -r fullname username email tmppass; do
  # s-nail provides the -S smtp= option (brew install s-nail)
  mail -s "Your Mac rental login — $(hostname)" \
       -S smtp="smtp://${RELAY}:25" \
       -r "it-admin@university.edu" \
       "$email" <<EOF
Hello $fullname,

Your temporary Mac login for this semester:
  Host:     $(hostname)
  Username: $username
  Password: $tmppass

Please change your password on first login with: passwd

Contact it-support@university.edu if you have trouble connecting.
EOF
done < ./creds.current

If the relay requires authentication, keep the user and password in ~/.mailrc with mode 600 rather than on the command line. After the loop, rm -P ./creds.current.

Mid-Semester Support

Reset a forgotten password on the host:

sudo sysadminctl -resetPasswordFor achen -newPassword 'TempPass-9f2c'

Notify the student through a channel they still have access to. Reinstall a broken package or add a tool mid-term as the student user:

sudo -u achen brew reinstall python
sudo -u achen brew install jupyter

If your institution licenses Apple Remote Desktop, its console can push the same command to many hosts at once — useful when the syllabus adds a tool in week 7.

End-of-Term Cleanup: Export, Then Delete

Give students a window (a two-week reminder email covers most cases) to retrieve their work. Then:

#!/usr/bin/env bash
# cleanup-students.sh — run as root; archives home dirs before deletion
set -euo pipefail

CSV="${1:?provide students.csv}"
ARCHIVE_DIR="/tmp/student-archives-$(date +%Y%m)"
mkdir -p "$ARCHIVE_DIR"
chmod 700 "$ARCHIVE_DIR"

tail -n +2 "$CSV" | while IFS=',' read -r fullname username email; do
  if id "$username" >/dev/null 2>&1; then
    tar -czf "${ARCHIVE_DIR}/${username}-$(date +%Y%m%d).tar.gz" \
        -C /Users "$username" || { echo "archive failed: $username"; continue; }
    # Confirm the current delete-user flag on your macOS version with: sysadminctl -h
    sysadminctl -deleteUser "$username" -secure
    echo "Removed: $username"
  fi
done

echo "Archives staged in: $ARCHIVE_DIR — transfer off-host before releasing the Mac."

Move $ARCHIVE_DIR to institutional storage before the rental ends. Home-directory archives can be large; run df -h /tmp first and switch the archive path to a larger volume if needed. For a shared M-series host serving several students, confirm with your Figment quote whether the host is released as a whole at term end or whether you keep it for the next cohort.

Ready to kick off the semester? Request a configuration with host count, preferred macOS version, and the access method you want students to use (browser console for $29 VMs, or the method agreed in your M-series quote).


Subscribe for Figma design and website publishing guides.


Figment.so

Contact

Twitter

Website pricing

Compute index

About

Privacy

Terms