Type something to search...
How to Use WP-CLI to Manage a WordPress Website?

How to Use WP-CLI to Manage a WordPress Website?

WP-CLI lets you manage plugins, users, content, and the database from the command line, turning tasks that take a dozen clicks through wp-admin into a single command, and tasks that are outright impractical through the UI, like bulk-updating ten thousand posts, into a one-line script. It's the official command-line tool for WordPress, maintained under the WordPress organization itself, and it's installed on virtually every serious host and used throughout CI/CD pipelines and Docker-based local development.

Anything WP-CLI does, it does by bootstrapping WordPress itself and calling the same core functions your PHP code would, wp post create genuinely calls wp_insert_post() under the hood, so its behavior matches what happens through wp-admin exactly, just without a browser or a page load in the way.

This guide covers installation, core commands for plugins/themes/users/database work, searching and replacing content safely, custom commands for automating your own site-specific tasks, and running WP-CLI against a remote server over SSH.

Step 1: Install WP-CLI

On most Linux/macOS environments, the standard install downloads the executable Phar file directly:

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
wp --info

wp --info confirms the install worked and reports the PHP version, WP-CLI version, and paths it's using. Many hosts (Kinsta, WP Engine, Pantheon, SiteGround) ship WP-CLI pre-installed and reachable over SSH already, worth checking before installing your own copy.

Every WP-CLI command needs to run from inside a WordPress installation's directory (or point at one with --path=), since it needs to find wp-config.php to bootstrap WordPress.

Step 2: Core Site Commands

# Check the current WordPress core version
wp core version

# Update WordPress core to the latest version
wp core update

# Update the database schema after a core update
wp core update-db

# Check overall site health from the command line
wp core check-update

Step 3: Managing Plugins and Themes

# List all installed plugins with their status and version
wp plugin list

# Install and activate a plugin in one command
wp plugin install advanced-custom-fields --activate

# Update every installed plugin at once
wp plugin update --all

# Deactivate and delete a plugin entirely
wp plugin deactivate akismet
wp plugin delete akismet

# Same set of subcommands works for themes
wp theme list
wp theme update --all
wp theme activate twentytwentyfour

wp plugin update --all is one of the most common WP-CLI commands in real maintenance workflows, since it applies every available plugin update non-interactively, exactly what a scheduled maintenance script or CI job needs, without clicking through the Plugins screen's "Update" links one at a time.

Step 4: Managing Users

# Create a new administrator account
wp user create jane jane@example.com --role=administrator --user_pass=""

# List all users with a specific role
wp user list --role=editor

# Reset a user's password
wp user update jane --user_pass=newSecurePass123

# Remove a user, reassigning their posts to another user
wp user delete jane --reassign=1

Leaving --user_pass empty in the create example generates a random password and emails it to the new user automatically, which is often preferable to hardcoding a password in a script or shell history.

Step 5: Database Operations

# Export the full database to a timestamped SQL file
wp db export backup-$(date +%F).sql

# Import a SQL file into the current site's database
wp db import backup-2026-08-11.sql

# Open an interactive MySQL shell using the site's configured credentials
wp db cli

# Run a raw query directly
wp db query "SELECT COUNT(*) FROM wp_posts WHERE post_status = 'publish';"

# Check and optimize database tables
wp db optimize

wp db export/wp db import read connection details straight from wp-config.php, which is why they're the standard tool for migrating a database between environments, no separate credentials to type in or hardcode anywhere.

Step 6: Search and Replace Safely

Moving a WordPress site between domains (staging to production, or an old URL to a new one) requires updating every serialized reference to the old URL throughout the database, not just a simple find-and-replace, since a naive SQL UPDATE on a LIKE match will corrupt PHP-serialized data whose stored string-length prefixes no longer match after the replacement.

# Preview what would change, without touching the database
wp search-replace 'https://staging.example.com' 'https://example.com' --dry-run

# Actually perform the replacement, serialization-safe
wp search-replace 'https://staging.example.com' 'https://example.com'

# Limit the replacement to specific tables
wp search-replace 'https://staging.example.com' 'https://example.com' wp_posts wp_postmeta

