PHPackages                             iandunn/wp-cli-network-users - PHPackages - PHPackages  [Skip to content](#main-content)[PHPackages](/)[Directory](/)[Categories](/categories)[Trending](/trending)[Leaderboard](/leaderboard)[Changelog](/changelog)[Analyze](/analyze)[Collections](/collections)[Log in](/login)[Sign up](/register)

1. [Directory](/)
2. /
3. [CLI &amp; Console](/categories/cli)
4. /
5. iandunn/wp-cli-network-users

ActiveWordpress-plugin[CLI &amp; Console](/categories/cli)

iandunn/wp-cli-network-users
============================

WP-CLI commands for managing users across a WordPress Multisite network

v1.0.4(1w ago)027GPL-2.0-onlyPHPCI passing

Since May 15Pushed 5d agoCompare

[ Source](https://github.com/iandunn/wp-cli-network-users)[ Packagist](https://packagist.org/packages/iandunn/wp-cli-network-users)[ Docs](https://github.com/iandunn/wp-cli-network-users)[ RSS](/packages/iandunn-wp-cli-network-users/feed)WikiDiscussions main Synced 1w ago

READMEChangelogDependencies (8)Versions (6)Used By (0)

WP-CLI Network Users
====================

[](#wp-cli-network-users)

WP-CLI commands for managing users across a WordPress Multisite network.

Provides `wp user delete-network` and `wp user set-role-network`. Both can be applied to users who haven't been active in the past `n` days, or who have never been active.

"Active" just means that they've logged in during the given time period.

```
> wp user delete-network --inactive=180 --reassign=jane.doe --scope=network --dry-run

Found 183 users to delete:

+------+------------------------------+------------------------------------+-------+-------------+------------+
| ID   | username                     | email                              | sites | super_admin | last_login |
+------+------------------------------+------------------------------------+-------+-------------+------------+
| 10   | hoban.washburne              | hoban.washburne@example.org        | 31    | yes         | 2022-08-24 |
| 2847 | zoe.washburne                | zoe.washburne@example.org          | 1     | yes         | never      |
| 5931 | inara.serra                  | inara.serra@example.org            | 43    | no          | 2025-11-07 |
| 614  | malcolm.reynolds             | malcolm.reynolds@example.org       | 3     | yes         | 2024-03-11 |
| 1278 | jayne.cobb                   | jayne.cobb@example.org             | 2     | no          | 2023-06-15 |
| 88   | kaylee.frye                  | kaylee.frye@example.org            | 4     | yes         | never      |
| 89   | simon.tam                    | simon.tam@example.org              | 28    | no          | 2024-09-30 |
| 90   | river.tam                    | river.tam@example.org              | 38    | no          | 2021-12-04 |
| 2053 | derrial.book                 | derrial.book@example.org           | 26    | yes         | 2025-04-18 |
| ...  | ...                          | ...                                | ...   | ...         | ...        |
| 5187 | adelai.niska                 | adelai.niska@example.org           | 3     | no          | 2022-01-29 |
| 341  | jubal.early                  | jubal.early@example.org            | 19    | no          | 2023-10-03 |
| 1864 | tracey.smith                 | tracey.smith@example.org           | 1     | no          | 2024-07-22 |
| 6102 | atherton.wing                | atherton.wing@example.org          | 2     | no          | never      |
| 927  | yolanda.haymer               | yolanda.haymer@example.org         | 41    | no          | 2025-02-14 |
| 555  | saffron.reynolds             | saffron.reynolds@example.org       | 45    | no          | 2021-07-09 |
| 248  | fanty.oram@example.org       | fanty.oram@example.org             | 35    | no          | 2023-03-27 |
| 4843 | laurence.dobson              | laurence.dobson@example.org        | 1     | no          | never      |
| 1531 | mingo.oram@example.org       | mingo.oram@example.org             | 30    | no          | 2026-01-05 |
+------+------------------------------+------------------------------------+-------+-------------+------------+

Content will be reassigned to: [91] jane.doe (jane.doe@example.org)

Network accounts will be permanently deleted.

Warning: 5 users are a super admin and will be skipped. Add --include-super-admins to include them.

Dry run — no changes made.
```

Simpler Alternatives
--------------------

[](#simpler-alternatives)

For simple cases, the built-in WP-CLI commands and a little plumbing is enough:

```
# Re-assign content on all sites before deleting a user network-wide
wp site list --field=url | xargs -I {} wp --url={} user delete fanty.oram@example.org --reassign=205
wp user delete 26 --network

# Set a role on every site. This will add the user to every site in the network.
wp site list --field=url --network | xargs -I {} wp --url={} user set-role jubal.early subscriber
```

Use this if you want:
---------------------

[](#use-this-if-you-want)

- **Inactivity targeting** — bulk-target users who haven't logged in within `n` days, or ever since the plugin was installed (`--inactive=` / `--inactive=never`)
- **Speed on large networks** - this is much faster than the `wp site list...` loop, because it only acts on sites the user is already on, and doesn't re-load WP for every site
- **Targeting assigned sites** — only sets the user's role on sites they're already a member of; the `wp site list... set-role` loop adds them to every site in the network
- **Multiple users at once** — comma-separated IDs, usernames, or emails in a single command
- **Dry-run preview** — see who would be affected before committing (`--dry-run`)
- **VIP-aware inactivity** — automatically incorporates WordPress VIP's `wpvip_last_seen` data when present, so users active via VIP before this plugin was installed are still handled correctly
- **Convenience** - you don't have to remember or look up how to pipe site URLs to `xargs`
- **Using usernames or emails** when reassigning content, instead of having to look up IDs
- **Super admin protection** on delete — super admins are skipped by default; opt in with `--include-super-admins`

Installing
----------

[](#installing)

1. Ensure your `composer.json` has `composer/installers` and the plugins path configured. Most Composer-managed WordPress projects will already have this.

    ```
    {
    	"require": {
    		"composer/installers": "^2.2"
    	},
    	"extra": {
    		"installer-paths": {
    		"wp-content/plugins/{$name}/": ["type:wordpress-plugin"]
    		}
    	}
    }
    ```
2. Install the plugin:

    ```
    composer require iandunn/wp-cli-network-users
    ```
3. Activate the plugin:

    ```
    wp plugin activate wp-cli-network-users --network
    ```

Commands
--------

[](#commands)

### `wp user delete-network`

[](#wp-user-delete-network)

Delete users network-wide, with optional content reassignment.

```
# Target and re-assign by user ID, username, or email
wp user delete-network --users=42,inara.serra,derrial.book@example.org --no-reassign --scope=sites
wp user delete-network --users=42,jane,bob@example.com --reassign=hoban.washburne --scope=network

# Target by inactivity
wp user delete-network --inactive=365 --reassign=zoe.washburne --scope=sites
wp user delete-network --inactive=never --no-reassign --scope=network
```

**Flags:**

- `--users=` — Comma-separated list of user IDs, usernames, or emails. Mutually exclusive with `--inactive`.
- `--inactive=` — Target users whose most recent activity is older than this many days. Mutually exclusive with `--users`.
- `--inactive=never` — Target users with no activity record. Mutually exclusive with `--users`.
- `--reassign=` — User ID, username, or email to reassign all content to. Mutually exclusive with `--no-reassign`.
- `--no-reassign` — Permanently delete all content belonging to removed users. Mutually exclusive with `--reassign`.
- `--scope=` — `sites` removes users from all site memberships but keeps their network account. `network` also permanently deletes the account. Required.
- `--include-super-admins` — When using `--scope=network`, revoke super admin status before deleting. Without this flag, super admins are skipped.
- `--dry-run` — Show what would be changed without making any changes.
- `--yes` — Skip confirmation prompt.

Before deleting, shows a confirmation table with ID, username, email, site count, super admin status, and last login date.

---

### `wp user set-role-network`

[](#wp-user-set-role-network)

Set a role for users on every site they belong to across the network. Leave off `--role` to default to `subscriber`.

```
# Target by user ID, username, or email
wp user set-role-network --users=42,atherton.wing@example.org,saffron.reynolds # set to `subscriber` by default
wp user set-role-network --users=simon.tam,kaylee.frye --role=administrator

# Target by inactivity
wp user set-role-network --inactive=365
wp user set-role-network --inactive=never --role=subscriber
```

**Flags:**

- `--users=` — Comma-separated list of user IDs, usernames, or emails. Mutually exclusive with `--inactive`.
- `--inactive=` — Target users whose most recent activity is older than this many days. Mutually exclusive with `--users`.
- `--inactive=never` — Target users with no activity record from either source. Mutually exclusive with `--users`.
- `--role=` — Role to assign. Defaults to `subscriber`.
- `--dry-run` — Show what would be changed without making any changes.
- `--yes` — Skip confirmation prompt.

Before updating, shows the same confirmation table as `delete-network`.

Notes
-----

[](#notes)

- Inactivity is determined by the most recent of two timestamps: this plugin's own `network_users_last_login` (recorded at login) and WordPress VIP's `wpvip_last_seen` (recorded on each page load), if present. Whichever is newer wins.
- ⚠️ Users with neither timestamp won't be matched by `--inactive=`. Use `--inactive=never` to target them specifically.
- This is only intended for Multisite networks, and hasn't been tested in single sites.

Contributing / Setup
--------------------

[](#contributing--setup)

See [CONTRIBUTING.md](CONTRIBUTING.md)

###  Health Score

40

—

FairBetter than 86% of packages

Maintenance99

Actively maintained with recent releases

Popularity10

Limited adoption so far

Community6

Small or concentrated contributor base

Maturity37

Early-stage or recently created project

 Bus Factor1

Top contributor holds 100% of commits — single point of failure

How is this calculated?**Maintenance (25%)** — Last commit recency, latest release date, and issue-to-star ratio. Uses a 2-year decay window.

**Popularity (30%)** — Total and monthly downloads, GitHub stars, and forks. Logarithmic scaling prevents top-heavy scores.

**Community (15%)** — Contributors, dependents, forks, watchers, and maintainers. Measures real ecosystem engagement.

**Maturity (30%)** — Project age, version count, PHP version support, and release stability.

###  Release Activity

Cadence

Every ~3 days

Total

5

Last Release

11d ago

### Community

Maintainers

![](https://www.gravatar.com/avatar/af78c57280b5a7b834b2311a82e2c7cc115875a43a99f171720a77fe08d0098b?d=identicon)[iandunn](/maintainers/iandunn)

---

Top Contributors

[![iandunn](https://avatars.githubusercontent.com/u/484068?v=4)](https://github.com/iandunn "iandunn (38 commits)")

---

Tags

wordpress-multisitewp-cli-commandwordpressUsersmultisitewp-cli

### Embed Badge

![Health badge](/badges/iandunn-wp-cli-network-users/health.svg)

```
[![Health](https://phpackages.com/badges/iandunn-wp-cli-network-users/health.svg)](https://phpackages.com/packages/iandunn-wp-cli-network-users)
```

###  Alternatives

[wp-cli/wp-cli

WP-CLI framework

5.1k18.5M386](/packages/wp-cli-wp-cli)[wpsh/wp-cli-replicator

3583.6k](/packages/wpsh-wp-cli-replicator)[wearerequired/wp-cli-clear-opcache

Use WP-CLI to clear the OPcache for a site via HTTP.

1736.4k](/packages/wearerequired-wp-cli-clear-opcache)[frozzare/wp-cli-media-restore

Restore media attachments using WP CLI

2010.9k](/packages/frozzare-wp-cli-media-restore)

PHPackages © 2026

[Directory](/)[Categories](/categories)[Trending](/trending)[Changelog](/changelog)[Analyze](/analyze)
