I Got tired of Manually Destroying VMs, So I Automated It
Proxmox makes spinning up virtual machines easy, but when working in an active development environment, constantly creating and destroying test VMs becomes a repetitive task. Deleting a VM manually through the UI or CLI every time you need to clean up slows things down. So it made sense to automate the process while keeping it safe from accidental deletions.
This script takes a VM ID, retrieves its details, displays them, and then asks for confirmation before stopping and destroying the VM. It ensures that the VM is gracefully shut down before deletion.
Bash Script to Stop and Destroy a Proxmox VM
#!/bin/bash
# Set Proxmox API Details (Obfuscated)
PROXMOX_HOST="your.proxmox.host"
NODE="your-node-name"
API_TOKEN="your-obfuscated-token"
# Check if VM ID was provided
if [ -z "$1" ]; then
echo "Usage: $0 <VMID>"
exit 1
fi
VMID=$1
# Fetch VM Details
VM_INFO=$(curl -s -k -H "Authorization: PVEAPIToken=$API_TOKEN" \
"https://$PROXMOX_HOST:8006/api2/json/nodes/$NODE/qemu/$VMID/config")
# Extract Name and Display Info
VM_NAME=$(echo "$VM_INFO" | jq -r '.data.name')
VM_DISK=$(echo "$VM_INFO" | jq -r '.data.scsi0')
VM_MEMORY=$(echo "$VM_INFO" | jq -r '.data.memory')
VM_IP=$(echo "$VM_INFO" | jq -r '.data.ipconfig0' | sed -n 's/ip=\(.*\)\/.*/\1/p')
if [ "$VM_NAME" == "null" ]; then
echo "VM with ID $VMID not found on node $NODE."
exit 1
fi
echo "VM Found: $VM_NAME ($VMID)"
echo " - Disk: $VM_DISK"
echo " - Memory: ${VM_MEMORY}MB"
if [ -n "$VM_IP" ]; then
echo " - Cloud-Init Assigned IP: $VM_IP"
else
echo " - No IP Found (Check Cloud-Init Configuration)"
fi
echo ""
read -p "Are you sure you want to STOP and DESTROY this VM? (yes/no): " CONFIRM
if [[ "$CONFIRM" != "yes" ]]; then
echo "Operation canceled."
exit 0
fi
# Stop the VM
echo "Stopping VM $VMID..."
curl -s -k -X POST -H "Authorization: PVEAPIToken=$API_TOKEN" \
"https://$PROXMOX_HOST:8006/api2/json/nodes/$NODE/qemu/$VMID/status/stop"
# Wait for the VM to shut down
echo "Waiting for VM to fully stop..."
sleep 10
# Destroy the VM
echo "Destroying VM $VMID..."
curl -s -k -X DELETE -H "Authorization: PVEAPIToken=$API_TOKEN" \
"https://$PROXMOX_HOST:8006/api2/json/nodes/$NODE/qemu/$VMID"
echo "VM $VMID ($VM_NAME) has been destroyed."
# Remove the old SSH key to prevent host key verification errors
if [ -n "$VM_IP" ]; then
echo "Cleaning up old SSH key for $VM_IP..."
ssh-keygen -f "$HOME/.ssh/known_hosts" -R "$VM_IP" >/dev/null 2>&1
fi
echo "Old SSH key removed. You can now reconnect without errors."
How It Works
- The script takes a VM ID as an argument.
- It queries the Proxmox API to fetch details about the VM, including its name, disk, and memory.
- If the VM does not exist, the script exits immediately.
- If the VM is found, it displays its details and asks for confirmation before proceeding.
- If confirmed, it first stops the VM using the API.
- It then waits 10 seconds to ensure the VM is fully shut down.
- Next, it deletes the VM from Proxmox.
- Finally, it removes the old SSH key from localhost. This is so we do not encounter an invalid host key error when trying to log in or run the next Ansible scripts.
Why This Matters
This script makes it easy to clean up test VMs without unnecessary UI navigation or repeated CLI commands. It ensures that deletion is deliberate, reducing the risk of removing the wrong VM. The Proxmox API is powerful, and automating routine actions like this saves time and prevents mistakes.
For now, this is a standalone tool for development cleanup, but it could be expanded into a broader automation framework for managing VM lifecycles.
-Always Breaking Something
--Bryan