Repository navigation
Command Line Reference
Run these with php artisan from the application directory. In Docker, prefix
with docker compose exec cortendesk.
Several of these are the way back in when the console itself will not let you sign in, so it is worth knowing they exist before you need them.
php artisan cortendesk:2fa-reset <username>Disables TOTP on that account so they can sign in with their password and re-enrol. This is the answer to "the administrator lost their phone" and it does not require console access.
php artisan cortendesk:2fa-requirement status
php artisan cortendesk:2fa-requirement offFor when Require 2FA for everyone or for administrators is on and nobody
who can reach Settings has enrolled. off clears both switches. Users who
already enrolled are still asked for their code. Since 1.0.5.
php artisan cortendesk:email-verification off
php artisan cortendesk:email-verification on
php artisan cortendesk:email-verification # report current stateUse off when mail has broken while emailed sign-in codes are required —
otherwise nobody can complete a sign-in. Run with no argument to report the
current state and relay health.
Not an artisan command — an environment variable:
CORTENDESK_OIDC_DISABLED=true
Forces SSO off regardless of stored settings and restores the password form. Needed when password sign-in has been disabled and the identity provider is unreachable; see Single sign-on.
php artisan cortendesk:prune-logs
php artisan cortendesk:prune-logs --days=90 # override the configured windowDeletes rows older than the retention window across connections, file transfers,
logins, alarms and the console audit trail. Deletes in chunks so it does not lock
tables on a large install. Does nothing when retention is 0 (keep forever).
Runs nightly on the scheduler.
php artisan cortendesk:prune-invitationsRemoves expired invitations, long-accepted ones, and expired trusted-device records. Hygiene only — expiry is enforced at redemption regardless.
php artisan cortendesk:close-stale-sessionsCloses sessions belonging to devices that have stopped heartbeating — a machine that was rebooted, unplugged or had its service stopped never reports its session closed, so without this it would show as active indefinitely.
Runs every five minutes on the scheduler.
Since 1.11.0.
php artisan cortendesk:dedupe-audits # report only
php artisan cortendesk:dedupe-audits --force # remove the copiesRemoves the connection, file transfer and alarm rows that RustDesk 1.5.0
clients stored two or three times before 1.11.0 (see
Audit logs). Without
--force it only prints how many copies it found in each table.
A row counts as a copy when it matches an earlier row from the same device and arrived on the client's retry schedule: about 10 seconds after the first, then about 30 seconds after that. The same transfer repeated by hand a minute later is kept, and a second run finds nothing. For connections, the authorized row is kept and takes the earliest start time. Rows with a note or a disconnect request are never removed.
| Option | Effect |
|---|---|
--force |
Remove the copies. Without it nothing changes (--dry-run is the default). |
--all |
Look at every row. By default only rows since 2026-10-01, when RustDesk 1.5.0 shipped. |
--any-version |
Also look at devices that report a client older than 1.5.0, or none. By default only devices on 1.5.0 or later. |
Back up the database before running it with --force.
php artisan cortendesk:import-lejianwen <path-to-sqlite-db>Imports users (with passwords intact), devices, address books and audit history. See Importing from rustdesk-api.
Everything above marked "runs on the scheduler" needs Laravel's scheduler running.
- Docker — already running inside the container. Nothing to do.
- Manual install — add the cron entry, or none of the scheduled jobs ever run:
* * * * * cd /path/to/cortendesk && php artisan schedule:run >> /dev/null 2>&1
Without it, logs grow forever and sessions from powered-off machines pile up as permanently active.
Before 1.10.1, a manual install whose PHP has pcntl_signal in
disable_functions (a common hosting-panel default) ran each locked task once
and then left it locked for 24 hours. Notifications, the stale-session sweep
and the diagnostics heartbeat stopped. 1.10.1 fixes this and lets locks expire
after minutes. After upgrading, clear the old locks once:
php artisan schedule:clear-cacheDocker installs are not affected.