Written by 5:41 pm For Developers, How-To Guides, Site Maintenance Basics Views: 0

The Ultimate WP-CLI Guide: Automate Boring WordPress Tasks Fast

WP-CLI terminal commands for automating WordPress site management

If you manage one or more WordPress sites, you already know the drill: update plugins, export the database, swap URLs after a migration, clean up expired transients, and repeat. All of it is clickable inside the dashboard, but clicking is slow, error-prone, and impossible to script. WP-CLI turns every one of those chores into a single terminal command you can run, schedule, or chain into a shell script. This guide gives you real, copy-paste wp command recipes for the tasks that eat most of your time.

What WP-CLI Actually Is (and Why It Belongs in Your Toolkit)

WP-CLI is the official command-line interface for WordPress. You install it once on a server or local machine and it connects to any WordPress install in the current directory, letting you manage posts, users, plugins, themes, options, and the database without ever touching a browser. Think of it as a remote control that speaks WordPress natively.

The project is open source, actively maintained on GitHub, and ships as a single Phar file you download with curl. Hosts like Kinsta, WP Engine, and Cloudways pre-install it. If yours does not, adding it takes under two minutes.

Installing WP-CLI and Setting Up Aliases

Download the Phar file, make it executable, and move it somewhere on your $PATH:

curl -O https://raw.githubusercontent.com/wp-cli/builds/gh-pages/phar/wp-cli.phar
chmod +x wp-cli.phar
sudo mv wp-cli.phar /usr/local/bin/wp

Verify it works:

wp --info

You should see PHP version, WP-CLI version, and paths. If you get a permission error on shared hosting, download the Phar to your home directory and call it with php ~/wp-cli.phar instead.

Shell Aliases That Save Typing

When you manage multiple sites, switching between them manually is friction. Two alias patterns fix this. Add them to ~/.bashrc or ~/.zshrc:

# Site-specific alias
alias wpdev="wp --path=/var/www/mysite/public"

# Path argument for any site
wp_site() { wp --path="$1" "${@:2}"; }

Now wpdev plugin list always targets that one site without a cd. On local tools like LocalWP, wp --path=$(pwd) from inside the site directory works automatically because WP-CLI walks up the directory tree looking for wp-config.php.

Bulk Plugin and Core Updates with Backups

Updating through the dashboard means clicking “Update” for every item, watching progress bars, and hoping nothing breaks. With WP-CLI you can back up the database, update everything, and bail out automatically if something goes wrong, all in one script.

One-Line Core and Plugin Update

# Update WordPress core
wp core update

# Update all plugins
wp plugin update --all

# Update all themes
wp theme update --all

Update Script with Pre-flight Backup

The safer pattern backs up first, then updates:

#!/bin/bash
set -e

SITE_PATH="/var/www/mysite/public"
BACKUP_DIR="/home/user/backups"
DATE=$(date +%Y-%m-%d-%H%M)

# Export database before touching anything
wp --path="$SITE_PATH" db export "$BACKUP_DIR/pre-update-$DATE.sql"

# Run updates
wp --path="$SITE_PATH" core update
wp --path="$SITE_PATH" plugin update --all
wp --path="$SITE_PATH" theme update --all

echo "Done. Backup at $BACKUP_DIR/pre-update-$DATE.sql"

The set -e flag makes the script exit immediately if any command fails, so a botched plugin update does not cascade into a broken site with no backup.

Update Only Specific Plugins

wp plugin update woocommerce contact-form-7

Skip a Plugin That Always Breaks on Update

wp plugin update --all --exclude=problematic-plugin

Search and Replace for Migrations Using –dry-run

Moving a site from http://staging.example.com to https://example.com involves URL references scattered across post content, option values, widget data, and serialized arrays. Manual SQL updates routinely corrupt serialized data. WP-CLI handles the serialization automatically. If you are doing a full domain migration, see the complete step-by-step guide on how to move a WordPress site to a new domain without losing Google rankings.

Always Preview First

