WP-CLI Skill
Manage WordPress installations using WP-CLI: core, plugins, themes, users, database, options, cron, and more.
Prerequisites
wpinstalled and on PATH; run from the WordPress root or pass--path=<path>wp doctorneeds the separatewp-cli/doctor-commandpackage:wp package install wp-cli/doctor-command:@stableComposer resolves@stableagainst the installed WP-CLI. If it reports a version conflict, checkwp --versionand pin an exact release that supports it insteadwp maintenance-modeis bundled with WP-CLI (no extra package needed)
Core
wp --version
wp core version
wp core is-installed
wp core check-update
wp core update && wp core update-db # add --network to update-db on multisite
wp core verify-checksums
# Install fresh. --prompt keeps secrets out of shell history, but it reads from stdin
# and blocks forever without a terminal
wp core download
wp config create --dbname=wordpress --dbuser=root --dbhost=localhost --prompt=dbpass
wp core install --url=example.com --title="Site" --admin_user=admin --admin_email=admin@example.com --prompt=admin_password
# Non-interactive equivalent (scripts, agents, CI): read the secret from the
# environment so the value itself never reaches the command line or history
wp config create --dbname=wordpress --dbuser=root --dbhost=localhost --dbpass="$WP_DB_PASS"
wp core install --url=example.com --title="Site" --admin_user=admin --admin_email=admin@example.com --admin_password="$WP_ADMIN_PASS"
Plugins & Themes
wp plugin list [--status=active] [--update=available]
wp plugin install <slug> --activate
wp plugin activate <name>
wp plugin deactivate <name>
wp plugin update --all
wp plugin verify-checksums --all
wp theme list
wp theme install <slug> --activate
wp theme update --all
Users
wp user list [--role=administrator]
wp user create <username> <email> --role=<role> --prompt=user_pass
wp user update <id> --role=editor --display_name="Name"
wp user update <id> --prompt=user_pass
wp user delete <id> --reassign=<other-id>
Database
wp db export backup.sql
wp db import backup.sql
wp option get siteurl # prefix-agnostic; prefer over raw SQL
wp db query "SELECT option_value FROM $(wp config get table_prefix)options WHERE option_name='siteurl';"
wp db optimize
wp db repair
# Always --dry-run first, with the exact flags the real run will use
wp search-replace 'old' 'new' --precise --recurse-objects --all-tables-with-prefix --dry-run
wp search-replace 'old' 'new' --precise --recurse-objects --all-tables-with-prefix
Options, Cache, Rewrites
wp option get <name>
wp option update <name> <value>
wp option delete <name>
wp option list --search="*cache*"
wp cache flush
wp transient delete --all # database transients only; with an external object
# cache you need `wp cache flush` too, and --network
# for network transients on multisite
wp rewrite flush
wp rewrite structure '/%postname%/'
Cron
wp cron event list
wp cron event run --due-now
wp cron event run <hook-name>
wp cron test
Posts & Media
wp post list --post_type=post --post_status=publish
wp post create --post_title='Title' --post_content='Body' --post_status=publish
wp post delete <id> --force
wp post generate --count=10
wp media regenerate # add --yes only after confirming; it rewrites every thumbnail
wp media import <url-or-path>
Maintenance & Troubleshooting
wp maintenance-mode activate
wp maintenance-mode deactivate
wp maintenance-mode status
wp doctor check --all # requires wp-cli/doctor-command package
wp shell
wp eval 'echo PHP_VERSION;'
wp config get <name>
wp config list
Multisite
wp site list
wp site create --slug=<slug> --title="Title"
wp site list --field=url | xargs -I {} wp option get blogname --url={}
# Network-wide operations need --network; without it they only touch the main site
wp core update-db --network
wp transient delete --all --network
wp plugin list --status=active,active-network
Rules
- Always
--dry-runsearch-replacefirst, andwp db exportbefore destructive changes - The dry run must carry the same flags as the real run — a preview with a different table scope does not describe what the real run will modify
- Prefer
--all-tables-with-prefixover--all-tables: the latter rewrites every table in the database, including tables owned by other apps sharing it. Use it only deliberately - Keep passwords and secrets off the command line:
--prompt=<arg>when a terminal is attached, or an environment variable (--dbpass="$WP_DB_PASS") when running non-interactively ---promptblocks on stdin and will hang a script or agent - Confirm destructive actions (
--yes,delete --force,plugin deactivate --all) with the user first --format=jsonfor machine output,--fields=<cols>to trim columns
Common Workflows
# Domain migration
wp db export pre-migration.sql
wp search-replace 'https://old.com' 'https://new.com' --precise --recurse-objects --all-tables-with-prefix --dry-run
wp search-replace 'https://old.com' 'https://new.com' --precise --recurse-objects --all-tables-with-prefix
# search-replace only rewrites the database. WP_HOME/WP_SITEURL in wp-config.php override
# the rewritten options, so the old domain keeps serving - check `wp config list` first
wp config set WP_HOME 'https://new.com'
wp config set WP_SITEURL 'https://new.com'
wp cache flush && wp rewrite flush
# Update everything
wp core update && wp core update-db # --network on multisite, or subsites keep the old schema
wp plugin update --all
wp theme update --all
wp cache flush
# Bisect a broken site
wp core verify-checksums
wp plugin list --status=active --field=name > active-plugins.txt # capture first, so state is restorable
wp plugin deactivate --all
# Re-activate one by one from active-plugins.txt to find the culprit
wp plugin activate <name>
# Restore the original set: xargs wp plugin activate < active-plugins.txt