WP-CLI
Loggedin ships a set of WP-CLI commands so you can inspect and clear user sessions, and read or change plugin settings, without opening wp-admin. Useful for bulk operations, deploy scripts, support workflows and headless installs.
Available since 3.1.0. No configuration or extra install is needed — the commands register themselves when the plugin is active. They are wired only on WP-CLI requests, so they add nothing to the cost of a normal page load.
Command overview
wp loggedin sessions list <user> # Active sessions for a user
wp loggedin sessions count <user> # Number of active sessions
wp loggedin sessions destroy <user> # Sign a user out
wp loggedin sessions destroy-all # Sign out every user on the site
wp loggedin settings list # Every setting and its value
wp loggedin settings get <key> # Read one setting
wp loggedin settings set <key> <value># Write one settingRun wp help loggedin, or wp help loggedin sessions list for any individual command, to see the same reference from your terminal.
Identifying a user
Every sessions command takes a <user> argument that accepts the same three forms as the User field on the Sessions page. The lookup is WP-CLI's own, the one wp user uses, so it is a little more forgiving than the Sessions page, which doesn't fall back from an email address to a username:
| Input looks like | Looked up as |
|---|---|
Digits only (e.g. 42) | User ID |
An email address (e.g. user@example.com) | Email address, then user_login if no account has that email |
Anything else (e.g. jdoe) | user_login |
If a username is all digits and another user has that number as their ID, WP-CLI warns and uses the ID.
If nothing matches, the command exits with an error and changes nothing:
$ wp loggedin sessions count nobody
Error: Invalid user ID, email or login: 'nobody'wp loggedin sessions list
Lists the user's active sessions, newest first.
wp loggedin sessions list <user> [--field=<field>] [--fields=<fields>] [--format=<format>]| Option | Description |
|---|---|
--field=<field> | Print only this field's value for each session. |
--fields=<fields> | Comma-separated columns to show. Default: token,login,expiration,ip,ua |
--format=<format> | table (default), csv, json, yaml, count, ids. ids prints the token hashes on one line, separated by spaces. |
Columns:
| Column | Description |
|---|---|
token | Hashed session token. Identifies the session for a single-session destroy. The raw token is never exposed. |
login | When the session was created, in your site's timezone. |
expiration | When WordPress will consider the session expired. |
ip | IP address recorded at login. |
ua | User-agent string recorded at login. |
$ wp loggedin sessions list editor@example.com
+------------------+---------------------+---------------------+-------------+-----------------+
| token | login | expiration | ip | ua |
+------------------+---------------------+---------------------+-------------+-----------------+
| a69662435664c6.. | 2026-07-29 09:01:18 | 2026-07-31 09:01:18 | 203.0.113.9 | Mozilla/5.0 ... |
+------------------+---------------------+---------------------+-------------+-----------------+A user with no active sessions gets Success: No active sessions for <login>. instead of a table.
Expired-but-not-yet-deleted tokens are filtered out. WordPress only prunes those when the user next signs in, so the raw database row is not a reliable "currently logged in" list — this command is.
Scripting
--field=token prints one token hash per line, ready to feed into a follow-up destroy --token= call.
wp loggedin sessions count
Prints just the number of active sessions — handy in conditionals.
$ wp loggedin sessions count 42
3Unlike list, this reads through the WP_Session_Tokens API, so it stays accurate on sites using a custom session backend.
wp loggedin sessions destroy
Destroys sessions, signing the user out. Without --token, every session for the user is destroyed — the CLI equivalent of the Sign out a user card on the Sessions page.
wp loggedin sessions destroy <user> [--token=<hash>] [--yes]| Option | Description |
|---|---|
--token=<hash> | Destroy only this one session. Take the value from the token column of sessions list. |
--yes | Skip the confirmation prompt. Required in unattended scripts. |
# Sign a user out everywhere.
$ wp loggedin sessions destroy editor@example.com --yes
Success: Destroyed 3 session(s) for editor.
# Sign a user out of one device only.
$ wp loggedin sessions destroy 42 --token=a69662435664c6... --yes
Success: Destroyed 1 session for editor.If the user has no active sessions, the command prints Success: No active sessions for <login>. and asks nothing. A --token that matches none of the user's sessions is an error.
Destroying all sessions fires loggedin_destroy_all_sessions, the same action the Sessions page fires, so add-ons and custom code see both paths. A single-session destroy fires loggedin_destroy_session instead.
--token with an empty value is rejected
wp loggedin sessions destroy 42 --token=$TOKEN where $TOKEN is unset would otherwise silently destroy all of the user's sessions. The command errors out instead. Drop the flag entirely when you mean "all".
wp loggedin sessions destroy-all
Signs out every user on the site — the CLI equivalent of the Sign out all users button. Added in 3.3.0.
wp loggedin sessions destroy-all [--yes]| Option | Description |
|---|---|
--yes | Skip the confirmation prompt. Required in unattended scripts. |
$ wp loggedin sessions destroy-all --yes
Success: All users will be logged out on their next request.Unlike the destroy command, this doesn't iterate users. It stores a site-wide logout timestamp (the logout epoch); every session created before that moment is rejected and destroyed on its owner's next request. That makes the command O(1) — it completes instantly whether the site has ten users or a million — and it works with any session storage backend.
Because no per-user loop runs, loggedin_destroy_all_sessions does not fire. Listen for loggedin_logout_all_users (once, at trigger time) and loggedin_session_invalidated (per session, as each is rejected) instead.
Nobody is exempt on the CLI
The wp-admin button keeps the clicking admin's session alive. The CLI has no session of its own, so no exemption applies — every session is logged out, including yours if you're also signed in to wp-admin in a browser.
wp loggedin settings list
Prints every setting and its current value.
$ wp loggedin settings list
+--------------------+-------+
| key | value |
+--------------------+-------+
| maximum | 3 |
| logic | block |
| unlock | 1 |
| exempt_admins | 1 |
| password_signout | 1 |
| message | |
| displaced_redirect | |
+--------------------+-------+On/off settings print 1 for on and an empty value for off. The keys added in 3.4.0 are described under Settings storage. Auto logout's settings live in their own options, so they aren't listed here.
Supports --format=table|csv|json|yaml. Settings registered by add-ons through loggedin_settings_defaults appear here automatically. settings set can change one only once the add-on also gives it a schema through loggedin_settings_properties.
wp loggedin settings get
$ wp loggedin settings get maximum
3On/off settings print 1 or an empty line, as in list. An unknown key errors out and lists the valid keys.
wp loggedin settings set
$ wp loggedin settings set maximum 3
Success: Updated maximum to 3.
$ wp loggedin settings set logic block
Success: Updated logic to block.maximum takes a whole number of 1 or more. Valid values for logic are allow (Logout All), logout_oldest (Logout Oldest) and block (Block New) — see Login Limits for what each mode does.
On/off settings (unlock, exempt_admins, password_signout) take true/false, yes/no, on/off or 1/0:
$ wp loggedin settings set exempt_admins on
Success: Updated exempt_admins to true.message takes text, where a link, bold and italics (<a href>, <strong>, <em>) are allowed. displaced_redirect takes the URL of a page on this site, or on a host allowed by the allowed_redirect_hosts filter. Pass an empty string ("") to clear either.
Writes go through the same sanitizer as the REST API and the admin UI, and a value the sanitizer would reject or alter is refused before anything is written:
$ wp loggedin settings set logic nonsense
Error: "nonsense" is not a valid value for logic. Nothing was changed.This matters more than it looks: without the check, a typo would store the default mode instead, quietly loosening the limit on a site that was deliberately set to Block New.
Session storage support
Two commands read the session store directly, because the WordPress API has no way to address one specific session:
| Command | Custom session backend (Redis, Memcached, …) |
|---|---|
sessions count | ✅ Works |
sessions destroy (all) | ✅ Works |
sessions destroy-all | ✅ Works |
sessions list | ⚠️ Needs the default user-meta storage |
sessions destroy --token= | ⚠️ Needs the default user-meta storage |
On a site with a custom backend, sessions list prints a warning and lists no sessions, and destroy --token= errors out and points you at the destroy-all form. Before 3.4.0, sessions list read the user meta directly and could show rows left over from before the site switched backends. This mirrors the Logout Oldest mode's constraint.
Recipes
Sign out everyone in a role — e.g. after revoking access:
wp user list --role=subscriber --field=ID | while read -r id; do
wp loggedin sessions destroy "$id" --yes
doneTighten the limit during an incident, then restore it:
wp loggedin settings set logic block
wp loggedin settings set maximum 1
# ... later ...
wp loggedin settings set maximum 3Find accounts that look shared — more sessions than your cap:
wp user list --field=ID | while read -r id; do
count=$(wp loggedin sessions count "$id")
[ "$count" -gt 3 ] && echo "user $id has $count sessions"
doneDoing this in the browser instead
The Active Sessions add-on gives you the same cross-user view as a sortable admin screen, including per-device detail and one-click sign-out.
Extending
Add-ons can register their own subcommands under the wp loggedin namespace on the loggedin_cli_init action, which fires after the core commands are registered.
add_action( 'loggedin_cli_init', function () {
WP_CLI::add_command( 'loggedin my-addon', My_Addon_Command::class );
} );