wp search-replace 'http://staging.example.com' 'https://example.com' --dry-run

The --dry-run flag shows you exactly how many replacements would happen in each table without touching the database. Check the output before removing it.

Run the Real Replace

wp search-replace 'http://staging.example.com' 'https://example.com'

Target Specific Tables

On large databases, replacing every table takes time. Narrow to the tables that actually hold URLs:

wp search-replace 'http://staging.example.com' 'https://example.com' \
  wp_options wp_posts wp_postmeta

Flush Caches After Replace

wp cache flush
wp rewrite flush

Object cache still holds old URLs from before the replace. Flush it immediately or visitors will see stale redirects.

User and Role Bulk Operations

Adding or modifying dozens of users by hand in the dashboard is the kind of task WP-CLI was born to eliminate.

Create a User

wp user create jsmith [email protected] --role=editor --user_pass=SecurePass123

Bulk-Create Users from a CSV

Create a file users.csv:

user_login,user_email,role
alice,[email protected],editor
bob,[email protected],author
carol,[email protected],subscriber

Then import with a shell loop:

tail -n +2 users.csv | while IFS=',' read login email role; do
  wp user create "$login" "$email" --role="$role"
done

Change the Role of Every Current Author

wp user list --role=author --field=ID | xargs -I {} wp user set-role {} editor

Reset a Password

wp user update jsmith --user_pass=NewSecurePass456

Delete Users and Reassign Their Content

wp user delete 42 --reassign=1

Passing --reassign=1 moves that user’s posts to the admin account (ID 1) instead of deleting them.

Database Export, Import, and Optimization

WP-CLI wraps mysqldump and mysql into commands that work with WordPress configuration automatically, no digging through wp-config.php for credentials.

Export the Database

wp db export backup.sql

Export and Compress in One Step

wp db export - | gzip > backup-$(date +%Y%m%d).sql.gz

Import a Backup

wp db import backup.sql

Optimize All Tables

WordPress databases accumulate overhead from deleted posts, revisions, and spam comments. Optimizing reclaims space:

wp db optimize

Repair Corrupted Tables

wp db repair

Check Table Sizes

wp db query "SELECT table_name, ROUND(data_length/1024/1024, 2) AS size_mb \
  FROM information_schema.tables WHERE table_schema = DATABASE() \
  ORDER BY size_mb DESC;"

WP-Cron Management

WordPress cron runs on page load, which means it only fires when someone visits the site. On low-traffic sites, scheduled tasks like backups or email queues can run hours late. WP-CLI gives you real control over the cron schedule.

List All Scheduled Events

wp cron event list

Run a Specific Event Immediately

wp cron event run wp_scheduled_delete

Run All Due Events

wp cron event run --due-now

Fix Unreliable Cron with a Real Cron Job

Disable WP-Cron in wp-config.php first:

define('DISABLE_WP_CRON', true);

Then add a system cron job (on Linux via crontab -e):

*/5 * * * * php /var/www/mysite/public/wp-cron.php

Or use WP-CLI directly from cron for cleaner output:

*/5 * * * * /usr/local/bin/wp --path=/var/www/mysite/public cron event run --due-now

Delete a Stuck Cron Event

wp cron event delete event_hook_name

Transient Cleanup

Transients are temporary key-value pairs stored in the database. Plugins use them for caching API responses, license checks, and other short-lived data. Over time they pile up and slow down every database query that touches wp_options. For a deep-dive into the full range of database bloat problems, the guide on stopping WordPress database bloat with wp_options cleanup covers autoloaded data, orphaned rows, and query optimization strategies.

Delete All Expired Transients

wp transient delete --expired

Delete Every Transient (Force-Clean)

wp transient delete --all

Use this after a plugin conflict or when troubleshooting caching issues. Most transients will be rebuilt on the next page load.

Check How Many Transients Exist

wp db query "SELECT COUNT(*) FROM wp_options WHERE option_name LIKE '_transient_%';"

