Created
January 7, 2025 03:40
-
-
Save cuongitl/4ab88dd47771ed15f973b7724267e55f to your computer and use it in GitHub Desktop.
Moving a virtual machine between ESXi hosts
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| # Built with ❤️ by Cuongitl (LE VAN CUONG) | |
| # Filename: migrate-vm.py | |
| # Modified: 2025-01-02 | |
| # Purpose: Moving a virtual machine between ESXi hosts | |
| # Reference: | |
| # - https://t.me/Cuongitl | |
| # ============================================================================= | |
| import time | |
| from pyVmomi import vim | |
| from pyVim.connect import SmartConnect, Disconnect | |
| import pyvmware.vmutils as vmutils | |
| import sys | |
| import ssl | |
| from loguru import logger | |
| #------------------ | |
| # Inputs: | |
| username = "your-username" | |
| password = "your-passwrod" | |
| # --- | |
| file_vms = "files/vms_vnesxi02.txt" # a list of vms | |
| vcenter = "vnsvcenter01" # vCenter Server | |
| destination_host = "vnesxi02.infra.lecuong.info" | |
| # ============================================================================= | |
| def create_client(vcenter): | |
| si = None | |
| try: | |
| # Bypass SSL certificate verification | |
| context = ssl._create_default_https_context() | |
| context.check_hostname = False | |
| context.verify_mode = ssl.CERT_NONE | |
| si = SmartConnect(host=vcenter, user=username, pwd=password, port=443, sslContext=context) | |
| except IOError as e: | |
| logger.error(e) | |
| sys.exit() | |
| return si | |
| def migrate_vm(si, vm_name, destination_host): | |
| esx_host = vmutils.get_host_by_name(si, destination_host) | |
| logger.info(esx_host) | |
| # Finding source VM | |
| vm = vmutils.get_vm_by_name(si, vm_name) | |
| if vm: | |
| logger.debug(vm) | |
| # relocate spec, to migrate to another host | |
| # this can do other things, like storage and resource pool | |
| # migrations | |
| relocate_spec = vim.vm.RelocateSpec(host=esx_host) | |
| # does the actual migration to host | |
| vm.Relocate(relocate_spec) | |
| def load_vms(_source_vms): | |
| with open(_source_vms) as file: | |
| vms = file.read() | |
| vms = vms.splitlines() | |
| # for vm in vms: | |
| # logger.warning(f"vm: {vm}") | |
| return vms | |
| def vMotion_vms(vcenter, vms, destination_host): | |
| _client = create_client(vcenter) | |
| if not _client: | |
| logger.critical(f"Cannot initial connection to vCenter: {vcenter}") | |
| return | |
| total_vms = 0 | |
| count = 0 | |
| error_vms = [] | |
| for vm in vms: | |
| total_vms +=1 | |
| try: | |
| migrate_vm(_client, vm, destination_host) | |
| time.sleep(1) | |
| count +=1 | |
| except BaseException as e: | |
| logger.error(f"Error:{e}/VM: {vm}") | |
| if vm not in error_vms: | |
| error_vms.append(vm) | |
| continue | |
| logger.info(f"moved: {count}/{total_vms}") | |
| # ----------- | |
| if _client: | |
| Disconnect(_client) | |
| if __name__ == "__main__": | |
| # ---- | |
| # Load vms from txt file | |
| vms = load_vms(file_vms) | |
| # VMware VM Migration From One ESXi Host to Another | |
| vMotion_vms(vcenter, vms=vms, destination_host=destination_host) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment