How to convert VM from Proxmox To VMware

fcarpintero

New Member
Feb 3, 2023
1
0
1
Hi Community,

Is there official documentation on how to convert a VM from Proxmox to VMware and what tools/converters are used that is CLI or a third party product etc.

Regards!
 
OP asked about PVE > ESX, not the other way around.

Not sure if vmware converter can handle it, but qemu-img certainly seems to be the favorite in various blogs.


Blockbridge : Ultra low latency all-NVME shared storage for Proxmox - https://www.blockbridge.com/proxmox
oh sorry.

If you have a file storage , you can use move disk to convert to vmdk. (works also online if you want to reduce downtime).

qm move_disk <vmid> <disk> <filestorage> --format vmdk

ex:

qm move_disk 100 scsi0 myfilestorage --format vmdk
 
I would consider using the GUI. In your VM select the disk and then at the top of the screen you have 'Disk Actions', one of which is to 'move' the disk and you can select vmdk.
 
  • Like
Reactions: ali rafie
To export a qcow2 to VMDK

Bash:
wget https://cdimage.debian.org/images/cloud/bookworm-backports/latest/debian-12-backports-nocloud-amd64.qcow2
qemu-img convert -f qcow2 -O vmdk ./debian-12-backports-nocloud-amd64.qcow2 ./debian-12-backports-nocloud-amd64.vmdk

To export a disk to VMDK (Source: https://www.reddit.com/r/Proxmox/comments/mg44yy/comment/gsrwgcg/)

Bash:
qemu-img convert -f raw -O vmdk /dev/mapper/mylvm-vm-101-disk-1 /outputdir/image.vmdk

Let's import the into a VM (Source: https://forum.proxmox.com/threads/create-a-vm-from-qcow2.136128/post-603253)

Bash:
qm importdisk $VMID ./debian-12-backports-nocloud-amd64.qcow2 $STORAGE_POOL_NAME

Assign the disk to a storage, and edit the boot order to include the drive.

Export back the VM (ZFS)
Bash:
zfs list -t volume
qemu-img convert -f raw -O vmdk /dev/zvol/rpool/data/vm-12005-disk-0 ./my-vm.vmdk
 
or simply use my script:

tell me how it works ;)

Bash:
#!/bin/bash

# proxmox-vm_vmware.sh - Convert Proxmox VM to VMware format
# Author: 0zzy
# Date: 2023-09-10
# Version: 1.0
# License: MIT
#
# Description: This script converts a Proxmox VM to VMware format.
#              It can convert to VMware VMX, OVF, or OVA format.
#              It requires the ovftool command-line tool.
#              It uses the qemu-img command-line tool to convert disks.
#              It uses the jq command-line tool to parse
#
# To use the Script, run the following command:
# chmod +x proxmox-vm_vmware.sh
#
# Then run it with the required VM ID:
# ./proxmox-vm_vmware.sh -i VMID
# Example: ./proxmox-vm_vmware.sh -i 100
#
# Or with additional options:
# ./proxmox-vm_vmware.sh -i 100 -n MyVM -d /path/to/output -f ova


set -e

# Function to display usage information
function show_usage() {
    echo "Usage: $0 -i VMID [-n VM_NAME] [-d DESTINATION] [-f FORMAT]"
    echo
    echo "Options:"
    echo "  -i VMID         Proxmox VM ID to convert"
    echo "  -n VM_NAME      Name for the converted VM (default: uses original VM name)"
    echo "  -d DESTINATION  Destination directory for converted files (default: current directory)"
    echo "  -f FORMAT       VMware format (vmx, ovf, ova) (default: vmx)"
    echo "  -h              Show this help message"
    exit 1
}

# Function to check if a command exists
function check_command() {
    if ! command -v "$1" &> /dev/null; then
        echo "Error: Required command '$1' not found. Please install it."
        exit 1
    fi
}

# Function to log messages
function log() {
    echo "[$(date '+%Y-%m-%d %H:%M:%S')] $1"
}

# Parse command line arguments
VMID=""
VM_NAME=""
DESTINATION="$(pwd)"
FORMAT="vmx"