If you see thousands of rows, a plugin is leaking transients. Common offenders include WooCommerce extensions that generate unique cache keys per product or session.

Schedule Weekly Transient Cleanup via Cron

0 3 * * 0 /usr/local/bin/wp --path=/var/www/mysite/public transient delete --expired

Running this at 3 AM on Sundays keeps the options table lean without any manual work.

Scaffolding Custom Commands

Once you find yourself running the same multi-step WP-CLI sequence, it is time to scaffold a custom command and reduce it to one call.

Generate a Plugin Scaffold

wp scaffold plugin my-cli-tools --plugin_name="My CLI Tools" --activate

This creates a plugin directory with the correct file structure, class skeleton, and readme.

Add a Custom WP-CLI Command to That Plugin

Open my-cli-tools.php and add:

if ( defined( 'WP_CLI' ) && WP_CLI ) {
    class My_CLI_Command {

        /**
         * Cleans transients and optimizes the database.
         *
         * ## EXAMPLES
         *   wp mytools cleanup
         *
         * @when after_wp_load
         */
        public function cleanup( $args, $assoc_args ) {
            WP_CLI::line( 'Deleting expired transients...' );
            WP_CLI::runcommand( 'transient delete --expired' );

            WP_CLI::line( 'Optimizing database tables...' );
            WP_CLI::runcommand( 'db optimize' );

            WP_CLI::success( 'Cleanup complete.' );
        }
    }

    WP_CLI::add_command( 'mytools', 'My_CLI_Command' );
}

Now running wp mytools cleanup runs both steps. Add as many methods as you need: each public method on the class becomes a subcommand.

Scaffold a Theme or CPT

# Scaffold a child theme
wp scaffold child-theme my-child --parent_theme=twentytwentyfive

# Scaffold a custom post type
wp scaffold post-type project --label="Project" --textdomain=my-plugin

Putting It All Together: A Weekly Maintenance Script

Here is a production-ready script that combines several recipes above into a weekly run. Save it to /usr/local/bin/wp-weekly-maintenance and make it executable with chmod +x.

#!/bin/bash
set -e

WP="wp --path=/var/www/mysite/public"
BACKUP_DIR="/home/user/backups"
DATE=$(date +%Y-%m-%d)
LOG="/var/log/wp-maintenance.log"

echo "=== WP Maintenance $DATE ===" >> "$LOG"

# 1. Export database backup
$WP db export "$BACKUP_DIR/weekly-$DATE.sql" && echo "DB backup saved" >> "$LOG"

# 2. Update core, plugins, themes
$WP core update >> "$LOG" 2>&1
$WP plugin update --all >> "$LOG" 2>&1
$WP theme update --all >> "$LOG" 2>&1

# 3. Clean transients
$WP transient delete --expired >> "$LOG" 2>&1

# 4. Optimize database
$WP db optimize >> "$LOG" 2>&1

# 5. Flush caches
$WP cache flush >> "$LOG" 2>&1
$WP rewrite flush >> "$LOG" 2>&1

echo "=== Done ===" >> "$LOG"

Add it to cron to run every Sunday at 2 AM:

0 2 * * 0 /usr/local/bin/wp-weekly-maintenance

Working with the WordPress Configuration File

WP-CLI can read and write constants and variables in wp-config.php without you having to open the file manually. This is especially handy when you need to toggle debug mode before a troubleshooting session and turn it off again afterward.

Enable Debug Mode

wp config set WP_DEBUG true --raw
wp config set WP_DEBUG_LOG true --raw
wp config set WP_DEBUG_DISPLAY false --raw

The --raw flag writes the value as a PHP expression rather than a string, so true becomes the boolean true in the file instead of the string 'true'.

Check the Current Value of Any Constant

wp config get WP_DEBUG
wp config get table_prefix

List Every Constant and Variable

wp config list

This prints every defined constant and variable from wp-config.php in a table, useful for auditing a site you did not set up yourself.

Add a New Constant

wp config set WP_MEMORY_LIMIT 256M

