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
--force
Option – If you are sure about deleting VMs, use--force
to 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