while getopts "i:n:d:f:h" opt; do
    case $opt in
        i) VMID="$OPTARG" ;;
        n) VM_NAME="$OPTARG" ;;
        d) DESTINATION="$OPTARG" ;;
        f) FORMAT="$OPTARG" ;;
        h) show_usage ;;
        *) show_usage ;;
    esac
done

# Check if VMID is provided
if [ -z "$VMID" ]; then
    echo "Error: VM ID is required"
    show_usage
fi

# Check required tools
check_command qemu-img
check_command jq

# Check if we're running on a Proxmox host
if [ ! -f /etc/pve/qemu-server/${VMID}.conf ]; then
    echo "Error: VM with ID ${VMID} not found on this Proxmox host"
    exit 1
fi

# Create temporary working directory
TEMP_DIR=$(mktemp -d)
log "Created temporary directory: $TEMP_DIR"

# Cleanup function
function cleanup() {
    log "Cleaning up temporary files..."
    rm -rf "$TEMP_DIR"
}

# Register cleanup function to run on exit
trap cleanup EXIT

# Get VM details
if [ -z "$VM_NAME" ]; then
    VM_NAME=$(grep -E "^name:" /etc/pve/qemu-server/${VMID}.conf | cut -d' ' -f2)
    if [ -z "$VM_NAME" ]; then
        VM_NAME="vm-${VMID}"
    fi
fi

log "Converting Proxmox VM ${VMID} (${VM_NAME}) to VMware format"

# Create destination directory if it doesn't exist
mkdir -p "$DESTINATION"

# Get disk information
DISKS=$(grep -E "^(scsi|sata|ide)[0-9]+:" /etc/pve/qemu-server/${VMID}.conf | grep -v "cdrom")

# Check if VM is running
if qm status $VMID | grep -q running; then
    log "Warning: VM is currently running. It's recommended to shut it down before conversion."
    read -p "Do you want to continue anyway? (y/N): " CONTINUE
    if [[ ! "$CONTINUE" =~ ^[Yy]$ ]]; then
        log "Conversion aborted"
        exit 0
    fi
fi

# Process each disk
DISK_COUNT=0
VMX_DISK_ENTRIES=""

log "Processing VM disks..."
while read -r DISK_LINE; do
    # Extract disk details
    DISK_ID=$(echo "$DISK_LINE" | cut -d: -f1)
    
    # Extract just the disk path, ignoring additional parameters
    DISK_PATH=$(echo "$DISK_LINE" | cut -d' ' -f2 | cut -d, -f1)
    
    log "Processing disk: $DISK_ID with path: $DISK_PATH"
    
    if [[ "$DISK_PATH" == *":"* ]]; then
        # Handle storage:disk format
        STORAGE=$(echo "$DISK_PATH" | cut -d: -f1)
        DISK_FILE=$(echo "$DISK_PATH" | cut -d: -f2)
        
        log "Getting full path for storage: $STORAGE, disk: $DISK_FILE"
        FULL_PATH=$(pvesm path "$STORAGE:$DISK_FILE")
    else
        # Handle direct path
        FULL_PATH="$DISK_PATH"
    fi
    
    log "Full disk path: $FULL_PATH"
    
    # Get disk format
    DISK_FORMAT=$(qemu-img info "$FULL_PATH" | grep "file format" | cut -d' ' -f3)
    log "Disk format: $DISK_FORMAT"
    
    # Convert disk to VMDK
    VMDK_NAME="${VM_NAME}-disk${DISK_COUNT}.vmdk"
    log "Converting disk $DISK_ID ($FULL_PATH) to VMDK format..."
    qemu-img convert -f "$DISK_FORMAT" -O vmdk "$FULL_PATH" "$TEMP_DIR/$VMDK_NAME"
    
    # Copy to destination
    cp "$TEMP_DIR/$VMDK_NAME" "$DESTINATION/"
    
    # Add to VMX entries
    VMX_DISK_ENTRIES+="scsi${DISK_COUNT}.present = \"TRUE\"\n"
    VMX_DISK_ENTRIES+="scsi${DISK_COUNT}.fileName = \"${VMDK_NAME}\"\n"
    
    DISK_COUNT=$((DISK_COUNT + 1))
