LifterLMS WP-CLI: Managing Courses and Students with wp llms

What the LifterLMS WP-CLI commands bundled with LifterLMS 10.x can do: list and create courses, read course structure and enrollments, manage add-ons and licenses, bulk-enroll students safely, and run background jobs from the command line.

  • Add as a preferred source on Google
Illustration for “LifterLMS WP-CLI: Managing Courses and Students with wp llms”

If you manage LifterLMS sites for clients, or you have SSH access to your own server, the command line is often the fastest way to answer questions and make bulk changes. How many students are in this course? Which add-ons need updates on all twelve sites? Can we enroll these 300 people before Monday? LifterLMS WP-CLI support handles all three.

This guide is for developers and technical site managers. It covers which wp llms commands exist in LifterLMS 10.x, how they work under the hood, practical recipes, and the safety habits that stop a one-line command from becoming a very bad afternoon.

Commands were checked against the LifterLMS 10.3 source and the LifterLMS CLI command reference. You need WP-CLI installed on the server.

LifterLMS WP-CLI: what is included

Since LifterLMS 10.1 the CLI is bundled in the core plugin; before that it was a separate download. There is nothing to install beyond WP-CLI itself. Run wp help llms to see the commands your version provides.

LifterLMS still labels the CLI a public beta and warns that commands may change without notice. Read the changelog before relying on a command in a scheduled script, and pin scripts to a tested LifterLMS version.

The command groups

CommandWhat it does
wp llms version [<slug>]Shows the LifterLMS version, or an add-on's version
wp llms course, section, lessonCourse content
wp llms membership, access-planMemberships and pricing
wp llms student, instructorPeople
wp llms api-keyREST API keys
wp llms course content <id>The full outline of a course: sections and lessons in order (added in 10.1)
wp llms course enrollments <id>Students enrolled in a course, paginated (added in 10.1)
wp llms addonList, install, activate, deactivate, update and uninstall add-ons
wp llms licenseActivate, deactivate and list license keys

The resource commands (course, lesson, student and so on) share the same subcommands: list, get, create, update, delete, plus diff, generate and edit. On 10.x you may also see commands for newer resources added to the REST API, such as webhooks and quizzes, because the command list is built from the API.

How the commands work

Most wp llms resource commands are generated from the LifterLMS REST API. When you run wp llms course list, the CLI makes an internal request to the same courses endpoint the API uses, with the same fields, validation and permission checks. Everything in our REST API introduction applies: the same field names, the same filters, the same results.

Two consequences matter:

  • The acting user. If you do not pass --user, the CLI picks an administrator account to run as. Pass --user= explicitly in scripts so changes are attributable and permission checks reflect a real role.
  • Arguments are API parameters. Options like --per_page, --search, --status and --orderby are the API's collection parameters, with underscores as the API spells them.

Read commands accept --format=table|json|csv|yaml|ids|count and --fields= to limit columns. Create, update and delete accept --porcelain, which prints only the ID so you can chain commands.

Everyday recipes

Find courses and read their structure

# Published courses: ID, title and URL only
wp llms course list --status=publish --fields=id,title,permalink --per_page=50 --format=json

# Search by title
wp llms course list --search="onboarding" --format=json

# The sections and lessons of course 42
wp llms course content 42 --format=json

Count and export enrollments

# How many students are enrolled in course 42?
wp llms course enrollments 42 --format=count

# Enrollment rows as CSV, 100 per page
wp llms course enrollments 42 --per_page=100 --page=1 --format=csv > course-42.csv

Create a draft course and capture its ID

COURSE_ID=$(wp llms course create --title="Safety Basics 2027" \
  --content="Course description goes here." --status=draft --porcelain --user=admin)
echo "Created course $COURSE_ID"

Both --title and --content are required when creating a course. Build the sections and lessons in the course builder afterwards, or create them with wp llms section create and wp llms lesson create, which take the parent ID.

Delete with care

wp llms course delete 42 moves the course to the trash. Adding --force=true bypasses the trash. Take a database backup with wp db export before any bulk delete.

generate, edit and diff

Three subcommands are less obvious than the rest:

  • generate creates test records, ten by default, with --count= to change that. wp llms course generate --count=5 --title="Test course" --content="Test" gives you five test courses for checking a catalog layout. Use it on staging only; it writes real posts.
  • edit opens a record in your terminal's text editor as YAML, then saves your changes back through the API. It is handy for a quick fix to one field on a server without an admin login.
  • diff is described in the reference as comparing records between environments, for example checking that staging and production have the same courses before a launch. Read its help with wp help llms course diff on your version before relying on it, as the CLI is still in beta.

Every subcommand has built-in help listing its exact options, generated from the API schema: wp help llms lesson create shows every field a lesson accepts.

Bulk-enrolling students

The CLI reference also lists students-enrollments and students-progress commands. Their routes need two IDs, the student and the course, so for scripts we prefer wp eval with LifterLMS's own enrollment function, which is simple to read and check. It runs the same code as any other enrollment, so engagements, notifications and webhooks fire as normal.

