← All posts

Removing Orphaned Uploads From Multisite

If you have an active multisite network, chances are you have orphaned content left over from deleted subsites. To clean up the database, there is a fantastic plugin Cleanup Multisite DB Tables which adds a few wp-cli commands to locate and remove any orphaned database tables. To cleanup files, I wasn’t able to find an automated approach. The following are some manual steps I took recently while cleaning up a rather large multisite installation.

In order to figure out which sites are safe to remove from, we first need a list of all subsites. This can gather by running the following wp-cli command wp site list --format=ids which will output something like 1 2 4 7.

Next we need a list of actual upload folders within multisite. On legacy multisite networks this is found under /wp-content/blogs.dir/ for modern networks /wp-content/uploads/sites. From the terminal we can grab a full list by running ls wp-content/blogs.dir/ which will return something like this:

1    2  3  4  5  6  7

These site IDs can be copied into a new bash script we’ll call remove_orphaned_mu_uploads.sh.

#!/bin/bash

# Site IDs taken from `wp site list --format=ids`
sites_to_keep=(1 2 4 7)

# Site IDs from current multisite
#all_site_ids=(`ls wp-content/blogs.dir/`)
all_site_ids=(1    2  3  4  5  6  7)

all_site_ids_count=${#all_site_ids[*]}

# Function to check array for match
containsElement () {
  local e
  for e in "${@:2}"; do [[ "$e" == "$1" ]] && return 0; done
  return 1
}

# Loop through all site IDs upload folders and check if found in active Site ID. Outputs orphaned uploads.
for (( i=0; i<${all_site_ids_count}; i++ ));
do
  containsElement "${all_site_ids[$i]}" "${sites_to_keep[@]}"
  if [ $? == 1 ]
  then
    printf "${all_site_ids[$i]} "
  fi
done

Running remove_orphaned_mu_uploads.sh will output the following: 3 5 6 which are orphaned upload directories. These folders are safe to delete.

I recommend backing up these these directories before deleting. That can be accomplished by pasting those resulting site IDs into the following archive_orphaned_directories.sh script. This script will move the orphaned directories into a temporary location, generate a backup zip and then remove the directories.

# Site IDs taken from output of remove_orphaned_mu_uploads.sh
to_remove=(3 5 6)

# Make directory to archive old directories
mkdir -p ~/private/orphaned_directories/

# Change directories
cd wp-content/blogs.dir/

# Move orphaned directories to archive location
for site in ${to_remove[@]}; do
    mv $site ~/private/orphaned_directories/
done

# Generate zip
cd ~/private
zip_name="$(date +'%Y-%m-%d')-orphaned_directories.zip"
zip -r $zip_name orphaned_directories/

# Remove orphaned directories
rm -rf ~/private/orphaned_directories/
Austin Ginder
Subscribe