done <<< "$DISKS"

# Get memory and CPU information
MEMORY=$(grep -E "^memory:" /etc/pve/qemu-server/${VMID}.conf | cut -d' ' -f2)
MEMORY=${MEMORY:-2048}  # Default to 2GB if not specified
CORES=$(grep -E "^cores:" /etc/pve/qemu-server/${VMID}.conf | cut -d' ' -f2)
CORES=${CORES:-1}  # Default to 1 core if not specified
SOCKETS=$(grep -E "^sockets:" /etc/pve/qemu-server/${VMID}.conf | cut -d' ' -f2)
SOCKETS=${SOCKETS:-1}  # Default to 1 socket if not specified

# Create VMX file
if [ "$FORMAT" = "vmx" ] || [ "$FORMAT" = "ovf" ] || [ "$FORMAT" = "ova" ]; then
    log "Creating VMX file..."
    cat > "$TEMP_DIR/${VM_NAME}.vmx" << EOF
.encoding = "UTF-8"
config.version = "8"
virtualHW.version = "19"
pciBridge0.present = "TRUE"
pciBridge4.present = "TRUE"
pciBridge4.virtualDev = "pcieRootPort"
pciBridge4.functions = "8"
pciBridge5.present = "TRUE"
pciBridge5.virtualDev = "pcieRootPort"
pciBridge5.functions = "8"
pciBridge6.present = "TRUE"
pciBridge6.virtualDev = "pcieRootPort"
pciBridge6.functions = "8"
pciBridge7.present = "TRUE"
pciBridge7.virtualDev = "pcieRootPort"
pciBridge7.functions = "8"
vmci0.present = "TRUE"
displayName = "${VM_NAME}"
numvcpus = "$((CORES * SOCKETS))"
memsize = "${MEMORY}"
scsi0.virtualDev = "lsisas1068"
scsi0.present = "TRUE"
$(echo -e "$VMX_DISK_ENTRIES")
ethernet0.virtualDev = "vmxnet3"
ethernet0.present = "TRUE"
ethernet0.connectionType = "bridged"
ethernet0.startConnected = "TRUE"
ethernet0.addressType = "generated"
bios.bootDelay = "5000"
powerType.powerOff = "soft"
powerType.powerOn = "hard"
powerType.suspend = "hard"
powerType.reset = "soft"
tools.syncTime = "FALSE"
EOF

    # Copy VMX file to destination
    cp "$TEMP_DIR/${VM_NAME}.vmx" "$DESTINATION/"
    log "VMX file created at $DESTINATION/${VM_NAME}.vmx"
fi

# Convert to OVF/OVA if requested
if [ "$FORMAT" = "ovf" ] || [ "$FORMAT" = "ova" ]; then
    log "Converting to $FORMAT format..."
    check_command ovftool
    
    if [ "$FORMAT" = "ovf" ]; then
        ovftool "$DESTINATION/${VM_NAME}.vmx" "$DESTINATION/${VM_NAME}.ovf"
        log "OVF file created at $DESTINATION/${VM_NAME}.ovf"
    else
        ovftool "$DESTINATION/${VM_NAME}.vmx" "$DESTINATION/${VM_NAME}.ova"
        log "OVA file created at $DESTINATION/${VM_NAME}.ova"
        
        # Remove VMX and VMDK files as they're now in the OVA
        rm "$DESTINATION/${VM_NAME}.vmx"
        for ((i=0; i<DISK_COUNT; i++)); do
            rm "$DESTINATION/${VM_NAME}-disk${i}.vmdk"
        done
    fi
fi

log "Conversion completed successfully!"
log "VM files are available in: $DESTINATION"
 
or simply use my script:

tell me how it works ;)

Bash:
#!/bin/bash

# proxmox-vm_vmware.sh - Convert Proxmox VM to VMware format
# Author: 0zzy
# Date: 2023-09-10
# Version: 1.0
# License: MIT
#
# Description: This script converts a Proxmox VM to VMware format.
#              It can convert to VMware VMX, OVF, or OVA format.
#              It requires the ovftool command-line tool.
#              It uses the qemu-img command-line tool to convert disks.
#              It uses the jq command-line tool to parse
#
# To use the Script, run the following command:
# chmod +x proxmox-vm_vmware.sh
#
# Then run it with the required VM ID:
# ./proxmox-vm_vmware.sh -i VMID
# Example: ./proxmox-vm_vmware.sh -i 100
#
# Or with additional options:
# ./proxmox-vm_vmware.sh -i 100 -n MyVM -d /path/to/output -f ova


