Verified against Proxmox VE 9.2.4 · Proxmox Backup Server 4.2.5 · Ceph Squid / Tentacle · Debian 13 (Trixie) · Linux kernel 7.0 (PVE 9.2 default) · 2026-08-12
○Not yet marked complete on this device.
A Proxmox node ships roughly fifteen command-line tools, and the design
is more consistent than it first appears: each tool owns one area of
the system, and its name tells you which. Learning the map is worth
more than memorising any individual command, because with the map you can
find the command you need and without it you cannot.
The other thing worth knowing up front is that almost none of these tools
do the work themselves. They are clients of the same REST API the web
interface uses. That has practical consequences — for permissions, for
what appears in the task log, and for what a script should call — and the
mechanism section at the end covers them.
The map
Tool
Owns
Scope
qm
QEMU/KVM virtual machines
This node’s guests
pct
LXC containers
This node’s guests
pvesm
Storage definitions and volumes
Cluster-wide config, node-local status
pvesh
The API itself, as a shell
Anything the API exposes
pvecm
Cluster membership and quorum
Cluster-wide
pveum
Users, groups, roles, ACLs, API tokens
Cluster-wide
pveceph
Ceph deployment and lifecycle
Cluster-wide
pvenode
Node-level operations, tasks, certificates
This node
ha-manager
HA resources, groups and CRM commands
Cluster-wide
pvesr
Storage replication jobs (ZFS)
Cluster-wide config
vzdump
Taking backups
This node’s guests
qmrestore
Restoring a VM backup
This node
pvesubscription
Subscription key and repository entitlement
This node
pveperf
A quick node benchmark
This node
pvereport
Evidence collection for support
This node
proxmox-boot-tool
The ESP, bootloader and kernel entries
This node
pveversion
Package versions
This node
The scope column is the one that catches people. qm and pct act on
guests on the node you are logged into; pveum and pvecm change
state that every node sees immediately. Running the wrong one on the
wrong node is the difference between a mistake and an incident.
qm — virtual machines
Read-only / Safewhat VMs are on this node, and what is one of them made of?— Read-only. qm list covers this node only; for a cluster-wide view use pvesh get /cluster/resources. qm config shows the configuration as stored, including any pending changes.
qm list
VMID=100
qm config "$VMID"
qm status "$VMID" --verbose
Read-only / Safeqm list, and what the columns mean— Illustrative. MEM is the configured memory in MiB, not what the guest is using. BOOTDISK is the primary disk size. PID is the QEMU process, and its absence is how you tell 'stopped' from 'the process died'.
The two qm subcommands that repay learning early are less obvious than
start and stop.
Read-only / Safewhat QEMU command line does this configuration produce?— Read-only. showcmd renders the exact qemu-system invocation PVE would use. It is the fastest way to answer 'is this option actually taking effect' and the first thing to attach to a bug report.
VMID=100
qm showcmd "$VMID" --pretty
Read-only / Safeqm showcmd tells you what PVE really did with your config— Illustrative and abridged. Reading this is how you confirm that iothread, aio and cache settings reached QEMU rather than being silently ignored.
Read-only / Safewhich disks does this VM own, and where do they live?— Read-only. Answers the question that precedes every storage migration and every 'can I delete this volume' decision.
pct mirrors qm deliberately: list, config, start, stop,
shutdown, status, set, destroy all behave the same way. Three
subcommands have no qm equivalent because they exploit the fact that a
container shares the host kernel.
Read-only / Safeget inside a container, and move files without a network— Read-only in the sense that these commands do not themselves change state, but pct enter gives you a root shell inside the container, from which anything is possible. There is no equivalent for a VM because a VM has its own kernel.
CTID=205
pct list
pct config "$CTID"
# a root shell inside, no SSH and no network required
pct enter "$CTID"
Configuration changecopy a file in or out without networking— Writes a file into or out of the container filesystem from the host. Useful precisely when the container's network is broken, which is when you most need it.
Read-only / Safewhat storage exists, is it up, and what is on it?— Read-only. status is the first command in any storage incident: it shows each storage's type, whether it is active, and its usage.
pvesm status
pvesm list local-zfs
pvesm path local-zfs:vm-100-disk-0
Read-only / Safepvesm status, and the column that matters— Illustrative. Active 0 on a storage that should be up is the finding — it means the node cannot reach the backend right now, which is a different problem from the storage being full.
# pvesm status
Name Type Status Total Used Available %
backup-pbs pbs active 41943040000 18294419456 23648620544 43.62%
ceph-rbd rbd active 8796093022 3221225472 5574867550 36.62%
local dir active 98564608 14203392 79322112 14.41%
local-zfs zfspool active 1717986918 412316860 1305670058 24.00%
nfs-iso nfs inactive 0 0 0 0.00%
Illustrative output
Storage entries have a content type — images, rootdir, vztmpl,
iso, backup, snippets, import — and a storage only accepts the
types it declares. The documentation defines them as: images for
“QEMU/KVM VM images”, rootdir to “allow to store container data”,
vztmpl for “container templates”, backup for “backup files
(vzdump)”, iso for “ISO images”, snippets for “snippet files, for
example guest hook scripts”, and import for “OVAs and VM disk images
that can be imported from this storage”.
pvesh — the API as a shell
pvesh is “a shell interface for the Proxmox VE API” that, in the man
page’s words, “allows to directly invoke API function, without using the
REST/HTTPS server”. Five subcommands map onto HTTP methods:
pvesh
HTTP
Use
get
GET
Read
set
PUT
Modify an existing object
create
POST
Create, or invoke an action
delete
DELETE
Remove
ls
—
List child nodes of a path
usage
—
Print the API documentation for a path
Read-only / Safeexplore the API without leaving the shell— Read-only. ls walks the tree; usage prints the parameters a path accepts, which is faster than the online API viewer and is guaranteed to match the version installed on this node.
pvesh ls /nodes
pvesh ls /cluster
pvesh usage /nodes/{node}/qemu/{vmid}/status/start --verbose
Read-only / Safethe single most useful pvesh call— Read-only. /cluster/resources is the cluster-wide inventory: every guest, storage and node, with status and usage, from any node. This is the one to reach for when qm list only shows you one node's worth.
pvesh get /cluster/resources --type vm --output-format json | jq -r \
'.[] | [.vmid, .name, .node, .status] | @tsv'
Read-only / Safeevery guest in the cluster, and where it is— Illustrative. The node column is what makes this different from qm list: it answers 'where is VM 141 right now', which after an HA failover is not a question you can answer from any single node.
# pvesh get /cluster/resources --type vm --output-format json | jq -r '.[] | [.vmid, .name, .node, .status] | @tsv'
--output-format accepts json, json-pretty, text and yaml, with
text as the default. Scripts should always pass json: the text
format is a human-readable table whose columns can change between
versions, and parsing it is how automation breaks at an upgrade.
pvecm — cluster membership
Read-only / Safeis this node in the cluster, and does the cluster have quorum?— Read-only. status is the first command in any cluster incident. The Quorate line is the one that determines whether /etc/pve is writable.
pvecm status
pvecm nodes
Read-only / Safepvecm status on a healthy three-node cluster— Illustrative. Expected votes 3, Total votes 3, Quorate Yes. If Total votes drops below Quorum, /etc/pve goes read-only and no guest configuration can be changed anywhere.
# pvecm status
Cluster information
-------------------
Name: pve-prod
Config Version: 7
Transport: knet
Secure auth: on
Quorum information
------------------
Date: Wed Aug 12 14:31:08 2026
Quorum provider: corosync_votequorum
Nodes: 3
Node ID: 0x00000001
Ring ID: 1.4f2
Quorate: Yes
Votequorum information
----------------------
Expected votes: 3
Highest expected: 3
Total votes: 3
Quorum: 2
Flags: Quorate
Illustrative output
pveum — access control
Read-only / Safewho has access to what?— Read-only. The ACL list is the authoritative answer to 'who can do this', and it is worth reading before granting anything, because permissions inherit down the path tree.
pveum user list
pveum role list
pveum acl list
pveum token list root@pam
Configuration changecreate a scoped automation identity— Creates a user, a token with privilege separation, and an ACL limited to one path. privsep 1 means the token carries only the permissions granted to the token itself, not the user's. The secret is printed once and cannot be retrieved again.
pveum user add automation@pve --comment "CI pipeline"
pveum acl modify /vms/100 --users automation@pve --roles PVEVMAdmin
pveum user token add automation@pve ci --privsep 1
pveum acl list
pvenode — the node itself
pvenode is the tool most operators discover last and then use daily,
because it owns the task log.
Read-only / Safewhat has this node been doing?— Read-only. task list is the node's history: every backup, migration, start, stop and snapshot, with its UPID and exit status. This is where you look after 'something happened last night'.
pvenode task list --limit 20
pvenode config get
pvenode cert info
Read-only / Safepvenode task list, with a failure in it— Illustrative. The Status column is the whole point: OK for success, anything else is the error string. Copy the UPID and feed it to pvenode task log for the full output.
# pvenode task list --limit 6
UPID Type Status
UPID:pve-01:00006A2F:04C1B2E1:6A7C83E0:vzdump:100:root@pam: vzdump OK
UPID:pve-01:00006B41:04C2F011:6A7BD3F1:vzdump:101:root@pam: vzdump OK
UPID:pve-01:00006C88:04C41A02:6A7BD3A3:vzdump:141:root@pam: vzdump job errors
UPID:pve-01:00007012:04C88811:6A7C2A18:qmigrate:102:root@pam: qmigrate OK
UPID:pve-01:000071A0:04C9C401:6A7C3B04:qmstart:150:root@pam: qmstart OK
UPID:pve-01:00007244:04CA1180:6A7C4D90:qmsnapshot:100:root@pam: qmsnapshot OK
Illustrative output
Service impact possiblebulk guest operations for a maintenance window— migrateall moves every guest off this node to the named target; startall and stopall act on every guest on this node. These are the correct tools for draining a node, and they respect each guest's startup order and delay.
Read-only / Safewhat is HA managing, and what does the CRM think?— Read-only. status shows the master, each node's LRM state, and every managed resource with its current and requested state. A node in 'wait_for_agent_lock' is the usual sign of trouble.
ha-manager status
ha-manager config
Read-only / Safereplication and Ceph status— Read-only. pvesr status shows each ZFS replication job's last run and next run; pveceph status is the PVE-flavoured wrapper around ceph -s.
pvesr status
pvesr list
pveceph status
pveceph pool ls
Backup, restore and evidence
Service impact possibletake a backup by hand— Runs a backup immediately rather than on a schedule. Snapshot mode is the least disruptive; the guest keeps running. bwlimit is in KiB/s and is the control that stops a manual backup saturating shared storage.
Destructiverestore a VM from a backup— Restoring onto an existing VMID overwrites that VM entirely, including its disks. Restore to an unused VMID first and verify, unless you have specifically decided to overwrite.
Read-only / Safecollect everything at once for a support case— Read-only. pvereport gathers versions, storage, network, cluster, disk and guest configuration into one stream. Redirect it to a file. It is the single most useful command to run before opening a ticket, and it is worth running while a node is still misbehaving rather than after a reboot.
Read-only / Safeversions, subscription and boot configuration— Read-only. pveversion -v is what every forum answer will ask you for. proxmox-boot-tool status tells you which bootloader the node uses, which decides where kernel command-line changes go.
pveversion -v
pvesubscription get
proxmox-boot-tool status
Which tool answers which question?
The question
The command
What is on this node?
qm list, pct list
Where in the cluster is guest N?
pvesh get /cluster/resources --type vm
Why did last night’s backup fail?
pvenode task list, then pvenode task log UPID
Is the cluster quorate?
pvecm status
Is the storage reachable?
pvesm status
What can this user actually do?
pveum acl list
Did my disk option reach QEMU?
qm showcmd VMID --pretty
What is HA about to do?
ha-manager status
What do I attach to a support case?
pvereport, pveversion -v
Where do kernel parameters go on this node?
proxmox-boot-tool status
What parameters does this API path take?
pvesh usage PATH --verbose
Common mistakes
Treating qm list as a cluster view. It shows one node.
pvesh get /cluster/resources --type vm is the cluster inventory.
Parsing pvesh text output in a script. It is a human table.
Always pass --output-format json.
Using qm stop when qm shutdown was meant.stop is the power
cable; shutdown sends ACPI and lets the guest flush its filesystems.
pvesm set --content without listing every type you want. The
option replaces the list; omitting a type removes it.
Reaching for pvecm expected 1 during a quorum loss. It is a
recovery tool for nodes you have confirmed are powered off, not a first
response to a partition.
Restoring onto an existing VMID.qmrestore overwrites it,
including disks, without a prompt.
Running pvereport after rebooting the node. Collect the evidence
while the fault is present.
Not knowing which bootloader the node uses.proxmox-boot-tool status answers it; guessing means editing a file
nothing reads.
Key takeaways
Each tool owns one area, and its name says which. Learn the map, not
the commands.
qm and pct are node-scoped; pvecm, pveum, pveceph and
ha-manager change cluster-wide state that propagates immediately.
pvesh is the API as a shell, with get/set/create/delete
mapping to GET/PUT/POST/DELETE, plus ls and usage for exploring.
pvesh get /cluster/resources is the cluster-wide inventory that
qm list is not.
pvenode task list and pvenode task log are where you find out what
happened overnight.
Storage entries declare content types; “does not support content type”
is configuration, not a bug, and pvesm set --content replaces the
list rather than appending to it.
pvereport collects everything a support case needs, and should be run
while the fault is still present.
Every pve* tool is a client of the same API with the same permission
checks, so scripts should call documented API paths with JSON output
rather than parse human-formatted tables.
Knowledge check
Knowledge check · 5 questions
Q1. After an HA failover you need to know which node VM 141 is running on, from a shell on pve-01. Which command answers it?
Q2. Which of these commands change state that every node in the cluster sees immediately? Select all that apply.
Q3. pvesh talks to the API without going through the REST/HTTPS server, so it also bypasses the API permission checks and always runs with full privileges.
Q4. A vzdump job fails with an error saying the storage does not support content type "backup". What is the fix?
Q5. Why should a durable automation script call pvesh with --output-format json rather than parsing the default output?
Passing score: 75%. Answers are checked in this browser.