Skip to content

Create a Proxmox VE VM with PowerShell

These scripts create guests. Every value (node, storage, bridge, ISO, template) must exist on your cluster: change them before running. The token needs a role that can create VMs, for example PVEVMAdmin on the pool or path, plus Datastore.AllocateSpace on the storage.

Disks and network interfaces are indexed parameters: a hashtable from the device number to the value the API expects.

$node = 'pve01'
$vmid = (Get-PveClusterNextid).Response.data # first free id
$r = New-PveNodesQemu -Node $node -Vmid $vmid -Name 'web01' `
-Ostype l26 -Cores 2 -Memory 4096 -Cpu host `
-Scsihw virtio-scsi-single `
-ScsiN @{ 0 = 'local-lvm:32,discard=on,iothread=1' } `
-IdeN @{ 2 = 'local:iso/debian-13.1.0-amd64-netinst.iso,media=cdrom' } `
-NetN @{ 0 = 'virtio,bridge=vmbr0,firewall=1' } `
-Agent 'enabled=1' `
-Boot 'order=scsi0;ide2'
if (-not $r.IsSuccessStatusCode) { throw $r.ReasonPhrase }
Wait-PveTaskIsFinish -Upid $r.Response.data -Timeout 120000 | Out-Null

local-lvm:32 asks for a new 32 GiB disk on storage local-lvm: storage:size in GiB, followed by the disk options.

$r = New-PveNodesQemu -Node pve01 -Vmid 130 -Name 'win01' `
-Ostype win11 -Machine q35 -Bios ovmf -Cores 4 -Memory 8192 -Cpu host `
-Efidisk0 'local-lvm:1,efitype=4m,pre-enrolled-keys=1' `
-Tpmstate0 'local-lvm:1,version=v2.0' `
-Scsihw virtio-scsi-single `
-ScsiN @{ 0 = 'local-lvm:80,discard=on,iothread=1' } `
-IdeN @{ 2 = 'local:iso/Win11.iso,media=cdrom'; 3 = 'local:iso/virtio-win.iso,media=cdrom' } `
-NetN @{ 0 = 'virtio,bridge=vmbr0' } `
-Agent 'enabled=1'

-Efidisk0 and -Tpmstate0 are single devices, not indexed: they take a string. The VirtIO drivers ISO on ide3 lets Windows setup see the VirtIO disk and network card.

$r = New-PveNodesLxc -Node pve01 -Vmid 210 -Hostname 'dns01' `
-Ostemplate 'local:vztmpl/debian-13-standard_13.1-2_amd64.tar.zst' `
-Storage local-lvm -Rootfs 'local-lvm:8' `
-Cores 1 -Memory 512 -Swap 512 `
-NetN @{ 0 = 'name=eth0,bridge=vmbr0,ip=dhcp' } `
-Unprivileged $true `
-Password (Read-Host -AsSecureString 'root password') `
-Start $true

-Password is a SecureString, see Parameters. For a static address write ip=192.0.2.10/24,gw=192.0.2.1 in the network value.

Most environments create VMs from a template rather than from an ISO:

$template = Get-PveGuest -VmIdOrName 'debian13-template'
foreach ($name in 'web01', 'web02', 'web03') {
$newid = (Get-PveClusterNextid).Response.data
$r = New-PveNodesQemuClone -Node $template.node -Vmid $template.vmid -Newid $newid -Name $name -Full $true
if (-not (Wait-PveTaskIsFinish -Upid $r.Response.data -Timeout 900000)) { throw "Clone of $name timed out" }
Start-PveGuest -VmIdOrName $newid | Out-Null
}