set -e

# Function to display usage information
function show_usage() {
    echo "Usage: $0 -i VMID [-n VM_NAME] [-d DESTINATION] [-f FORMAT]"
    echo
    echo "Options:"
    echo "  -i VMID         Proxmox VM ID to convert"
    echo "  -n VM_NAME      Name for the converted VM (default: uses original VM name)"
    echo "  -d DESTINATION  Destination directory for converted files (default: current directory)"
    echo "  -f FORMAT       VMware format (vmx, ovf, ova) (default: vmx)"
    echo "  -h              Show this help message"
    exit 1
}

# Function to check if a command exists
function check_command() {
    if ! command -v "$1" &> /dev/null; then
        echo "Error: Required command '$1' not found. Please install it."
        exit 1
    fi
}

# Function to log messages
function log() {
    echo "[$(date '+%Y-%m-%d %H:%M:%S')] $1"
}

# Parse command line arguments
VMID=""
VM_NAME=""
DESTINATION="$(pwd)"
FORMAT="vmx"

while getopts "i:n:d:f:h" opt; do
    case $opt in
        i) VMID="$OPTARG" ;;
        n) VM_NAME="$OPTARG" ;;
        d) DESTINATION="$OPTARG" ;;
        f) FORMAT="$OPTARG" ;;
        h) show_usage ;;
        *) show_usage ;;
    esac
done

# Check if VMID is provided
if [ -z "$VMID" ]; then
    echo "Error: VM ID is required"
    show_usage
fi

# Check required tools
check_command qemu-img
check_command jq

# Check if we're running on a Proxmox host
if [ ! -f /etc/pve/qemu-server/${VMID}.conf ]; then
    echo "Error: VM with ID ${VMID} not found on this Proxmox host"
    exit 1
fi

# Create temporary working directory
TEMP_DIR=$(mktemp -d)
log "Created temporary directory: $TEMP_DIR"

# Cleanup function
function cleanup() {
    log "Cleaning up temporary files..."
    rm -rf "$TEMP_DIR"
}

# Register cleanup function to run on exit
trap cleanup EXIT

# Get VM details
if [ -z "$VM_NAME" ]; then
    VM_NAME=$(grep -E "^name:" /etc/pve/qemu-server/${VMID}.conf | cut -d' ' -f2)
    if [ -z "$VM_NAME" ]; then
        VM_NAME="vm-${VMID}"
    fi
fi

log "Converting Proxmox VM ${VMID} (${VM_NAME}) to VMware format"

# Create destination directory if it doesn't exist
mkdir -p "$DESTINATION"

# Get disk information
DISKS=$(grep -E "^(scsi|sata|ide)[0-9]+:" /etc/pve/qemu-server/${VMID}.conf | grep -v "cdrom")

# Check if VM is running
if qm status $VMID | grep -q running; then
    log "Warning: VM is currently running. It's recommended to shut it down before conversion."
    read -p "Do you want to continue anyway? (y/N): " CONTINUE
    if [[ ! "$CONTINUE" =~ ^[Yy]$ ]]; then
        log "Conversion aborted"
        exit 0
    fi
fi

# Process each disk
DISK_COUNT=0
VMX_DISK_ENTRIES=""