wp search-replace is serialization-aware: it correctly unserializes PHP arrays and objects stored as strings, updates the length prefixes for any replaced substrings, and re-serializes the result, exactly the operation that plain SQL can't do safely. Always run with --dry-run first on anything touching production data, since it reports exactly how many replacements it would make per table without committing them.

Step 7: Content Management at Scale

# Bulk-create test posts, useful for local theme development
wp post generate --count=50 --post_type=post

# Find and delete every post in the trash
wp post delete $(wp post list --post_status=trash --format=ids)

# Update the post status of every draft older than 90 days
wp post list --post_status=draft --format=ids | xargs -I {} wp post update {} --post_status=trash

# Regenerate all image thumbnail sizes, useful after adding a new image size
wp media regenerate --yes

Piping wp post list --format=ids (which prints one post ID per line, without any table formatting) into xargs is the standard WP-CLI pattern for bulk operations that don't have a single dedicated bulk command of their own.

Step 8: Managing Custom Post Types and Taxonomies from the CLI

Everything covered in the custom post types and custom taxonomies guides works through WP-CLI once those types are registered by your theme or plugin code:

# Create a new Product post
wp post create --post_type=product --post_title="Wireless Mouse" --post_status=publish

# Assign a term from a custom taxonomy to a post
wp post term add 123 product_category laptops

# List all terms in a custom taxonomy
wp term list product_category --fields=term_id,name,slug,count

Step 9: Write a Custom WP-CLI Command

For anything specific to your own site (a one-off data migration, a repeated import job), registering a custom command keeps that logic reachable the same way as any built-in command, rather than as a one-off script you have to remember how to invoke:

<?php
// mu-plugins/tidewave-cli.php

if ( ! defined( 'WP_CLI' ) || ! WP_CLI ) {
    return;
}

class Tidewave_CLI_Commands {

    /**
     * Recalculates the price total across all products.
     *
     * ## OPTIONS
     *
     * [--dry-run]
     * : Preview the change without saving anything.
     *
     * ## EXAMPLES
     *
     *     wp tidewave recalculate-prices
     *     wp tidewave recalculate-prices --dry-run
     */
    public function recalculate_prices( $args, $assoc_args ) {
        $dry_run = WP_CLI\Utils\get_flag_value( $assoc_args, 'dry-run', false );

        $products = get_posts( [
            'post_type'      => 'product',
            'posts_per_page' => -1,
        ] );

        foreach ( $products as $product ) {
            $price = (float) get_field( 'price', $product->ID );
            $new_price = round( $price * 1.1, 2 ); // example: apply a 10% adjustment

            if ( $dry_run ) {
                WP_CLI::log( "Would update #{$product->ID}: {$price} -> {$new_price}" );
                continue;
            }

            update_field( 'price', $new_price, $product->ID );
            WP_CLI::log( "Updated #{$product->ID}: {$price} -> {$new_price}" );
        }

        WP_CLI::success( count( $products ) . ' products processed.' );
    }
}

WP_CLI::add_command( 'tidewave', 'Tidewave_CLI_Commands' );

Once registered as a must-use plugin, wp tidewave recalculate-prices --dry-run runs the logic and prints a preview for every product before anyone commits to changing real data. The PHPDoc comment block above the method is not decorative, WP-CLI parses it directly to generate wp help tidewave recalculate-prices output and validate the --dry-run flag.

Step 10: Running WP-CLI Against a Remote Server

For a remote host with SSH access, WP-CLI can run commands there directly from your local machine using an ssh: alias, without needing to open a separate SSH session first:

# In wp-cli.yml at the project root
@production:
  ssh: user@example.com/var/www/html
  path: /var/www/html

@staging:
  ssh: user@staging.example.com/var/www/html
  path: /var/www/html
wp @production plugin list
wp @production db export backup.sql
wp @staging search-replace 'old-domain.com' 'staging.example.com'

This alias pattern is what makes WP-CLI genuinely useful in deployment scripts and CI/CD pipelines, since the same command works identically whether it targets local, staging, or production, just by swapping the alias.

Step 11: Useful Flags Worth Knowing

A handful of global flags apply across almost every WP-CLI command and are worth having memorized:

# Skip all plugins and themes from loading, useful for debugging or running maintenance
# commands on a site with a fatal error in a plugin
wp plugin list --skip-plugins --skip-themes

