Create VM using vmcli.exe and vmrun.exe

Documentation for vmcli.exe and vmrun.exe are poor. I did a lot of trial-and-error to figure out the commands.

Here is a sample PowerShell script to create a new VM in VMware Workstation, attach existing virtual hard disks, and configure settings like CPU, RAM, NIC, CD-ROM, display resolution, and shared folder.

I ended up figuring out how to set the parameters by creating a VM in VMware Workstation UI first, then examining the generated .vmx file to see what parameters are set.

# Description: Create a new VM in VMware Workstation using vmcli.exe and vmrun.exe.
#   .\vmware-next.ps1 debian.iso

param (
    [Parameter(Mandatory)]          [String] $ISOfile,
)

# Declare variables.
    $vm_name = "next-64bit"
    $vm_cpus = 2
    $vm_ram = (12*1024)

    $vm_dir = [IO.Path]::Combine("${env:VMWARE_OS}", "${vm_name}");
    $vm_wmdk_file = [IO.Path]::Combine("${vm_dir}", "${vm_name}.vmdk");
    $vm_vmx_file = [IO.Path]::Combine("${vm_dir}", "${vm_name}.vmx");

# Delete existing VM if exists
    Remove-Item -Path $vm_dir -Recurse -Force

# Create VM
    vmcli VM Create -n "$vm_name" -d "$vm_dir" -g "debian12-64"
    vmcli ConfigParams SetEntry displayName "${vm_name}" "${vm_vmx_file}"
    vmcli ConfigParams SetEntry memsize "${vm_ram}" "${vm_vmx_file}"
    vmcli ConfigParams SetEntry numvcpus "${vm_cpus}" "${vm_vmx_file}"

# Turn floppy off: By default VMware Workstation will include a floppy-controller/floppy drive in every new VM
    vmcli ConfigParams SetEntry floppy0.present        "FALSE" "${vm_vmx_file}"
    vmcli ConfigParams SetEntry floppy0.startConnected "FALSE" "${vm_vmx_file}"

# Attach CD drive
    vmcli Sata SetPresent sata0 1 "${vm_vmx_file}"
    vmcli Disk SetBackingInfo sata0:0 cdrom_image "${ISOfile}" 1 "${vm_vmx_file}"
    vmcli Disk SetPresent sata0:0 1 "${vm_vmx_file}"

    # Define boot order: CD-ROM first, then disk
    vmcli ConfigParams SetEntry bios.bootOrder        "cdrom,hdd,floppy,ethernet1"   "${vm_vmx_file}"

# Add all hard drives found as SATA port. $env:VMWARE_HD
    Get-ChildItem -File $env:VMWARE_HD\*.v* -Include "*.vhd" | ForEach-Object {$sata_port=1} {
        $hd_path = $_.FullName
        write-Output "Adding $hd_path to VM on port ${sata_port}."
        vmcli Disk SetBackingInfo sata0:${sata_port} disk "${hd_path}" 1 "${vm_vmx_file}"
        vmcli Disk SetPresent sata0:${sata_port} 1 "${vm_vmx_file}"

        $sata_port++
    }

# Configure NIC0 to use VMnet8 (NAT)
    vmcli ConfigParams SetEntry ethernet0.present        "TRUE"     "${vm_vmx_file}"
    vmcli ConfigParams SetEntry ethernet0.connectionType "nat"      "${vm_vmx_file}"
    vmcli ConfigParams SetEntry ethernet0.vnet           "VMnet8"   "${vm_vmx_file}"
    vmcli ConfigParams SetEntry ethernet0.virtualDev     "e1000"    "${vm_vmx_file}"

# Set display resolution (example: 1920x1080)
    vmcli ConfigParams SetEntry svga.autodetect "FALSE" "${vm_vmx_file}"
    vmcli ConfigParams SetEntry svga.maxWidth    "1920"  "${vm_vmx_file}"
    vmcli ConfigParams SetEntry svga.maxHeight   "1080"  "${vm_vmx_file}"


############ If you don't run the vm, it will not show in VMware Workstation UI ############
vmrun start "$vm_vmx_file"

# Shared folder
    Start-Sleep -Seconds 30
    vmrun -T ws enableSharedFolders "${vm_vmx_file}" "TRUE"
    vmrun -T ws addSharedFolder "${vm_vmx_file}" "shared" ($env:VMWARE_SHARED)