log "Processing VM disks..."
while read -r DISK_LINE; do
    # Extract disk details
    DISK_ID=$(echo "$DISK_LINE" | cut -d: -f1)
   
    # Extract just the disk path, ignoring additional parameters
    DISK_PATH=$(echo "$DISK_LINE" | cut -d' ' -f2 | cut -d, -f1)
   
    log "Processing disk: $DISK_ID with path: $DISK_PATH"
   
    if [[ "$DISK_PATH" == *":"* ]]; then
        # Handle storage:disk format
        STORAGE=$(echo "$DISK_PATH" | cut -d: -f1)
        DISK_FILE=$(echo "$DISK_PATH" | cut -d: -f2)
       
        log "Getting full path for storage: $STORAGE, disk: $DISK_FILE"
        FULL_PATH=$(pvesm path "$STORAGE:$DISK_FILE")
    else
        # Handle direct path
        FULL_PATH="$DISK_PATH"
    fi
   
    log "Full disk path: $FULL_PATH"
   
    # Get disk format
    DISK_FORMAT=$(qemu-img info "$FULL_PATH" | grep "file format" | cut -d' ' -f3)
    log "Disk format: $DISK_FORMAT"
   
    # Convert disk to VMDK
    VMDK_NAME="${VM_NAME}-disk${DISK_COUNT}.vmdk"
    log "Converting disk $DISK_ID ($FULL_PATH) to VMDK format..."
    qemu-img convert -f "$DISK_FORMAT" -O vmdk "$FULL_PATH" "$TEMP_DIR/$VMDK_NAME"
   
    # Copy to destination
    cp "$TEMP_DIR/$VMDK_NAME" "$DESTINATION/"
   
    # Add to VMX entries
    VMX_DISK_ENTRIES+="scsi${DISK_COUNT}.present = \"TRUE\"\n"
    VMX_DISK_ENTRIES+="scsi${DISK_COUNT}.fileName = \"${VMDK_NAME}\"\n"
   
    DISK_COUNT=$((DISK_COUNT + 1))
done <<< "$DISKS"

# Get memory and CPU information
MEMORY=$(grep -E "^memory:" /etc/pve/qemu-server/${VMID}.conf | cut -d' ' -f2)
MEMORY=${MEMORY:-2048}  # Default to 2GB if not specified
CORES=$(grep -E "^cores:" /etc/pve/qemu-server/${VMID}.conf | cut -d' ' -f2)
CORES=${CORES:-1}  # Default to 1 core if not specified
SOCKETS=$(grep -E "^sockets:" /etc/pve/qemu-server/${VMID}.conf | cut -d' ' -f2)
SOCKETS=${SOCKETS:-1}  # Default to 1 socket if not specified

# Create VMX file
if [ "$FORMAT" = "vmx" ] || [ "$FORMAT" = "ovf" ] || [ "$FORMAT" = "ova" ]; then
    log "Creating VMX file..."
    cat > "$TEMP_DIR/${VM_NAME}.vmx" << EOF
.encoding = "UTF-8"
config.version = "8"
virtualHW.version = "19"
pciBridge0.present = "TRUE"
pciBridge4.present = "TRUE"
pciBridge4.virtualDev = "pcieRootPort"
pciBridge4.functions = "8"
pciBridge5.present = "TRUE"
pciBridge5.virtualDev = "pcieRootPort"
pciBridge5.functions = "8"
pciBridge6.present = "TRUE"
pciBridge6.virtualDev = "pcieRootPort"
pciBridge6.functions = "8"
pciBridge7.present = "TRUE"
pciBridge7.virtualDev = "pcieRootPort"
pciBridge7.functions = "8"
vmci0.present = "TRUE"
displayName = "${VM_NAME}"
numvcpus = "$((CORES * SOCKETS))"
memsize = "${MEMORY}"
scsi0.virtualDev = "lsisas1068"
scsi0.present = "TRUE"
$(echo -e "$VMX_DISK_ENTRIES")
ethernet0.virtualDev = "vmxnet3"
ethernet0.present = "TRUE"
ethernet0.connectionType = "bridged"
ethernet0.startConnected = "TRUE"
ethernet0.addressType = "generated"
bios.bootDelay = "5000"
powerType.powerOff = "soft"
powerType.powerOn = "hard"
powerType.suspend = "hard"
powerType.reset = "soft"
tools.syncTime = "FALSE"
EOF

    # Copy VMX file to destination
    cp "$TEMP_DIR/${VM_NAME}.vmx" "$DESTINATION/"
    log "VMX file created at $DESTINATION/${VM_NAME}.vmx"
fi

