Manually removing stale or orphaned virtual machines from vCenter Server
search cancel

Manually removing stale or orphaned virtual machines from vCenter Server

book

Article ID: 311105

calendar_today

Updated On:

Products

VMware vCenter Server

Issue/Introduction

This article provides instructions for removing orphaned virtual machine or template records from the vCenter Server database. This is used when the objects cannot be removed via the vSphere Client.

  • A virtual machine cannot be removed from the inventory.

  • The "Remove from Inventory" or "Delete from Disk" option is grayed out.

  • The virtual machine appears as "orphaned" or "inaccessible" in the vSphere Client.

Attempts to delete a VM template result in the following error: YYYY-MM-DDT HH:MM:SS The object 'vim.VirtualMachine:vm-####' has already been deleted or has not been completely created.

Environment

  • vCenter 7.x
  • vCenter 8.x
  • vCenter 9.x

Cause

Metadata inconsistency occurs when a virtual machine is removed directly from an ESXi host during vCenter Server downtime or when an administrative task is interrupted, leaving residual entries in the vCenter Server database.

Resolution

NOTE: Ensure a fresh backup or offline snapshot of the vCenter Server Appliance has been created. If the vCenter Server is part of a Linked Mode replication group, backups must be created for every member as described in KB Snapshot Best practices for vCenter Server Virtual Machines

Method 1: Using a dummy VM folder in vSphere Client

  1. In vSphere Client, change into the "VMs and Folders" view.
  2. Create a new Virtual Machine folder.
  3. Drag and drop the orphaned virtual machine into this folder.
  4. Delete the folder. 

Method 2: Manual Removal (Single VM Object)

  1. SSH to vCenter and login as root.
  2. Stop the vpxd service: service-control --stop vmware-vpxd

  3. Connect to the database: /opt/vmware/vpostgres/current/bin/psql -d VCDB -U postgres

  4. To identify the Virtual Machine ID, use one of the following three methods:

    a. Select the VM in the vCenter GUI and look for VirtualMachine:vm- ### in the url. Use the ### as <id_from_url> and validate the VM exists in vpx_entity :

      select * from vpx_entity where id = '<id_from_url>';

        Example Output:

        VCDB=# select * from vpx_entity where id = '0000';
         id      |   name      | type_id | parent_id
         -------+--------------+----------+-------------
         0000 |  vm-name |       #    |      # 

    b. Identify the VM ID in the vCenter database with this command (replace <vm name> against the actual name of the orphaned VM):

         select * from vpx_entity where name like '%<vm name>%';

         Example Output:

         VCDB=# select * from vpx_entity where name like '%vcsa%';
          id      |   name                | type_id  | parent_id
         --------+---------------------+------------+------------
          0000 | vcsa(orphaned) |    #        |    #

    c. Find it in the vpxd.log (var/log/vmware/vpxd/vpxd.log) on the vCenter when searching for the VM name.

  5. Execute the following DELETE statements in order, replacing <VM_ID> with the numeric ID from the VM ID noted from above output

     delete from VPX_COMPUTE_RESOURCE_DAS_VM where VM_ID=<VM_ID>;

     delete from VPX_COMPUTE_RESOURCE_DRS_VM where VM_ID=<VM_ID>;

     delete from VPX_COMPUTE_RESOURCE_ORC_VM where VM_ID=<VM_ID>;

     delete from VPX_VM_SGXINFO where VM_ID=<VM_ID>;

     delete from VPX_GUEST_DISK where VM_ID=<VM_ID>;

     delete from VPX_VM_VIRTUAL_DEVICE where ID=<VM_ID>;

     delete from VPX_VM_DS_SPACE where VM_ID=<VM_ID>;

     delete from VPX_NON_ORM_VM_CONFIG_INFO where ID=<VM_ID>;

     delete from VPX_NORM_VM_FLE_FILE_INFO where VM_ID=<VM_ID>;

     delete from VPX_VDEVICE_BACKING_REL where VM_ID=<VM_ID>;

     delete from VPX_VIRTUAL_DISK_IOFILTERS where VM_ID=<VM_ID>;

     delete from VPX_VM_STATIC_OVERHEAD_MAP where VM_ID=<VM_ID>;

     delete from VPX_VM_TEXT where VM_ID=<VM_ID>;

     delete from VPX_VM where ID=<VM_ID>;

     delete from VPX_ENTITY where ID=<VM_ID>;

     delete from VPX_DVPORT where connectee='<VM_Name>';

    5. Start the vpxd service: service-control --start vmware-vpxd

