{"id":50975794,"url":"https://github.com/iandunn/wp-cli-network-users","last_synced_at":"2026-06-19T08:00:59.208Z","repository":{"id":358122943,"uuid":"1240013902","full_name":"iandunn/wp-cli-network-users","owner":"iandunn","description":"WP-CLI commands for managing users across a WordPress Multisite network.","archived":false,"fork":false,"pushed_at":"2026-06-17T18:53:07.000Z","size":111,"stargazers_count":1,"open_issues_count":0,"forks_count":0,"subscribers_count":0,"default_branch":"main","last_synced_at":"2026-06-17T20:27:12.035Z","etag":null,"topics":["wordpress-multisite","wp-cli-command"],"latest_commit_sha":null,"homepage":"","language":"PHP","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/iandunn.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":"CONTRIBUTING.md","funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2026-05-15T17:18:10.000Z","updated_at":"2026-06-17T18:49:57.000Z","dependencies_parsed_at":null,"dependency_job_id":null,"html_url":"https://github.com/iandunn/wp-cli-network-users","commit_stats":null,"previous_names":["iandunn/wp-cli-network-users"],"tags_count":1,"template":false,"template_full_name":null,"purl":"pkg:github/iandunn/wp-cli-network-users","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/iandunn%2Fwp-cli-network-users","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/iandunn%2Fwp-cli-network-users/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/iandunn%2Fwp-cli-network-users/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/iandunn%2Fwp-cli-network-users/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/iandunn","download_url":"https://codeload.github.com/iandunn/wp-cli-network-users/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/iandunn%2Fwp-cli-network-users/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":34522042,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-05-26T15:22:16.424Z","status":"online","status_checked_at":"2026-06-19T02:00:06.005Z","response_time":61,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["wordpress-multisite","wp-cli-command"],"created_at":"2026-06-19T08:00:33.313Z","updated_at":"2026-06-19T08:00:59.202Z","avatar_url":"https://github.com/iandunn.png","language":"PHP","funding_links":[],"categories":[],"sub_categories":[],"readme":"WP-CLI Network Users\n====================\n\n[WP-CLI](http://wp-cli.org/) commands for managing users across a WordPress Multisite network.\n\nProvides `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.\n\n\"Active\" just means that they've logged in during the given time period.\n\n```bash\n\u003e wp user delete-network --inactive=180 --reassign=jane.doe --scope=network --dry-run\n\nFound 183 users to delete:\n\n+------+------------------------------+------------------------------------+-------+-------------+------------+\n| ID   | username                     | email                              | sites | super_admin | last_login |\n+------+------------------------------+------------------------------------+-------+-------------+------------+\n| 10   | hoban.washburne              | hoban.washburne@example.org        | 31    | yes         | 2022-08-24 |\n| 2847 | zoe.washburne                | zoe.washburne@example.org          | 1     | yes         | never      |\n| 5931 | inara.serra                  | inara.serra@example.org            | 43    | no          | 2025-11-07 |\n| 614  | malcolm.reynolds             | malcolm.reynolds@example.org       | 3     | yes         | 2024-03-11 |\n| 1278 | jayne.cobb                   | jayne.cobb@example.org             | 2     | no          | 2023-06-15 |\n| 88   | kaylee.frye                  | kaylee.frye@example.org            | 4     | yes         | never      |\n| 89   | simon.tam                    | simon.tam@example.org              | 28    | no          | 2024-09-30 |\n| 90   | river.tam                    | river.tam@example.org              | 38    | no          | 2021-12-04 |\n| 2053 | derrial.book                 | derrial.book@example.org           | 26    | yes         | 2025-04-18 |\n| ...  | ...                          | ...                                | ...   | ...         | ...        |\n| 5187 | adelai.niska                 | adelai.niska@example.org           | 3     | no          | 2022-01-29 |\n| 341  | jubal.early                  | jubal.early@example.org            | 19    | no          | 2023-10-03 |\n| 1864 | tracey.smith                 | tracey.smith@example.org           | 1     | no          | 2024-07-22 |\n| 6102 | atherton.wing                | atherton.wing@example.org          | 2     | no          | never      |\n| 927  | yolanda.haymer               | yolanda.haymer@example.org         | 41    | no          | 2025-02-14 |\n| 555  | saffron.reynolds             | saffron.reynolds@example.org       | 45    | no          | 2021-07-09 |\n| 248  | fanty.oram@example.org       | fanty.oram@example.org             | 35    | no          | 2023-03-27 |\n| 4843 | laurence.dobson              | laurence.dobson@example.org        | 1     | no          | never      |\n| 1531 | mingo.oram@example.org       | mingo.oram@example.org             | 30    | no          | 2026-01-05 |\n+------+------------------------------+------------------------------------+-------+-------------+------------+\n\nContent will be reassigned to: [91] jane.doe (jane.doe@example.org)\n\nNetwork accounts will be permanently deleted.\n\nWarning: 5 users are a super admin and will be skipped. Add --include-super-admins to include them.\n\nDry run — no changes made.\n```\n\n\n## Simpler Alternatives\n\nFor simple cases, the built-in WP-CLI commands and a little plumbing is enough:\n\n```bash\n# Re-assign content on all sites before deleting a user network-wide\nwp site list --field=url | xargs -I {} wp --url={} user delete fanty.oram@example.org --reassign=205\nwp user delete 26 --network\n\n# Set a role on every site. This will add the user to every site in the network.\nwp site list --field=url --network | xargs -I {} wp --url={} user set-role jubal.early subscriber\n```\n\n\n## Use this if you want:\n\n- **Inactivity targeting** — bulk-target users who haven't logged in within `n` days, or ever since the plugin was installed (`--inactive=\u003cdays\u003e` / `--inactive=never`)\n- **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\n- **Flexible site targeting** — `--sites=current` updates only sites the user already belongs to; `--sites=all` adds them to every site; or target specific sites by ID or URL\n- **Multiple users at once** — comma-separated IDs, usernames, or emails in a single command\n- **Dry-run preview** — see who would be affected before committing (`--dry-run`)\n- **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\n- **Convenience** - you don't have to remember or look up how to pipe site URLs to `xargs`\n- **Using usernames or emails** when reassigning content, instead of having to look up IDs\n- **Super admin protection** on delete — super admins are skipped by default; opt in with `--include-super-admins`\n\n\n## Installing\n\n1. Ensure your `composer.json` has `composer/installers` and the plugins path configured. Most Composer-managed WordPress projects will already have this.\n\t```json\n\t{\n\t\t\"require\": {\n\t\t\t\"composer/installers\": \"^2.2\"\n\t\t},\n\t\t\"extra\": {\n\t\t\t\"installer-paths\": {\n\t\t\t\"wp-content/plugins/{$name}/\": [\"type:wordpress-plugin\"]\n\t\t\t}\n\t\t}\n\t}\n\t```\n\n1. Install the plugin:\n\t```bash\n\tcomposer require iandunn/wp-cli-network-users\n\t```\n\n1. Activate the plugin:\n\t```bash\n\twp plugin activate wp-cli-network-users --network\n\t```\n\n## Commands\n\n### `wp user delete-network`\n\nDelete users network-wide, with optional content reassignment.\n\n```bash\n# Target and re-assign by user ID, username, or email\nwp user delete-network --users=42,inara.serra,derrial.book@example.org --no-reassign --scope=sites\nwp user delete-network --users=42,jane,bob@example.com --reassign=hoban.washburne --scope=network\n\n# Target by inactivity\nwp user delete-network --inactive=365 --reassign=zoe.washburne --scope=sites\nwp user delete-network --inactive=never --no-reassign --scope=network\n```\n\n\n**Flags:**\n\n- `--users=\u003cusers\u003e` — Comma-separated list of user IDs, usernames, or emails. Mutually exclusive with `--inactive`.\n- `--inactive=\u003cdays\u003e` — Target users whose most recent activity is older than this many days. Mutually exclusive with `--users`.\n- `--inactive=never` — Target users with no activity record. Mutually exclusive with `--users`.\n- `--reassign=\u003cuser\u003e` — User ID, username, or email to reassign all content to. Mutually exclusive with `--no-reassign`.\n- `--no-reassign` — Permanently delete all content belonging to removed users. Mutually exclusive with `--reassign`.\n- `--scope=\u003cscope\u003e` — `sites` removes users from all site memberships but keeps their network account. `network` also permanently deletes the account. Required.\n- `--include-super-admins` — When using `--scope=network`, revoke super admin status before deleting. Without this flag, super admins are skipped.\n- `--dry-run` — Show what would be changed without making any changes.\n- `--yes` — Skip confirmation prompt.\n\nBefore deleting, shows a confirmation table with ID, username, email, site count, super admin status, and last login date.\n\n---\n\n### `wp user set-role-network`\n\nSet a role for users on every site they belong to across the network. Leave off `--role` to default to `subscriber`.\n\n```bash\n# Target by user ID, username, or email\nwp user set-role-network --users=42,atherton.wing@example.org,saffron.reynolds --sites=current # set to `subscriber` by default\nwp user set-role-network --users=simon.tam,kaylee.frye --role=administrator --sites=all\n\n# Target by inactivity\nwp user set-role-network --inactive=365 --sites=current\nwp user set-role-network --inactive=never --sites=current\n\n# Target specific sites by ID or URL\nwp user set-role-network --users=simon.tam --role=editor --sites=2,foo.example.org,example.org/bar\n```\n\n\n**Flags:**\n\n- `--users=\u003cusers\u003e` — Comma-separated list of user IDs, usernames, or emails. Mutually exclusive with `--inactive`.\n- `--inactive=\u003cdays\u003e` — Target users whose most recent activity is older than this many days. Mutually exclusive with `--users`.\n- `--inactive=never` — Target users with no activity record from either source. Mutually exclusive with `--users`.\n- `--role=\u003crole\u003e` — Role to assign. Defaults to `subscriber`.\n- `--sites=\u003csites\u003e` — Required. Which sites to update: `current` only updates sites the user already belongs to; `all` updates every site in the network, adding users to any they're not on; or a comma-separated list of site IDs or URLs (e.g. `2,foo.example.org,example.org/bar`).\n- `--dry-run` — Show what would be changed without making any changes.\n- `--yes` — Skip confirmation prompt.\n\nBefore updating, shows the same confirmation table as `delete-network`.\n\n\n## Notes\n\n- 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.\n- ⚠️ Users with neither timestamp won't be matched by `--inactive=\u003cdays\u003e`. Use `--inactive=never` to target them specifically.\n- This is only intended for Multisite networks, and hasn't been tested in single sites.\n\n\n## Contributing / Setup\n\nSee [CONTRIBUTING.md](CONTRIBUTING.md)\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fiandunn%2Fwp-cli-network-users","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fiandunn%2Fwp-cli-network-users","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fiandunn%2Fwp-cli-network-users/lists"}