If the constant already exists it is updated. If not, it is inserted before the line that reads /* That's all, stop editing! */.

User Meta and Capabilities

Some tasks require reading or modifying user meta directly, without going through the Users screen. WP-CLI handles this cleanly.

Get a User’s Meta Value

wp user meta get 42 wp_capabilities

Grant an Extra Capability

wp user add-cap 42 manage_options

Remove a Capability

wp user remove-cap 42 manage_options

Find All Admins on the Site

wp user list --role=administrator --fields=ID,user_login,user_email

Running this on a hacked or inherited site is a quick way to spot rogue admin accounts added without your knowledge. Any account you do not recognize is worth investigating before you do anything else.

Automating WP-CLI with Shell Scripts and Aliases

Once you have a collection of useful commands, the next step is organizing them so you are not retyping them every time. There are three main approaches: shell aliases, shell functions, and full Bash scripts.

Shell Alias for a Common Sequence

alias wpmaint='wp transient delete --expired && wp db optimize && wp cache flush'

Now typing wpmaint in any site directory runs all three steps in sequence.

Shell Function for Multi-Site Work

wpu() {
  local SITE="$1"
  shift
  wp --path="/var/www/$SITE/public" "$@"
}

Call it as wpu mysite plugin update --all. The function passes everything after the site name directly to WP-CLI, so you can use any command with it.

Generate a Post-Deployment Script for CI/CD

If you deploy via Git hooks or a CI pipeline, WP-CLI belongs in your post-deploy step:

#!/bin/bash
set -e
WP="wp --path=/var/www/mysite/public"

$WP core update-db          # run any pending database upgrades
$WP cache flush             # clear stale cached data
$WP rewrite flush           # regenerate permalink rules
$WP transient delete --expired  # clean leftover transients
echo "Post-deploy tasks complete"

Running this every time you push a new version ensures the database schema and caches are always consistent with the deployed code.

Useful WP-CLI Flags to Know

Before you go, a few flags that change the behavior of almost any command:

  • --quiet: suppresses success messages, cleaner for cron logs
  • --debug: shows every internal operation, useful for troubleshooting
  • --skip-plugins: loads WordPress without any plugins, good for conflict isolation
  • --skip-themes: same but for the active theme
  • --allow-root: required on some Docker containers where the shell runs as root
  • --format=json: returns output as JSON for piping into other scripts

Combining --skip-plugins --skip-themes is the fastest way to run a database command when a broken plugin is preventing normal WordPress load.

Managing WordPress Options from the Command Line

WordPress stores site-wide settings in the wp_options table. WP-CLI gives you direct read and write access, which is helpful when you need to change a URL, toggle a feature flag, or clear a stuck option without loading the admin panel.

Read an Option

wp option get siteurl
wp option get blogdescription

Update an Option

wp option update siteurl 'https://example.com'
wp option update blogname 'My New Site Name'

Delete a Stuck Plugin Option

Some plugins leave behind orphaned option rows even after deletion. Clean them like this:

wp option delete my_plugin_settings

List All Options Matching a Pattern

wp option list --search='my_plugin_*' --fields=option_name,option_value

This is useful for auditing what a specific plugin has stored and for confirming cleanup after a plugin is removed.

Post and Comment Management in Bulk

WP-CLI lets you create, update, delete, and query posts and comments at scale without writing custom PHP scripts or installing extra admin plugins.

List Posts with Filters

wp post list --post_type=page --post_status=publish --fields=ID,post_title,post_date

Delete Old Post Revisions

WordPress saves a revision every time you update a post. On busy sites this adds thousands of rows to the database. Delete them all:

wp post delete $(wp post list --post_type=revision --format=ids) --force

The subshell $(wp post list ...) returns a space-separated list of IDs that wp post delete receives as arguments. Add --force to skip the trash and permanently delete.

Delete Spam Comments

wp comment delete $(wp comment list --status=spam --format=ids) --force

Approve Pending Comments in Bulk