Method 3: Scripted Removal (Multiple Objects) For scenarios involving multiple stale objects, a script can automate the deletion process.

  1. SSH to vCenter and login as root.
  2. Stop the vpxd service: service-control --stop vmware-vpxd
  3. Connect to the database: /opt/vmware/vpostgres/current/bin/psql -d VCDB -U postgres
  4. To identify the Virtual Machine ID, use one of the following three methods:

    a. Select the VM in the vCenter GUI and look for VirtualMachine:vm- ### in the url. Use the ### as <id_from_url> and validate the VM exists in vpx_entity :

      select * from vpx_entity where id = '<id_from_url>';

        Example Output:

        VCDB=# select * from vpx_entity where id = '0000';
         id      |   name      | type_id | parent_id
         -------+--------------+----------+-------------
         0000 |  vm-name |       #    |      # 

    b. Identify the VM ID in the vCenter database with this command (replace <vm name> against the actual name of the orphaned VM):

         select * from vpx_entity where name like '%<vm name>%';

         Example Output:

         VCDB=# select * from vpx_entity where name like '%vcsa%';
          id      |   name                | type_id  | parent_id
         --------+---------------------+------------+------------
          0000 | vcsa(orphaned) |    #        |    #

    c. Find it in the vpxd.log (var/log/vmware/vpxd/vpxd.log) on the vCenter when searching for the VM name.
  5. Create the Script:

    • Open a new file: vi /tmp/delete_vms.sh

    • Paste the following content, replacing x, y, z with your comma-separated VM IDs: 

          #!/bin/bash

         # Replace x, y, z with the numeric IDs of the VMs to be removed

             VM_IDS="x, y, z"

         # Replace name1, name2 with the names for DVPORT cleanup

             VM_NAMES="'name1', 'name2'"

            PSQL_CMD="/opt/vmware/vpostgres/current/bin/psql -U postgres VCDB -c"

            $PSQL_CMD "DELETE FROM VPX_COMPUTE_RESOURCE_DAS_VM WHERE VM_ID IN ($VM_IDS);"

      $PSQL_CMD "DELETE FROM VPX_COMPUTE_RESOURCE_DRS_VM WHERE VM_ID IN ($VM_IDS);"

      $PSQL_CMD "DELETE FROM VPX_COMPUTE_RESOURCE_ORC_VM WHERE VM_ID IN ($VM_IDS);"

      $PSQL_CMD "DELETE FROM VPX_VM_SGXINFO WHERE VM_ID IN ($VM_IDS);"

      $PSQL_CMD "DELETE FROM VPX_GUEST_DISK WHERE VM_ID IN ($VM_IDS);"

      $PSQL_CMD "DELETE FROM VPX_VM_VIRTUAL_DEVICE WHERE ID IN ($VM_IDS);"

      $PSQL_CMD "DELETE FROM VPX_VM_DS_SPACE WHERE VM_ID IN ($VM_IDS);"

      $PSQL_CMD "DELETE FROM VPX_NON_ORM_VM_CONFIG_INFO WHERE ID IN ($VM_IDS);"

      $PSQL_CMD "DELETE FROM VPX_NORM_VM_FLE_FILE_INFO WHERE VM_ID IN ($VM_IDS);"

      $PSQL_CMD "DELETE FROM VPX_VDEVICE_BACKING_REL WHERE VM_ID IN ($VM_IDS);"

      $PSQL_CMD "DELETE FROM VPX_VIRTUAL_DISK_IOFILTERS WHERE VM_ID IN ($VM_IDS);"

      $PSQL_CMD "DELETE FROM VPX_VM_STATIC_OVERHEAD_MAP WHERE VM_ID IN ($VM_IDS);"

     4. Execute the Script:

    • Set permissions: chmod +x /tmp/delete_vms.sh

    • Run the script: /tmp/delete_vms.sh >> /tmp/removal_results.txt

     5. Start the vpxd service: service-control --start vmware-vpxd

Additional Information

If the virtual machine was connected to a Distributed Virtual Switch (DVS) before becoming orphaned, ensure the VPX_DVPORT entry is removed to prevent port conflicts.