# Convert to OVF/OVA if requested
if [ "$FORMAT" = "ovf" ] || [ "$FORMAT" = "ova" ]; then
    log "Converting to $FORMAT format..."
    check_command ovftool
   
    if [ "$FORMAT" = "ovf" ]; then
        ovftool "$DESTINATION/${VM_NAME}.vmx" "$DESTINATION/${VM_NAME}.ovf"
        log "OVF file created at $DESTINATION/${VM_NAME}.ovf"
    else
        ovftool "$DESTINATION/${VM_NAME}.vmx" "$DESTINATION/${VM_NAME}.ova"
        log "OVA file created at $DESTINATION/${VM_NAME}.ova"
       
        # Remove VMX and VMDK files as they're now in the OVA
        rm "$DESTINATION/${VM_NAME}.vmx"
        for ((i=0; i<DISK_COUNT; i++)); do
            rm "$DESTINATION/${VM_NAME}-disk${i}.vmdk"
        done
    fi
fi

log "Conversion completed successfully!"
log "VM files are available in: $DESTINATION"


Hi, Is there any gitlab project for this nice script? Thanks
 
Hi, Is there any gitlab project for this nice script? Thanks
No actually not. I would share it firstly here. I’m not a developer. but you could do it if you wish. It’s free for everyone to use it.

If I have more time I could create a GitHub repo for it.
 
Last edited:
or simply use my script:

tell me how it works ;)

Bash:
#!/bin/bash

# proxmox-vm_vmware.sh - Convert Proxmox VM to VMware format
# Author: 0zzy
# Date: 2023-09-10
# Version: 1.0
# License: MIT
#
# Description: This script converts a Proxmox VM to VMware format.
#              It can convert to VMware VMX, OVF, or OVA format.
#              It requires the ovftool command-line tool.
#              It uses the qemu-img command-line tool to convert disks.
#              It uses the jq command-line tool to parse
#
# To use the Script, run the following command:
# chmod +x proxmox-vm_vmware.sh
#
# Then run it with the required VM ID:
# ./proxmox-vm_vmware.sh -i VMID
# Example: ./proxmox-vm_vmware.sh -i 100
#
# Or with additional options:
# ./proxmox-vm_vmware.sh -i 100 -n MyVM -d /path/to/output -f ova


set -e

# Function to display usage information
function show_usage() {
    echo "Usage: $0 -i VMID [-n VM_NAME] [-d DESTINATION] [-f FORMAT]"
    echo
    echo "Options:"
    echo "  -i VMID         Proxmox VM ID to convert"
    echo "  -n VM_NAME      Name for the converted VM (default: uses original VM name)"
    echo "  -d DESTINATION  Destination directory for converted files (default: current directory)"
    echo "  -f FORMAT       VMware format (vmx, ovf, ova) (default: vmx)"
    echo "  -h              Show this help message"
    exit 1
}

# Function to check if a command exists
function check_command() {
    if ! command -v "$1" &> /dev/null; then
        echo "Error: Required command '$1' not found. Please install it."
        exit 1
    fi
}

# Function to log messages
function log() {
    echo "[$(date '+%Y-%m-%d %H:%M:%S')] $1"
}

# Parse command line arguments
VMID=""
VM_NAME=""
DESTINATION="$(pwd)"
FORMAT="vmx"

while getopts "i:n:d:f:h" opt; do
    case $opt in
        i) VMID="$OPTARG" ;;
        n) VM_NAME="$OPTARG" ;;
        d) DESTINATION="$OPTARG" ;;
        f) FORMAT="$OPTARG" ;;
        h) show_usage ;;
        *) show_usage ;;
    esac
done

# Check if VMID is provided
if [ -z "$VMID" ]; then
    echo "Error: VM ID is required"
    show_usage
fi

# Check required tools
check_command qemu-img
check_command jq

# Check if we're running on a Proxmox host
if [ ! -f /etc/pve/qemu-server/${VMID}.conf ]; then
    echo "Error: VM with ID ${VMID} not found on this Proxmox host"
    exit 1
fi

# Create temporary working directory
TEMP_DIR=$(mktemp -d)
log "Created temporary directory: $TEMP_DIR"

# Cleanup function
function cleanup() {
    log "Cleaning up temporary files..."
    rm -rf "$TEMP_DIR"
}

