su — Switch user — su -, su alice, environment-reset login-shell semantics, runas Windows across all 5 shells
Equivalents in every shell
su - alice`su - USER` opens a LOGIN shell as USER (clears env, sources `~/.profile`/`~/.bash_profile`, sets HOME and PWD to USER's home). `su USER` (no dash) starts a non-login shell that INHERITS your env (PWD stays, PATH preserved, but $HOME confusingly stays as YOURS unless USER's shell init resets it). `su -c "cmd" alice` runs single command then exits. Always prompts for TARGET user's password (different from sudo which prompts for INVOKER's).
su - alicesu - aliceStart-Process pwsh -Credential alice`-Credential` opens a credential prompt (or accepts a `PSCredential` object built from `Get-Credential` or saved from `Export-Clixml`). Windows has NO terminal-switch-user — every "different user" runs in its own session/window. For unattended scripts: pre-build credentials via `(New-Object PSCredential alice, (ConvertTo-SecureString "PW" -AsPlainText -Force))` (insecure — plain text in script) or store via Credential Manager (`Get-StoredCredential` from `CredentialManager` module).
runas /user:alice cmd.exePrompts for alice's password, spawns a NEW cmd window running as alice. There is no "inline switch" in the current console. `runas /savecred /user:alice cmd.exe` caches the password in Credential Manager for future use (security risk on shared machines). For domain users: `runas /user:DOMAIN\alice cmd.exe`.
Worked examples
Open a login shell as another user
su - alicesu - aliceStart-Process pwsh -Credential alicerunas /user:alice cmd.exeRun a single command as another user
su -c "id" alicesu -c "id" aliceStart-Process -FilePath "whoami" -Credential (Get-Credential alice) -NoNewWindow -Waitrunas /user:alice "cmd /c whoami"Become root with full environment reset
su -su -Start-Process pwsh -Verb RunAsrunas /user:Administrator cmd.exeGotchas
- The `-` (dash) is critical and easy to forget. `su alice` and `su - alice` are different commands: the first keeps YOUR shell's environment (PATH, env vars, possibly even PWD), runs alice's default shell as a non-login process; the second SIMULATES a fresh login (clears env, runs alice's login init, sets HOME to /home/alice). "Why does my script behave differently when I `su alice` than when alice logs in via SSH?" — almost always missing the dash. For matching production behaviour, ALWAYS use `su -`.
- sudo vs su — pick the right tool. `sudo` asks for the CALLER's password and is grant-of-elevation-by-policy (per /etc/sudoers); `su` asks for the TARGET user's password and is identity-switch-by-credential. On systems where root has a disabled password (Ubuntu default, modern macOS) `su` (without `-c`) fails with "Authentication failure" — there's no root password to enter. The Ubuntu way is `sudo -i` (which DOES open a root login shell, equivalent to `su -` but using sudo's auth model). Mixed environments: scripts that assume `su -` works break on Ubuntu/Debian unless root has a password explicitly set with `sudo passwd root`.
- PAM rules differ between sudo and su. `/etc/pam.d/sudo` and `/etc/pam.d/su` are SEPARATE files with potentially different auth modules — `su` typically requires the `wheel` (or `sudo`/`admin`) group membership via `pam_wheel.so`; sudo uses `/etc/sudoers` for the same. Locking down one without the other is a common audit finding. CIS Benchmark Linux 5.2.5: "Ensure use of su is restricted to wheel group" — uncomment `auth required pam_wheel.so use_uid` in `/etc/pam.d/su`.
- Windows runas with NETWORK credentials — when alice's account is a domain account but you're running on a non-domain-joined machine: `runas /netonly /user:DOMAIN\alice cmd.exe` uses alice's credentials ONLY for NETWORK access (file shares, SQL Server), local commands still run as YOU. Useful for cross-domain admin tasks; confusing if not expected (`whoami` shows your local user, but `Test-Path \\server\share` succeeds because the network leg used alice).
- `su` in containers — most container images don't have `su` installed (BusyBox provides it, but `apt install`-based images often strip it). The container best-practice is "run as a non-root USER from the start" via the Dockerfile `USER alice` directive — using `su` inside a running container is usually a sign of an anti-pattern. If you genuinely need it (debugging, dev containers): `docker exec -u alice -it CONTAINER bash` or `kubectl exec -it POD -- su - alice` works WITHOUT needing su to be installed inside the container.