How to Automatically Add Users to All Sites in WordPress Multisite


In a WordPress Multisite network, managing users can be tedious, especially when you need to create a user and assign them access to more than one site. By default, WordPress doesn’t offer an easy way to sync or bulk assign users across subsites.

This guide walks you through a complete solution that:

  • Adds a custom “Add Synced User” form to the network admin panel.
  • It allows you to select subsites to add a user to during creation.
  • Introduces a custom bulk action to sync selected users to all subsites with just one click.

Solution: Add Users to All Sites in WordPress Multisite

// Add "Add Synced User" page under Users in Network Admin
add_action('network_admin_menu', function() {
    add_submenu_page(
        'users.php',
        'Add Synced User',
        'Add Synced User',
        'manage_network_users',
        'add-synced-user',
        'ts_custom_multisite_user_sync_page'
    );
});

// Render the Add User form
function ts_custom_multisite_user_sync_page() {
    if (isset($_POST['submit']) && check_admin_referer('custom_add_synced_user')) {
        $username = sanitize_user($_POST['username']);
        $email = sanitize_email($_POST['email']);
        $selected_sites = isset($_POST['sites']) ? array_map('intval', $_POST['sites']) : [];

        if (!username_exists($username) && !email_exists($email)) {
            $user_id = wpmu_create_user($username, wp_generate_password(), $email);

            if (!is_wp_error($user_id)) {
                foreach ($selected_sites as $site_id) {
                    add_user_to_blog($site_id, $user_id, 'subscriber');
                }
                echo '<div class="notice notice-success"><p>User created and added to selected sites!</p></div>';
            } else {
                echo '<div class="notice notice-error"><p>Error: ' . $user_id->get_error_message() . '</p></div>';
            }
        } else {
            echo '<div class="notice notice-warning"><p>User already exists.</p></div>';
        }
    }

    $sites = get_sites();
    ?>
    <div class="wrap">
        <h1>Add Synced User</h1>
        <form method="post">
            <?php wp_nonce_field('custom_add_synced_user'); ?>
            <table class="form-table">
                <tr>
                    <th scope="row"><label for="username">Username</label></th>
                    <td><input name="username" type="text" id="username" class="regular-text" required></td>
                </tr>
                <tr>
                    <th scope="row"><label for="email">Email</label></th>
                    <td><input name="email" type="email" id="email" class="regular-text" required></td>
                </tr>
                <tr>
                    <th scope="row">Add to Sites</th>
                    <td>
                        <?php foreach ($sites as $site): ?>
                            <label>
                                <input type="checkbox" name="sites[]" value="<?php echo esc_attr($site->blog_id); ?>">
                                <?php echo esc_html(get_blog_details($site->blog_id)->blogname); ?>
                            </label><br>
                        <?php endforeach; ?>
                    </td>
                </tr>
            </table>
            <?php submit_button('Add User', 'primary', 'submit'); ?>
        </form>
    </div>
    <?php
}

// -------------------------
// Bulk Action: Add Users to All Sites
// -------------------------

// 1. Register the custom bulk action
add_filter('bulk_actions-users-network', function($bulk_actions) {
    $bulk_actions['ts_add_to_sites'] = 'Add to all sites';
    return $bulk_actions;
});

// 2. Handle the bulk action logic
add_filter('handle_network_bulk_actions-users-network', function($redirect_to, $doaction, $user_ids) {
    if ('ts_add_to_sites' !== $doaction) {
        return $redirect_to;
    }

    $sites = get_sites([
        'fields' => 'ids',
        'spam' => 0,
        'deleted' => 0,
        'archived' => 0,
        'mature' => 0,
    ]);

    $count = 0;

    foreach ($user_ids as $user_id) {
        if (is_super_admin($user_id)) {
            continue; // Skip super admins
        }

        foreach ($sites as $site_id) {
            add_user_to_blog($site_id, $user_id, 'subscriber');
        }
        $count++;
    }

    return add_query_arg('ts_added_to_all_sites', $count, $redirect_to);
}, 10, 3);

// 3. Show a notice after bulk action
add_action('network_admin_notices', function() {
    if (!empty($_REQUEST['ts_added_to_all_sites'])) {
        $count = (int) $_REQUEST['ts_added_to_all_sites'];
        $message = sprintf(
            _n('%d user has been added to all sites.', '%d users have been added to all sites.', $count),
            $count
        );
        echo "<div class='updated notice is-dismissible'><p>{$message}</p></div>";
    }
});