VMware to Proxmox Migration: A Working Procedure With PowerCLI Export

The Broadcom renewal quote is what brings shops here. A three-host environment that used to pay $3,000 a year in support can be staring at $9,720 a year for VVF if the renewal lands under the 72-core minimum, and the math stops working. Proxmox VE is the first alternative I would evaluate for this size of shop. The migration itself is less painful than the licensing conversation that preceded it, but less painful is not the same as painless, and the places it hurts are predictable if you know where to look.

This is the procedure I run when moving VMs off ESXi onto Proxmox VE 9.0. It uses PowerCLI on the source side to export disks cleanly and Proxmox on the target side to import them. Which of the two paths through this you take depends on whether your ESXi host is still reachable over the network when you do the move.

What you are actually moving

A VMware VM is three things: a config file (.vmx), one or more disks (.vmdk), and a network identity. Proxmox does not care about your .vmx file. It generates its own config from scratch when you create the target VM. The disks are the only payload that has to physically cross the boundary, and they are also the only part that can corrupt if you rush it.

Network identity is where people lose time. ESXi VMs run VMware Paravirtual SCSI controllers and E1000 or VMXNET3 NICs. Proxmox speaks VirtIO SCSI and VirtIO Net. Linux guests re-detect hardware on first boot and survive the swap in most cases. Windows guests do not, and that problem gets its own section below.

Two paths: the import wizard versus manual export

Proxmox VE 8.2 added the ESXi import wizard through the web UI, backed by the pve-esxi-import-tools package. It connects Proxmox directly to your ESXi host, lists the VMs, and pulls disks across with automatic VMDK-to-QCOW2 conversion. If your ESXi host is powered on and reachable from the Proxmox node, this is the faster path and the one Proxmox documents first.

You take the manual path when the ESXi host is already powered down, when you are migrating from cold storage or a backup archive, or when the import wizard chokes on a specific VM. The manual path is also what you want if you need an auditable export artifact, an OVA you can re-import to VMware later as a rollback. Manual export works regardless of host state, and PowerCLI export is the part many migration notes skip.

Step 1: Inventory and export with PowerCLI

Connect to vCenter and get a clean inventory before you touch anything. You need to know which VMs have snapshots, because a VM with snapshots exports as a chain of delta files and the base disk alone is not a valid standalone VMDK.

Connect-VIServer -Server vcenter.yourdomain.local

# Snapshot check — do not export VMs with active snapshots
Get-VM | Where-Object { $_.ExtensionData.Snapshot -ne $null } |
    Select-Object Name, PowerState |
    Format-Table -AutoSize

# Consolidate or commit snapshots first, then re-run the check

Do not export VMs with active snapshots. Consolidate first so the exported VMDK is a clean standalone disk, not a delta-chain surprise discovered during import. I have watched someone lose four hours to this because the export "completed" and the imported VM would not boot.

With the snapshot list empty, export the VM to OVA, which is a single tarball and easier to move than the loose OVF folder:

$vm = Get-VM -Name "app-server-01"
$exportPath = "D:\migrations\app-server-01"

# Export-VApp writes to the machine running PowerCLI, not the vCenter
Export-VApp -VM $vm -Destination $exportPath -Format Ova

Two warnings the cmdlet will not give you. Export-VApp stages the OVA in $env:TEMP on the PowerCLI host before writing the final file, so the temp drive needs free space equal to roughly twice the VM's provisioned disk size. A 12 TB VM ate someone's C: drive this way; point $env:TEMP at a volume with room before you run the export. Second, the VM does not need to be powered off to export, but a powered-on export captures the disk in a crash-consistent state. Shut the VM down first unless you have a specific reason not to.

For environments where you want to script the whole estate, this loops every VM into its own OVA:

$targets = Get-VM | Where-Object {
    $_.ExtensionData.Snapshot -eq $null -and $_.PowerState -eq "PoweredOff"
}

foreach ($vm in $targets) {
    $safe = "{0}-{1}" -f ($vm.Name -replace '[^\w\-]', '_'), $vm.Id.Split('-')[-1]
    Export-VApp -VM $vm -Destination "D:\migrations\$safe" -Format Ova
}

The character replacement matters. Proxmox VM names tolerate a smaller character set than vCenter, and spaces or parentheses in the source name will bite you later in the shell.

Step 2: Stage the disks on the Proxmox node

Move the OVA to the Proxmox node by SCP or a staging share. Extract the tarball to get at the VMDK inside:

mkdir -p /mnt/staging/app-server-01
tar -xvf /mnt/staging/app-server-01.ova -C /mnt/staging/app-server-01

You are left with a .ovf descriptor and one or more .vmdk files. The descriptor is readable text; open it once to confirm the disk format. ESXi exports thick-provisioned VMDKs by default, and qm importdisk handles those directly without a separate qemu-img convert step. Run the convert step only if you need a target format the importer will not produce on its own.

If the staging volume and the Proxmox VM disk storage share the same physical disk, you need free space equal to roughly twice the VM size during import, because the VMDK is read while Proxmox writes the target disk. On directory storage that may be QCOW2; on ZFS it is usually a zvol. Compression may soften this, but check zfs list and df -h before starting a 500 GB import on a 600 GB pool.

For moving the OVA offsite or to a colocation cabinet, a fast external SSD is worth the money. A USB 3.2 SSD is enough for small migrations; a Samsung T7-class drive keeps a 500 GB transfer from turning into a spinning-disk wait.

Step 3: Create the target VM and import the disk

Create the target VM in Proxmox first, without a disk. Match CPU count and memory, and pick VirtIO SCSI for the disk controller even though there is no disk yet. Note the VM ID, 102 in this example.

