Managing updates for 10, 50, or 100 WordPress sites means logging into each dashboard, clicking through update screens, and praying nothing breaks. It wastes hours every week and delays critical security updates.
WP-CLI lets you update all plugins and themes across unlimited WordPress sites from your terminal—in minutes instead of hours. Add safety checks, automatic backups, and rollback capabilities, and you have enterprise-grade update automation.
In this guide, you’ll learn professional techniques for bulk updating WordPress installations safely, including pre-update backups, staged rollouts, and automated testing used by WordPress agencies managing hundreds of sites.
Why Bulk Update with WP-CLI?
WordPress updates are critical for security, but manual updates don’t scale.
Problems with Manual Updates
Time-consuming: Updating 50 sites manually takes 5-8 hours of repetitive clicking.
Security delays: Critical security patches sit uninstalled for days or weeks.
Inconsistent: Some sites get updated, others forgotten, creating security gaps.
No rollback: If an update breaks a site, you’re manually restoring backups.
Update fatigue: Developers avoid updates because the process is painful.
WP-CLI Bulk Update Advantages
Fast: Update 100 sites in under 30 minutes with automation scripts.
Consistent: Same update process across all sites prevents human error.
Safe: Automated backups before every update enable instant rollback.
Scheduled: Cron automation handles updates during maintenance windows.
Testable: Stage updates on test sites before production rollout.
According to WordPress security research, 60% of hacked WordPress sites were compromised due to outdated plugins. Efficient update workflows prevent breaches.
Single Site Update Operations
Master updating individual WordPress installations first.
Update All Plugins
# Update all plugins
wp plugin update --all
# Preview updates without installing
wp plugin update --all --dry-run
# Update excluding specific plugins
wp plugin update --all --exclude=woocommerce,elementor
# Update specific plugins only
wp plugin update wordfence yoast-seo contact-form-7Update All Themes
# Update all themes
wp theme update --all
# Update specific theme
wp theme update astra
# Dry run to preview
wp theme update --all --dry-runUpdate WordPress Core
# Update to latest version
wp core update
# Update to specific version
wp core update --version=6.4.2
# Update minor versions only (security updates)
wp core update --minorPro Tip: Always run --dry-run first to preview what will be updated before making changes.
Learn more in the official WP-CLI plugin update documentation.
Safe Update Workflow with Backups
Never update without backups and rollback capability.
Complete Backup Before Updates
#!/bin/bash
# safe-update.sh - Update with automatic backup
SITE_PATH="/var/www/html"
BACKUP_DIR="/backups"
DATE=$(date +%Y%m%d_%H%M%S)
cd "$SITE_PATH"
echo "Creating pre-update backup..."
# Backup database
wp db export "$BACKUP_DIR/db-before-update-$DATE.sql.gz"
# Backup files (plugins, themes, uploads)
tar -czf "$BACKUP_DIR/files-before-update-$DATE.tar.gz" \
wp-content/plugins \
wp-content/themes \
wp-content/uploads
echo "✓ Backup complete"
# Update plugins
echo "Updating plugins..."
wp plugin update --all
# Update themes
echo "Updating themes..."
wp theme update --all
# Verify WordPress still works
if wp core is-installed; then
echo "✓ Updates successful, WordPress functional"
else
echo "✗ WordPress check failed, restoring backup..."
wp db import "$BACKUP_DIR/db-before-update-$DATE.sql.gz"
exit 1
fiRollback Failed Updates
#!/bin/bash
# rollback-update.sh - Restore last backup
BACKUP_DIR="/backups"
# Find most recent backup
LATEST_DB=$(ls -t "$BACKUP_DIR"/db-before-update-*.sql.gz | head -1)
LATEST_FILES=$(ls -t "$BACKUP_DIR"/files-before-update-*.tar.gz | head -1)
if [ -z "$LATEST_DB" ]; then
echo "No backup found!"
exit 1
fi
echo "Rolling back to backup: $LATEST_DB"
# Restore database
wp db import "$LATEST_DB"
# Restore files
tar -xzf "$LATEST_FILES" -C /var/www/html/
echo "✓ Rollback complete"Bulk Update Across Multiple Sites
Update plugins and themes across all WordPress installations you manage.
Update Multiple Sites Script
#!/bin/bash
# bulk-update-sites.sh - Update all managed sites
SITES=(
"/var/www/site1"
"/var/www/site2"
"/var/www/site3"
"/var/www/client-site"
)
BACKUP_DIR="/backups"
LOG_FILE="/var/log/wp-bulk-updates.log"
log() {
echo "[$(date '+%Y-%m-%d %H:%M:%S')] $@" | tee -a "$LOG_FILE"
}
log "=== Bulk WordPress Update Started ==="
for SITE in "${SITES[@]}"; do
SITE_NAME=$(basename "$SITE")
log "Processing: $SITE_NAME"
cd "$SITE" || { log "ERROR: Cannot access $SITE"; continue; }
# Check WordPress is installed
if ! wp core is-installed 2>/dev/null; then
log "WARNING: WordPress not found in $SITE, skipping"
continue
fi
# Backup database
BACKUP_FILE="$BACKUP_DIR/${SITE_NAME}-$(date +%Y%m%d).sql.gz"
if wp db export "$BACKUP_FILE"; then
log "✓ Backed up: $SITE_NAME"
else
log "✗ Backup failed for $SITE_NAME, skipping updates"
continue
fi
# Update plugins
log "Updating plugins for $SITE_NAME..."
if wp plugin update --all --quiet; then
log "✓ Plugins updated: $SITE_NAME"
else
log "✗ Plugin update failed: $SITE_NAME"
fi
# Update themes
log "Updating themes for $SITE_NAME..."
if wp theme update --all --quiet; then
log "✓ Themes updated: $SITE_NAME"
else
log "✗ Theme update failed: $SITE_NAME"
fi
log "---"
done
log "=== Bulk Update Complete ==="Use Case: Agencies managing dozens of client sites can update all installations in one maintenance window.
Update with Email Notifications
#!/bin/bash
# bulk-update-notify.sh - Updates with email reporting
ADMIN_EMAIL="admin@example.com"
REPORT="/tmp/update-report-$$.txt"
{
echo "WordPress Bulk Update Report"
echo "Generated: $(date)"
echo "================================"
echo ""
# Update logic here (from previous script)
# ...
} > "$REPORT"
# Email report
mail -s "WordPress Bulk Update Report" "$ADMIN_EMAIL" < "$REPORT"
rm "$REPORT"Selective and Staged Update Strategies
Control exactly what gets updated and when.
Update Specific Plugins Only
#!/bin/bash
# update-security-plugins.sh - Update security plugins only
SECURITY_PLUGINS=(
"wordfence"
"sucuri-scanner"
"ithemes-security"
"all-in-one-wp-security-and-firewall"
)
for PLUGIN in "${SECURITY_PLUGINS[@]}"; do
echo "Updating security plugin: $PLUGIN"
wp plugin update "$PLUGIN" 2>/dev/null
done
echo "✓ Security plugins updated"Staged Rollout Strategy
#!/bin/bash
# staged-update.sh - Update test sites first, then production
TEST_SITES=("/var/www/test1" "/var/www/staging")
PROD_SITES=("/var/www/prod1" "/var/www/prod2")
echo "Stage 1: Updating test sites..."
for SITE in "${TEST_SITES[@]}"; do
cd "$SITE"
wp plugin update --all
wp theme update --all
done
echo "Test sites updated. Monitor for 24 hours before production."
read -p "Proceed with production updates? (y/n) " -n 1 -r
echo
if [[ ! $REPLY =~ ^[Yy]$ ]]; then
echo "Production updates cancelled"
exit 0
fi
echo "Stage 2: Updating production sites..."
for SITE in "${PROD_SITES[@]}"; do
cd "$SITE"
# Backup first
wp db export "/backups/$(basename $SITE)-prod-$(date +%Y%m%d).sql.gz"
wp plugin update --all
wp theme update --all
done
echo "✓ Staged rollout complete"Learn about WordPress staging environments best practices.
Exclude Problematic Plugins
#!/bin/bash
# update-exclude-known-issues.sh
# Plugins known to have issues in latest version
EXCLUDE_PLUGINS=(
"broken-plugin"
"problematic-theme-plugin"
)
# Build exclude parameter
EXCLUDE_PARAM=""
for PLUGIN in "${EXCLUDE_PLUGINS[@]}"; do
EXCLUDE_PARAM="${EXCLUDE_PARAM}${PLUGIN},"
done
# Remove trailing comma
EXCLUDE_PARAM=${EXCLUDE_PARAM%,}
# Update all except excluded
wp plugin update --all --exclude="$EXCLUDE_PARAM"
echo "Updated all plugins except: $EXCLUDE_PARAM"Automated Update Scheduling
Schedule bulk updates to run automatically during maintenance windows.
Weekly Automated Updates
#!/bin/bash
# weekly-auto-update.sh - Run via cron
LOG_FILE="/var/log/auto-updates.log"
BACKUP_DIR="/backups/auto"
SITES_DIR="/var/www"
log() {
echo "[$(date '+%Y-%m-%d %H:%M:%S')] $@" | tee -a "$LOG_FILE"
}
log "=== Automated Weekly Update Started ==="
# Find all WordPress installations
find "$SITES_DIR" -maxdepth 2 -name "wp-config.php" | while read WP_CONFIG; do
SITE_PATH=$(dirname "$WP_CONFIG")
SITE_NAME=$(basename "$SITE_PATH")
cd "$SITE_PATH"
log "Updating: $SITE_NAME"
# Backup
mkdir -p "$BACKUP_DIR"
wp db export "$BACKUP_DIR/$SITE_NAME-$(date +%Y%m%d).sql.gz" --quiet
# Update
wp plugin update --all --quiet
wp theme update --all --quiet
wp core update --minor --quiet
log "✓ Updated: $SITE_NAME"
done
# Cleanup old backups (keep 30 days)
find "$BACKUP_DIR" -name "*.sql.gz" -mtime +30 -delete
log "=== Automated Update Complete ==="Schedule with cron:
# Run every Sunday at 2 AM
0 2 * * 0 /usr/local/bin/weekly-auto-update.shUpdate Monitoring and Alerts
#!/bin/bash
# monitor-updates.sh - Check for available updates
SITES=("/var/www/site1" "/var/www/site2")
ALERT_EMAIL="admin@example.com"
UPDATES_FOUND=0
REPORT="/tmp/update-status-$$.txt"
{
echo "WordPress Update Status Report"
echo "Generated: $(date)"
echo "=============================="
echo ""
for SITE in "${SITES[@]}"; do
SITE_NAME=$(basename "$SITE")
cd "$SITE"
PLUGIN_UPDATES=$(wp plugin list --update=available --format=count 2>/dev/null)
THEME_UPDATES=$(wp theme list --update=available --format=count 2>/dev/null)
if [ "$PLUGIN_UPDATES" -gt 0 ] || [ "$THEME_UPDATES" -gt 0 ]; then
echo "Site: $SITE_NAME"
echo " Plugins needing update: $PLUGIN_UPDATES"
echo " Themes needing update: $THEME_UPDATES"
echo ""
UPDATES_FOUND=$((UPDATES_FOUND + 1))
fi
done
if [ "$UPDATES_FOUND" -eq 0 ]; then
echo "All sites are up to date!"
fi
} > "$REPORT"
# Send email if updates available
if [ "$UPDATES_FOUND" -gt 0 ]; then
mail -s "WordPress Updates Available ($UPDATES_FOUND sites)" "$ALERT_EMAIL" < "$REPORT"
fi
rm "$REPORT"Testing and Verification
Verify updates didn’t break functionality.
Post-Update Health Check
#!/bin/bash
# verify-updates.sh - Check sites after updates
SITES=("/var/www/site1" "/var/www/site2")
for SITE in "${SITES[@]}"; do
SITE_NAME=$(basename "$SITE")
cd "$SITE"
echo "Checking: $SITE_NAME"
# Check WordPress is functional
if ! wp core is-installed 2>/dev/null; then
echo "✗ WordPress check failed: $SITE_NAME"
continue
fi
# Check database connection
if ! wp db check 2>/dev/null; then
echo "✗ Database check failed: $SITE_NAME"
continue
fi
# Check site responds
SITE_URL=$(wp option get siteurl 2>/dev/null)
if curl -f -s "$SITE_URL" > /dev/null; then
echo "✓ $SITE_NAME is healthy"
else
echo "✗ $SITE_NAME not responding"
fi
doneAutomated Testing Script
#!/bin/bash
# test-after-update.sh
# Critical pages to test
TEST_URLS=(
"/"
"/shop"
"/checkout"
"/my-account"
)
SITE_URL=$(wp option get siteurl)
echo "Testing critical pages..."
for PATH in "${TEST_URLS[@]}"; do
URL="${SITE_URL}${PATH}"
HTTP_CODE=$(curl -s -o /dev/null -w "%{http_code}" "$URL")
if [ "$HTTP_CODE" -eq 200 ]; then
echo "✓ $PATH - OK (200)"
else
echo "✗ $PATH - FAILED ($HTTP_CODE)"
fi
doneNext Steps
You now have professional bulk update capabilities for WordPress sites at scale.
Recommended Learning Path
Week 1: Single site updates
- Practice safe update workflows
- Implement backup strategies
- Test rollback procedures
Week 2: Multi-site automation
- Build bulk update scripts
- Add safety checks
- Implement logging
Week 3: Staged rollouts
- Create test/production workflows
- Set up monitoring
- Automate notifications
Week 4: Full automation
- Schedule automated updates
- Build health check systems
- Document recovery procedures
Advanced Topics
- Zero-Downtime Updates – Update without taking sites offline
- Update Testing Automation – Automated functional testing
- Large-Scale WordPress Management – Managing 500+ sites
Get More Resources
Download update automation scripts including:
- Complete bulk update system
- Rollback automation
- Health check templates
- Weekly WP-CLI tutorials
- WordPress automation strategies
- Enterprise management techniques
Conclusion
Bulk updating WordPress sites with WP-CLI transforms a time-consuming, risky process into a fast, safe, automated workflow that scales to any number of installations.
What we covered:
✅ Single site update operations with safety checks ✅ Automated backup and rollback strategies ✅ Bulk update scripts for multiple sites ✅ Selective and staged update approaches ✅ Automated scheduling and monitoring ✅ Post-update testing and verification
Master these techniques, and you’ll manage WordPress updates across unlimited sites efficiently while maintaining security and minimizing downtime.
Ready for more? Learn WordPress deployment automation or continuous integration for WordPress.
Questions about bulk WordPress updates with WP-CLI? Drop a comment below!
Found this helpful? Share with other WordPress developers and agencies.