wp comment approve $(wp comment list --status=hold --format=ids)

Update a Custom Field Across All Posts

wp post list --post_type=post --format=ids | xargs -I {} \
  wp post meta update {} _my_custom_field "new_value"

Checking Site Health Without the Dashboard

The WordPress Site Health screen is useful, but accessing it requires a working admin login. WP-CLI gives you the same diagnostics from the terminal, which matters when the admin panel is inaccessible due to a plugin conflict or memory limit.

Run Site Health Checks

wp site-health check

This outputs a list of tests and their pass or fail status. You can pipe it into grep fail to see only the problems.

Check WordPress Version

wp core version
wp core verify-checksums

verify-checksums compares every core file against the official WordPress checksums and reports any file that has been modified. This is a fast security check that takes seconds instead of the minutes a manual file comparison would require.

List All Active Plugins

wp plugin list --status=active --fields=name,version,update

Adding --format=csv exports it in a spreadsheet-friendly format you can send to a client as a site inventory.

Multisite Operations

If you run a WordPress Multisite network, WP-CLI has a full set of network commands. You target individual sites within the network using the --url flag.

List All Sites in the Network

wp site list --fields=blog_id,url,registered,last_updated

Run a Command on Every Site in the Network

wp site list --field=url | xargs -I % wp --url=% plugin update --all

This pipes every site URL into a plugin update command. Use the same pattern for transient cleanup, cache flushes, or any other operation you want to broadcast across the entire network.

Activate a Plugin Network-Wide

wp plugin activate my-plugin --network

Create a New Site in the Network

wp site create --slug=new-subdomain --title="New Subdomain Site" [email protected]

Debugging with WP-CLI

When something breaks, WP-CLI is often the fastest tool for isolating the problem because it lets you run WordPress with various combinations of plugins and themes disabled.

Check PHP Fatal Errors Without Loading Plugins

wp --skip-plugins --skip-themes eval 'echo "WP core loads fine.";'

If this works but your normal wp call fails, the problem is in a plugin or theme. Re-add --skip-plugins and --skip-themes individually to narrow down which layer is at fault.

Test Email Sending

wp eval 'wp_mail("[email protected]", "WP-CLI Test", "Mail works.");'

If you get no email, check your SMTP configuration or the return value by catching the Boolean returned from wp_mail.

Flush Object Cache

wp cache flush

On sites using Redis or Memcached, this clears the in-memory cache immediately. On sites without a persistent cache, it has no effect but causes no harm.

Regenerate Thumbnails

wp media regenerate --yes

After switching themes or changing image size settings in functions.php, existing images need their thumbnails rebuilt. The --yes flag skips the confirmation prompt, making it scriptable.

Next Steps

WP-CLI covers nearly every WordPress operation you might do manually. The commands above are the ones that pay off fastest. Start with the update script, run it once on a staging site, and watch how much time it saves compared to clicking through the dashboard. From there, add the transient cleanup cron job, then wire up the maintenance script for your production site.

A practical starting order: get comfortable with wp plugin update --all and wp db export first, since those two commands alone protect you from the most common data loss scenarios. Once those feel natural, add the search-replace workflow to your migration checklist, then graduate to scheduling the full maintenance script via cron.

If you manage client sites, consider wrapping your most-used sequences into custom commands using the scaffold approach. A single wp clienttools deploy that handles post-deploy tasks, or wp clienttools checkup that runs site health and plugin audit checks, turns a 15-minute manual checklist into a 30-second automated one. Your clients get faster response times; you get back your afternoon.

For deeper reading, the official WP-CLI command reference lists every built-in command with all available flags. Bookmark the WP-CLI handbook for guides on writing custom commands, testing, and contributing new subcommands to the project. The GitHub repository is also where you can watch for releases, report bugs, and find community-maintained packages that extend WP-CLI with commands for popular plugins like WooCommerce, ACF, and Gravity Forms.

Visited 1 times, 1 visit(s) today

Last modified: May 8, 2026

Close