# Get machine-readable output for scripting, instead of a formatted table
wp post list --format=json
wp user list --format=csv

# Target a specific site in a multisite network
wp post list --url=site2.example.com

# See exactly what a command would do, for any command that supports it
wp plugin update --all --dry-run

--skip-plugins/--skip-themes are particularly valuable during an incident: if a bad plugin update has taken the site down with a fatal error, wp plugin deactivate broken-plugin --skip-plugins can still run because it bypasses loading any plugin code (including the broken one) before executing, something you can't do at all through wp-admin once a fatal error prevents that from loading either.

Step 12: Combine WP-CLI with Cron for Scheduled Maintenance

A real crontab entry running a nightly database backup and plugin update check, piping output to a log file for later review:

0 2 * * * cd /var/www/html && wp db export /var/backups/wp-$(date +\%F).sql --allow-root >> /var/log/wp-backup.log 2>&1
30 2 * * 0 cd /var/www/html && wp plugin update --all --allow-root >> /var/log/wp-updates.log 2>&1

--allow-root is required when a cron job runs as the root user, since WP-CLI refuses to execute as root by default as a safety measure against accidentally running arbitrary PHP with elevated system privileges; running the cron job under a dedicated, non-root deploy user instead avoids needing the flag at all, which is generally the safer setup.

Frequently Asked Questions (FAQ) About WP-CLI

Yes, it's an officially maintained WordPress project and uses the same core functions as the admin UI, so a command like wp plugin update behaves identically to clicking Update in wp-admin. The real risk with production use is the same as any admin action: always back up the database with wp db export before bulk operations, and use --dry-run wherever a command supports it.

No, one WP-CLI binary installed on a server (or your local machine) works against any WordPress installation on that same machine, or a remote one over SSH aliases, as long as it can locate that site's wp-config.php via its working directory or a --path flag.

wp search-replace correctly handles PHP-serialized data (arrays and objects stored as strings with length-prefixed segments, common in widget settings and some plugin options), recalculating length prefixes after a replacement. A raw SQL UPDATE ... REPLACE() on the same data corrupts any serialized value whose replaced substring changes length, often breaking widgets or plugin settings silently.

Yes, most commands accept a --url flag to target a specific site within a network, and dedicated commands like wp site list and wp site create manage the network's sites themselves. See our guide on setting up a WordPress multisite network for the underlying concepts these commands operate on.

Run wp help for a full list of top-level commands, or wp help (for example wp help post) to see every subcommand and flag available for that command, generated directly from each command's own registered documentation, the same mechanism used for custom commands as shown in Step 9.

Yes, WP-CLI commands are ordinary shell commands, so a standard cron job or a scheduled step in a CI/CD pipeline can run them exactly as shown in these examples, for example a nightly wp db export piped to an offsite backup location.

Conclusion

WP-CLI turns WordPress from a purely point-and-click admin experience into something scriptable, repeatable, and automatable, which matters the moment a task needs to run against more than one site, more than one time, or as part of a larger pipeline. Start with the core plugin, theme, and database commands covered here, since they cover the overwhelming majority of day-to-day maintenance work, and reach for custom commands only once you have a task specific enough to your own site that no built-in command covers it.

Once comfortable with the basics, WP-CLI becomes the natural backbone for Docker-based local development and CI/CD deployment pipelines, since both rely on exactly the kind of non-interactive, scriptable commands it provides.

Here are a few additional resources if you want to go deeper:

Tags :
Share :

Related Posts

Effortlessly Crafting Compelling WordPress Pages

Effortlessly Crafting Compelling WordPress Pages

As a website owner or content creator, having the ability to seamlessly add new pages to your WordPress site is crucial. Whether you're introducing a

Continue Reading
High Traffic Tips for WordPress Mastery 🚥

High Traffic Tips for WordPress Mastery 🚥

In our digital age, where online visibility is paramount, ensuring your WordPress site can handle surging traffic is crucial. Just like a finely-tune

Continue Reading
How Do I Change the WordPress Login URL?

How Do I Change the WordPress Login URL?

By default, every WordPress site's login page lives at the same predictable address: yoursite.com/wp-login.php (which also happens to redirect from

Continue Reading