destroy_vm.sh Updated, Supports Multiple Hosts and --force option now
The updated script now accepts multiple VMIDs as command-line arguments, making it easier to remove several VMs at once. Additionally, a --force option has been added, so you no longer have to confirm deletion for each VM manually.
This update streamlines VM cleanup by automating the process, reducing confirmation prompts, and ensuring SSH key cleanup for smoother re-deployment.
What’s New in This Update?
- Supports Multiple VMIDs – Instead of running the script one VM at a time, you can now pass multiple VMIDs as arguments.
- New
--forceOption – If you are sure about deleting VMs, use--forceto bypass manual confirmation. - Displays VM Details Before Deletion – Helps verify the correct VM is being deleted.
- Cleans Up Old SSH Keys – Prevents SSH host verification issues after VM destruction.
Usage
Run the script with one or more VMIDs:
./vm_destroyer.sh 101 102 103
Or use --force to skip confirmations:
./vm_destroyer.sh --force 101 102 103
How It Works
The script loops through each provided VMID, retrieves VM details, and prompts for confirmation unless --force is specified. It then stops the VM, waits for it to shut down, and deletes it. Finally, if the VM had a Cloud-Init assigned IP, the script removes the old SSH key entry to prevent connection issues in future deployments.
This update makes Proxmox VM lifecycle management faster and more efficient, particularly when dealing with batch deletions.
Eventually this will be programmed in Go as part of CodexMCP, but at this stage this was the fastest option.
destroy_vm.sh
#!/bin/bash
# Set Proxmox API Details
PROXMOX_HOST="your-proxmox-host"
NODE="mcp"
API_TOKEN="your-proxmox-api-token"
# Check if --force option is provided
FORCE_MODE=false
if [[ "$1" == "--force" ]]; then
FORCE_MODE=true
shift # Remove --force from argument list
fi
# Ensure at least one VMID is provided
if [ "$#" -lt 1 ]; then
echo "Usage: $0 [--force] [VMID2] [VMID3] ..."
exit 1
fi
# Loop through each VM ID provided as argument
for VMID in "$@"; do
echo "Fetching information for VM ID: $VMID..."
# 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."
continue
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 ""
# Confirm deletion unless --force is used
if [ "$FORCE_MODE" = false ]; then
read -p "Are you sure you want to STOP and DESTROY this VM? (yes/no): " CONFIRM
if [[ "$CONFIRM" != "yes" ]]; then
echo "Skipping VM $VMID."
continue
fi
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."
echo "------------------------------------------------------------"
done