# Register cleanup function to run on exit
trap cleanup EXIT

# Get VM details
if [ -z "$VM_NAME" ]; then
    VM_NAME=$(grep -E "^name:" /etc/pve/qemu-server/${VMID}.conf | cut -d' ' -f2)
    if [ -z "$VM_NAME" ]; then
        VM_NAME="vm-${VMID}"
    fi
fi

log "Converting Proxmox VM ${VMID} (${VM_NAME}) to VMware format"

# Create destination directory if it doesn't exist
mkdir -p "$DESTINATION"

# Get disk information
DISKS=$(grep -E "^(scsi|sata|ide)[0-9]+:" /etc/pve/qemu-server/${VMID}.conf | grep -v "cdrom")

# Check if VM is running
if qm status $VMID | grep -q running; then
    log "Warning: VM is currently running. It's recommended to shut it down before conversion."
    read -p "Do you want to continue anyway? (y/N): " CONTINUE
    if [[ ! "$CONTINUE" =~ ^[Yy]$ ]]; then
        log "Conversion aborted"
        exit 0
    fi
fi

# Process each disk
DISK_COUNT=0
VMX_DISK_ENTRIES=""

log "Processing VM disks..."
while read -r DISK_LINE; do
    # Extract disk details
    DISK_ID=$(echo "$DISK_LINE" | cut -d: -f1)
   
    # Extract just the disk path, ignoring additional parameters
    DISK_PATH=$(echo "$DISK_LINE" | cut -d' ' -f2 | cut -d, -f1)
   
    log "Processing disk: $DISK_ID with path: $DISK_PATH"
   
    if [[ "$DISK_PATH" == *":"* ]]; then
        # Handle storage:disk format
        STORAGE=$(echo "$DISK_PATH" | cut -d: -f1)
        DISK_FILE=$(echo "$DISK_PATH" | cut -d: -f2)
       
        log "Getting full path for storage: $STORAGE, disk: $DISK_FILE"
        FULL_PATH=$(pvesm path "$STORAGE:$DISK_FILE")
    else
        # Handle direct path
        FULL_PATH="$DISK_PATH"
    fi
   
    log "Full disk path: $FULL_PATH"
   
    # Get disk format
    DISK_FORMAT=$(qemu-img info "$FULL_PATH" | grep "file format" | cut -d' ' -f3)
    log "Disk format: $DISK_FORMAT"
   
    # Convert disk to VMDK
    VMDK_NAME="${VM_NAME}-disk${DISK_COUNT}.vmdk"
    log "Converting disk $DISK_ID ($FULL_PATH) to VMDK format..."
    qemu-img convert -f "$DISK_FORMAT" -O vmdk "$FULL_PATH" "$TEMP_DIR/$VMDK_NAME"
   
    # Copy to destination
    cp "$TEMP_DIR/$VMDK_NAME" "$DESTINATION/"
   
    # Add to VMX entries
    VMX_DISK_ENTRIES+="scsi${DISK_COUNT}.present = \"TRUE\"\n"
    VMX_DISK_ENTRIES+="scsi${DISK_COUNT}.fileName = \"${VMDK_NAME}\"\n"
   
    DISK_COUNT=$((DISK_COUNT + 1))
done <<< "$DISKS"

# Get memory and CPU information
MEMORY=$(grep -E "^memory:" /etc/pve/qemu-server/${VMID}.conf | cut -d' ' -f2)
MEMORY=${MEMORY:-2048}  # Default to 2GB if not specified
CORES=$(grep -E "^cores:" /etc/pve/qemu-server/${VMID}.conf | cut -d' ' -f2)
CORES=${CORES:-1}  # Default to 1 core if not specified
SOCKETS=$(grep -E "^sockets:" /etc/pve/qemu-server/${VMID}.conf | cut -d' ' -f2)
SOCKETS=${SOCKETS:-1}  # Default to 1 socket if not specified

# Create VMX file
if [ "$FORMAT" = "vmx" ] || [ "$FORMAT" = "ovf" ] || [ "$FORMAT" = "ova" ]; then
    log "Creating VMX file..."
    cat > "$TEMP_DIR/${VM_NAME}.vmx" << EOF
