Proxmox VEXXVI · Windows GuestsGetting Windows onto the hypervisor
VirtIO drivers, the guest agent and the balloon service
What you'll learn
- Enumerate the components on the virtio-win ISO and the PVE device each one drives
- Install the driver set, the QEMU guest agent and the balloon service by the correct mechanism for each
- Explain why the balloon service is a separate installation step from the balloon driver
- Diagnose a half-installed driver set from the host, without a console session
- Decide what a missing component actually costs before scheduling a reboot to fix it
Prerequisites
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
“Install the VirtIO drivers” is one instruction in every Windows-on-Proxmox guide, and it hides three separate installations with three separate mechanisms, three separate failure symptoms, and one of them not being a driver at all.
That is why the most common state of a Windows guest in a real estate is not “drivers installed” or “drivers missing”. It is partly done — storage on VirtIO because setup demanded it, network on VirtIO because someone noticed the NIC was slow, no guest agent, no balloon service, and a Proxmox summary page reporting memory figures that nobody trusts.
This lesson makes that state diagnosable.
What is actually on the ISO
The virtio-win ISO is organised by component, then by Windows version, then by
architecture. The Proxmox wiki names the directories you will meet: Balloon,
NetKVM, vioscsi, QXL and guest-agent, each containing subdirectories per
Windows release — w10, 2k19, 2k22, 2k25 and older — and an amd64
directory inside those.
The components that matter operationally, and the PVE configuration that creates the device each one claims:
| Component | Directory | Device it drives | Created by | Symptom when missing |
|---|---|---|---|---|
| VirtIO SCSI | vioscsi | Red Hat VirtIO SCSI pass-through controller | scsihw: virtio-scsi-single | Disks do not enumerate at all; setup shows no drives |
| VirtIO Block | viostor | Red Hat VirtIO block device | a disk on the virtio0 bus | Same, for the older block transport |
| Network | NetKVM | Redhat VirtIO Ethernet Adapter | net0: virtio,... | No NIC; an unknown Ethernet controller in Device Manager |
| Balloon | Balloon | VirtIO Balloon Driver | present unless balloon: 0 | Unknown PCI device; no memory reclaim |
| Serial | vioserial | VirtIO Serial Driver | agent: enabled=1 | Guest agent installs but never answers |
| Display | QXL | QXL video | vga: qxl | Basic display adapter, low resolutions |
| Guest agent | guest-agent | not a driver — a service | agent: enabled=1 | qm agent ping times out |
Two rows in that table are the ones people skip, and they are the two that are
not drivers you can see failing. vioserial is invisible because nothing looks
broken without it; guest-agent is invisible because it is a service, not a
device, so Device Manager has nothing to complain about.
The three mechanisms
One: the driver bundle
The wiki gives the straightforward path: execute virtio-win-gt-x64 from the
CD-ROM and follow the prompts, then reboot. The same content is available as a
downloadable virtio-win-gt-x64.msi (or virtio-win-gt-x86.msi for 32-bit) if
you would rather pull it inside the guest than mount the ISO.
The manual alternative is per-driver: navigate to the directory matching your
Windows version, right-click the Setup Information file, choose Install,
repeat for each driver, reboot. It exists for the cases where the bundle is not
appropriate — a locked-down image, an unattended build that installs specific
.inf files, or a guest where you deliberately want the storage and network
drivers and nothing else.
Two: the guest agent
The agent is not in the driver bundle by default and it needs two things the
bundle does not necessarily give it. The wiki is explicit about the order:
download the VirtIO ISO, install the virtio-serial driver via Device
Manager, then run the installer — qemu-ga-x86_64.msi for 64-bit or
qemu-ga-i386.msi for 32-bit — from the mounted ISO. The service that results
is named QEMU-GA.
There is also virtio-win-guest-tools, a wizard the wiki describes as
optionally installing the QEMU Guest Agent and the SPICE agent alongside the
drivers. On a fresh build that is the one-step path.
The third requirement is on the host, not in the guest: the VM must have the
agent enabled, qm set VMID --agent 1. All three are required and each fails
differently, which is what makes agent problems feel mysterious.
Three: the balloon service
This is the one that is genuinely a separate component, and the Proxmox wiki states it in one sentence:
You need to install the VirtIO Balloon Driver and the management service (
blnsvr.exe -i).
Read that as two objects. The driver is a kernel-mode driver for the virtio-balloon PCI device; it is what allows the host to inflate and deflate the balloon and reclaim memory. The service is a user-mode Windows service that reports the guest memory statistics back through the same device.
Since virtio-win-0.1.173-2 the wiki notes that the ISO provides an installer at
the root of the CD drive — virtio-win-gt-x64.msi — which can install the
ballooning service for Windows Server 2012, Windows 8.1 and newer, so on a
current guest the MSI usually covers it. On older guests, and on any guest where
the driver went in by hand from Device Manager, the service does not exist until
somebody runs blnsvr.exe -i from an elevated prompt.
Installing, in order
Run these inside the guest, from an elevated command prompt, with the VirtIO ISO mounted. Adjust the drive letter and the Windows version directory.
# 1. Drivers, plus the ballooning service on 2012/8.1 and newer
Start-Process msiexec.exe -Wait -ArgumentList '/i D:\virtio-win-gt-x64.msi /qn /norestart'
# 2. QEMU guest agent
Start-Process msiexec.exe -Wait -ArgumentList '/i D:\guest-agent\qemu-ga-x86_64.msi /qn /norestart'
# 3. Balloon service, if the MSI did not install it
Get-Service BlnSvr -ErrorAction SilentlyContinue
Restart-ComputerThen, on the host, make sure the VM side is enabled — this is configuration on the hypervisor and has no effect inside the guest until the agent is running:
VMID=9100
qm set "$VMID" --agent enabled=1,fstrim_cloned_disks=1
qm config "$VMID" | grep '^agent:'fstrim_cloned_disks=1 asks the agent to run a filesystem trim after a disk
move or a clone, which matters on thin-provisioned and ZFS-backed storage.
Part IX covers the rest of the sub-options; the defaults are documented as
enabled: 0, fstrim_cloned_disks: 0, freeze-fs: 1 and type: virtio.
Diagnosing a half-installed set from the host
This is the part worth keeping. You can determine most of a Windows guest driver state from the hypervisor, without a console session and without RDP, which means you can audit an estate rather than inspecting a machine.
# qm agent 9100 ping && echo "agent responding"agent respondingIllustrative output
qm agent is documented as an alias for qm guest cmd, and the allowed command
set is fixed: ping, info, get-osinfo, get-host-name, get-time,
get-timezone, get-users, get-vcpus, get-fsinfo,
network-get-interfaces, get-memory-blocks, get-memory-block-info,
fsfreeze-freeze, fsfreeze-thaw, fsfreeze-status, fstrim, shutdown,
suspend-ram, suspend-disk and suspend-hybrid. Four of them answer driver
questions.
Is the network driver bound and configured?
# qm agent 9100 network-get-interfaces[
{
"hardware-address" : "bc:24:11:3a:00:1f",
"ip-addresses" : [
{
"ip-address" : "192.0.2.51",
"ip-address-type" : "ipv4",
"prefix" : 24
}
],
"name" : "Ethernet",
"statistics" : { "rx-bytes" : 918273645, "tx-bytes" : 273645918 }
},
{
"hardware-address" : "00:00:00:00:00:00",
"ip-addresses" : [
{
"ip-address" : "127.0.0.1",
"ip-address-type" : "ipv4",
"prefix" : 8
}
],
"name" : "Loopback Pseudo-Interface 1"
}
]Illustrative output
An interface named Ethernet carrying the MAC from net0 means NetKVM is
bound. A guest that answers ping but returns only the loopback interface has
an agent and no working NIC — which is a diagnosis, and a specific one.
What is the guest, and does it match what PVE thinks it is?
# qm agent 9100 get-osinfo{
"id" : "mswindows",
"kernel-release" : "26100",
"kernel-version" : "10.0",
"machine" : "x86_64",
"name" : "Microsoft Windows",
"pretty-name" : "Windows Server 2025 Standard",
"version" : "Microsoft Windows Server",
"version-id" : "2025"
}Illustrative output
Use this to audit ostype. A fleet-wide sweep that compares what each guest
says it is against what its configuration claims will find the Server 2022 guest
somebody created as ostype: other in 2024.
Is the clock right? qm agent VMID get-time returns nanoseconds since the
epoch as the guest sees it. Compare it to the host. Lesson 6 explains what a
drifting Windows clock costs; this is how you measure it cheaply across an
estate.
for VMID in $(qm list | awk '$3 == "running" { print $1 }'); do
if qm agent "$VMID" ping >/dev/null 2>&1; then
NAME=$(qm agent "$VMID" get-osinfo 2>/dev/null | grep -o '"pretty-name" : "[^"]*"' | cut -d'"' -f4)
printf '%-6s OK %s\n' "$VMID" "${NAME:-unknown}"
else
printf '%-6s NO-AGENT\n' "$VMID"
fi
doneRun that once against a real estate and the result is usually uncomfortable. It is also the first honest inventory of Windows guest tooling most estates have had.
Key takeaways
- The virtio-win ISO carries drivers, a guest agent and a balloon service, and they install by three different mechanisms.
- The balloon driver enables memory reclaim. The balloon service
(
blnsvr.exe -i) enables memory reporting. Without the service, the Proxmox GUI reports something close to the allocation, and the correct end state is that the GUI figure matches Windows Task Manager. - The guest agent needs three things:
agent: enabled=1on the VM, the virtio-serial driver in the guest, and the QEMU-GA service running. All three fail as the same timeout. qm agent VMID network-get-interfaces,get-osinfoandget-timelet you audit driver state,ostypecorrectness and clock drift across an estate from the host.- On an imported guest, remove the old hypervisor tooling first, install VirtIO drivers second, and change the NIC model third — with console access and the IP configuration written down.
- Missing components have very different costs. The agent and the balloon service are the two usually worth a maintenance window.
Knowledge check
Knowledge check · 4 questions
Q1. A Windows guest with 16 GiB assigned reports 15.8 GiB used on the Proxmox summary page, while Task Manager inside the guest shows 4 GiB. The balloon driver is present in Device Manager. What is the correct conclusion?
Q2. qm agent 9100 ping times out on a Windows guest. Which of these are genuine possible causes? Select all that apply.
Q3. A Windows guest imported from VMware boots fine on VirtIO storage but still has an e1000 NIC and VMware Tools installed. What is the correct order of operations?
Q4. Installing only the VirtIO balloon driver, without the management service, means the host cannot reclaim memory from the guest at all.
Passing score: 75%. Answers are checked in this browser.