qm importdisk 102 /mnt/staging/app-server-01/app-server-01-disk0.vmdk local-zfs

local-zfs is the storage pool name from pvesm status. The import attaches the disk as an unused disk on VM 102. Open VM 102 in the Proxmox web UI, find the unused disk under Hardware, and attach it to the SCSI bus with the VirtIO SCSI controller. Set it as the boot device under Options, Boot Order.

For Linux guests, this is enough. Power on the VM. The guest re-detects the disk controller, the network card shows up as a new interface, and you log in via the Proxmox console to fix /etc/netplan or /etc/sysconfig/network-scripts for the new MAC. Downtime for a small Linux VM, from ESXi shutdown to Proxmox boot, is the disk transfer time plus five minutes.

For a batch migration where you want the commands in one place, this is the full sequence after the OVA is extracted:

VMID=102
STORAGE=local-zfs
qm create $VMID --name app-server-01 --memory 8192 --cores 4 --ostype l26
qm set $VMID --scsihw virtio-scsi-pci --scsi0 ${STORAGE}:0,import-from=/mnt/staging/app-server-01/app-server-01-disk0.vmdk
qm set $VMID --net0 virtio,bridge=vmbr0
qm set $VMID --boot order=scsi0

The import-from parameter on the disk definition handles the conversion inline, no separate importdisk call needed. This is the cleaner path on PVE 8.4 and later.

The Windows boot problem

Windows VMs commonly fail with INACCESSIBLE_BOOT_DEVICE when the boot disk moves from VMware PVSCSI to VirtIO SCSI without the VirtIO driver loaded first. The cause is that the Windows boot driver for the VMware Paravirtual SCSI controller loads at boot, and when the disk is suddenly on a VirtIO SCSI controller Windows has no driver for, the boot partition vanishes.

The fix, documented by StarWind and on the Proxmox forums, is to stage the VirtIO storage drivers in Windows before migration or plan a SATA-first boot in Proxmox. Download the stable VirtIO ISO from Fedora People and place the storage, network, and Balloon drivers where Windows can load them after cutover. If that is not reliable in the source environment, import the VM, attach the boot disk as SATA for the first Proxmox boot, install VirtIO drivers from the ISO, shut down, then move the disk to VirtIO SCSI.

Then shut down, export, and import. If the VM is already failing to boot, temporarily attach the disk to IDE or SATA instead of SCSI, boot Windows, install the VirtIO drivers, shut down, move the disk to the VirtIO SCSI bus, and reboot. It works but costs an extra cycle.

Uninstall VMware Tools before the first Proxmox boot. Leftover Tools services cause hangs and the VMware network adapter shows up as a phantom device in Device Manager.

Networking translation

VMXNET3 maps cleanly to VirtIO Net. E1000 can also be replaced with VirtIO Net, but E1000 is emulated hardware, not paravirtualized. The guest-visible MAC address and interface name change either way, which means DHCP leases break and anything pinned to a MAC, such as VMware reservations, switch port security, or monitoring, needs to be re-pinned.

If your VMware environment used VLAN trunking on a distributed switch, the Proxmox equivalent is a Linux bridge with VLAN awareness enabled, or a separate bridge per VLAN. For the migration window, a managed switch that can present the same VLANs to the Proxmox node saves re-cabling. A low-cost option like a TP-Link Omada managed switch handles VLAN trunking for a small rack without the enterprise price.

Proxmox has no direct equivalent to VMware's distributed switch. Multi-host clusters use Corosync for cluster communication, and bridge configuration is per-node, synchronized through the cluster filesystem. It works, but the mental model is different, and network engineers used to dvSwitches should expect a short adjustment.

What it costs to land here

Proxmox VE is AGPL-licensed and free to run with no feature gating. The optional subscription buys access to the Enterprise repository and support, and is priced per occupied CPU socket per year. 2026 list prices, from Proxmox's pricing page and resellers, run approximately €355 per socket for Basic, €500 for Standard, and €1,060 for Premium. No per-core meter, no 72-core order minimum. The Community repository is free but Proxmox displays a nag on login if no subscription key is installed, which is cosmetic.

Against VVF at the $135/core/year average list figure, a new order or subscription transition subject to the 72-core minimum would cost a three-host cluster of single-socket 16-core servers $9,720 a year with Broadcom and roughly €1,065 to €3,180 a year to Proxmox for the same three sockets, depending on tier. The math is what drives the migration, and it is not close. Verify current Proxmox and VMware list prices before quoting internally; reseller pricing in euros, dollar conversion, VMware term length, and Broadcom discounts all move the final number.

For a structured reference on the Proxmox side, Proxmox VE Administration covers clustering, storage, and backup in more depth than the wiki. It earns shelf space if Proxmox becomes the platform of record.

Where this procedure fails

The import path breaks in three places I have personally hit. Thin-provisioned source disks that were never consolidated import at their full provisioned size on the Proxmox side, which can blow up a pool sized for actual usage. Run Get-HardDisk -DiskType Thin and check the committed versus uncommitted values before you plan storage. Shared-disk VMs using VMware's physical or virtual RDM do not migrate through this path at all; they need a storage-level migration or re-architecture. And VMs with NVMe controllers or passthrough devices in ESXi require reconfiguration on the Proxmox side, because the device paths and passthrough mechanics are different.

Rollback during the migration window is clean as long as you keep the source VM powered off and unmodified in ESXi until you have validated the Proxmox copy. The moment you power on and modify the Proxmox VM, the two diverge, and rolling back means losing whatever changed since cutover. Plan the validation window in advance, decide what success looks like, then decommission the source.

Stay ahead of the VMware changes

We're publishing detailed licensing breakdowns, comparison guides, migration walkthroughs, and cost calculators. Get them in your inbox.