#!/usr/bin/env bash
# enroll.sh: enroll every email in emails.txt into course 42.
COURSE_ID=42
while read -r EMAIL; do
  USER_ID=$(wp user get "$EMAIL" --field=ID 2>/dev/null)
  if [ -z "$USER_ID" ]; then
    echo "No account: $EMAIL"
    continue
  fi
  wp eval "var_export( llms_enroll_student( $USER_ID, $COURSE_ID, 'llmsx_cli' ) );"
  echo " $EMAIL"
done < emails.txt

llms_enroll_student() returns true on success and false if the student was already enrolled or enrollment failed. To create accounts first, use wp llms student create --email=person@example.com --porcelain or WordPress's wp user create command.

Enrolling hundreds of people triggers hundreds of welcome emails if you have enrollment engagements. Decide whether that is what you want before running it. Run large batches during quiet hours.

Managing many sites: add-ons, licenses and reports

The add-on and license commands use the LifterLMS Helper, which is also bundled in core since 10.1.

# Activate a license key on this site
wp llms license activate YOUR-LICENSE-KEY

# Which add-ons are installed, and which have updates?
wp llms addon list --fields=name,status,version,update
wp llms addon list --update=available

# Install and activate an add-on
wp llms addon install lifterlms-groups --activate

# Preview, then run, updates for every installed add-on
wp llms addon update --all --dry-run
wp llms addon update --all

Add-on slugs work with or without the lifterlms- prefix, so advanced-videos and lifterlms-advanced-videos both work. With WP-CLI's aliases or a simple loop over SSH, this gives you a quick update report for every client site.

Reporting across many sites

Agencies get the most from the CLI by running the same read-only command on every site. WP-CLI aliases make this tidy. Define each site once in ~/.wp-cli/config.yml, then loop:

# ~/.wp-cli/config.yml
@client-a:
  ssh: deploy@client-a.example.com/var/www/html
@client-b:
  ssh: deploy@client-b.example.com/var/www/html

# Version and pending add-on updates for each site
for SITE in @client-a @client-b; do
  echo "== $SITE"
  wp $SITE llms version
  wp $SITE llms addon list --update=available --fields=name,version,update_version
done

The same pattern works for monthly reports, such as enrollment counts for each client's main course. Keep these loops read-only; for changes, connect to one site at a time so a mistake cannot spread.

Background jobs and scheduled tasks

LifterLMS runs recurring payments, access expirations, webhook deliveries and other jobs through Action Scheduler, which it bundles. Action Scheduler has its own WP-CLI command. On busy sites we disable WP-Cron's page-load trigger and run the queue from a real system cron:

# Every minute from the server's crontab
wp cron event run --due-now
wp action-scheduler run --batch-size=25

You can limit a run to one hook with --hooks=, for example llms_access_plan_expiration, which is useful when debugging. Be very careful with llms_charge_recurring_payment: running it charges real cards. On a cloned site, read our guide to staging sites and recurring payments first.

Safety habits

  • Staging first. Run any write command on staging, check the result in the admin, then run it on production.
  • Back up before bulk changes. wp db export before-change.sql takes seconds.
  • Use --user. Changes then carry a real user ID and the permission checks match that role.
  • Prefer IDs to titles. Titles repeat. Look up IDs with list, then act on IDs.
  • Log what you ran. Keep scripts in version control, not in shell history.
  • Watch for emails and webhooks. CLI changes trigger the same automations as clicks.

Frequently asked questions

Do I need to install the LifterLMS CLI separately?

Not on LifterLMS 10.1 or later. It is bundled in core. You do need WP-CLI on the server.

Can I run wp llms commands without SSH?

No. WP-CLI runs on the server. Without shell access, use the REST API, or the WordPress Abilities API covered in our guide to LifterLMS and AI agents.

Can AI coding agents use these commands?

Yes. LifterLMS publishes guidance for agents and recommends --format=json, --fields and --porcelain for parseable output. Give agents staging access first and review what they run.

Is there a command to export a course?

Not among the wp llms commands. Use the export tools in the LifterLMS admin, described in import, export and cloning courses.

What to do next

On a staging site, run wp help llms, then try the read-only recipes: list courses, read one course's content and count its enrollments. Once you trust the output, script the task you currently do by hand.

If you manage several LifterLMS sites and want scripted updates, bulk enrollment or a reliable cron setup, our LifterLMS support service handles it, and our development team can build custom commands for your workflows. Get in touch.

Add LifterLMS Expert to your preferred sources

Add lifterlmsexpert as a preferred source on Google, or open this article in your AI assistant to use it as a source.

  • Add as a preferred source on Google
Free consultation

Prefer expert help over DIY?

Skip the trial and error. Get specialist LifterLMS help and ship faster.

Talk to a LifterLMS Expert Explore our services

Replies within one business day