.encoding = "UTF-8"
config.version = "8"
virtualHW.version = "19"
pciBridge0.present = "TRUE"
pciBridge4.present = "TRUE"
pciBridge4.virtualDev = "pcieRootPort"
pciBridge4.functions = "8"
pciBridge5.present = "TRUE"
pciBridge5.virtualDev = "pcieRootPort"
pciBridge5.functions = "8"
pciBridge6.present = "TRUE"
pciBridge6.virtualDev = "pcieRootPort"
pciBridge6.functions = "8"
pciBridge7.present = "TRUE"
pciBridge7.virtualDev = "pcieRootPort"
pciBridge7.functions = "8"
vmci0.present = "TRUE"
displayName = "${VM_NAME}"
numvcpus = "$((CORES * SOCKETS))"
memsize = "${MEMORY}"
scsi0.virtualDev = "lsisas1068"
scsi0.present = "TRUE"
$(echo -e "$VMX_DISK_ENTRIES")
ethernet0.virtualDev = "vmxnet3"
ethernet0.present = "TRUE"
ethernet0.connectionType = "bridged"
ethernet0.startConnected = "TRUE"
ethernet0.addressType = "generated"
bios.bootDelay = "5000"
powerType.powerOff = "soft"
powerType.powerOn = "hard"
powerType.suspend = "hard"
powerType.reset = "soft"
tools.syncTime = "FALSE"
EOF

    # Copy VMX file to destination
    cp "$TEMP_DIR/${VM_NAME}.vmx" "$DESTINATION/"
    log "VMX file created at $DESTINATION/${VM_NAME}.vmx"
fi

# Convert to OVF/OVA if requested
if [ "$FORMAT" = "ovf" ] || [ "$FORMAT" = "ova" ]; then
    log "Converting to $FORMAT format..."
    check_command ovftool
   
    if [ "$FORMAT" = "ovf" ]; then
        ovftool "$DESTINATION/${VM_NAME}.vmx" "$DESTINATION/${VM_NAME}.ovf"
        log "OVF file created at $DESTINATION/${VM_NAME}.ovf"
    else
        ovftool "$DESTINATION/${VM_NAME}.vmx" "$DESTINATION/${VM_NAME}.ova"
        log "OVA file created at $DESTINATION/${VM_NAME}.ova"
       
        # Remove VMX and VMDK files as they're now in the OVA
        rm "$DESTINATION/${VM_NAME}.vmx"
        for ((i=0; i<DISK_COUNT; i++)); do
            rm "$DESTINATION/${VM_NAME}-disk${i}.vmdk"
        done
    fi
fi

log "Conversion completed successfully!"
log "VM files are available in: $DESTINATION"
I get an error about jq:

"Error: Required command 'jq' not found. Please install it."

but cannot install it via apt, how did you installed it?
 
as I wrote is not possible to install via apt:

root@proxmox:/tmp# apt install jq
Reading package lists... Done
Building dependency tree... Done
Reading state information... Done
E: Unable to locate package jq
 
as I wrote is not possible to install via apt:

root@proxmox:/tmp# apt install jq
Reading package lists... Done
Building dependency tree... Done
Reading state information... Done
E: Unable to locate package jq
solved there was a proxy block to debian repo
 
Does the:

proxmox-vm_vmware.sh (0zzy/2023-09-10/Version: 1.0)

script actually use "jq" for anything though?

If I grep it for "jq" I get:

# It uses the jq command-line tool to parse
check_command jq

So it checks whether jq is installed but it doesn't seem actually to launch jq, unless jq itself is launched by something else in the script or there is some other way to launch it.

Thanks.
 
@ronejamesdo yes it does. you need to run the script on one of your proxmox nodes and install jq with "apt install -y jq".
I dont want to add it in the script actually. Its not really a future proofed concept and is only for helping others or myself.
Why i have do this? Simply i dont like to make things twice.
I had an OpenScap Server Running with perfect settings and need a solution to convert my Server VM from Proxmox to VMWare Workstation or Fusion on Mac.

Thats what comes out if everything else is only a state of time thing and i hate to copy paste things over and over ;)