Created
January 6, 2021 08:51
-
-
Save menvol3/07df3bf5ea75fc9cfffa8e0c3d0dbf53 to your computer and use it in GitHub Desktop.
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
import argparse | |
import atexit | |
import getpass | |
import time | |
from pyVim import connect | |
from pyVmomi import vim | |
def get_args(): | |
parser = argparse.ArgumentParser() | |
parser.add_argument('-s', '--host', | |
required=True, | |
action='store', | |
help='Remote host to connect to') | |
parser.add_argument('-o', '--port', | |
required=False, | |
action='store', | |
help="port to use, default 443", default=443) | |
parser.add_argument('-u', '--user', | |
required=True, | |
action='store', | |
help='User name to use when connecting to host') | |
parser.add_argument('-p', '--password', | |
required=False, | |
action='store', | |
help='Password to use when connecting to host') | |
args = parser.parse_args() | |
password = None | |
if args.password is None: | |
password = getpass.getpass( | |
prompt='Enter password for host %s and user %s: ' % | |
(args.host, args.user)) | |
args = parser.parse_args() | |
if password: | |
args.password = password | |
return args | |
args = get_args() | |
service_instance = connect.SmartConnectNoSSL(host=args.host, user=args.user, pwd=args.password, port=args.port) | |
si = service_instance.content.searchIndex | |
atexit.register(connect.Disconnect, si) | |
content = service_instance.RetrieveContent() | |
datacenter = content.rootFolder.childEntity[0] | |
cluster = datacenter.hostFolder.childEntity[0] | |
print("Selected datacenter: " + datacenter.name) | |
viewType = [vim.HostSystem] # object types to look for | |
recursive = True # whether we should look into it recursively | |
containerView = content.viewManager.CreateContainerView(datacenter, viewType, recursive) | |
hosts_in_datacenter = containerView.view | |
container = content.viewManager.CreateContainerView(datacenter, [vim.ComputeResource], True) | |
cluster_resource_container = container.view[0] | |
def addOrRemoveKey(vm, device, remove=False): | |
""" | |
add or remove a single key to the specified agent | |
""" | |
usb_changes = [] | |
vm_spec = vim.vm.ConfigSpec() | |
usb_spec = vim.vm.device.VirtualDeviceSpec() | |
if remove: | |
usb_spec.operation = vim.vm.device.VirtualDeviceSpec.Operation.remove | |
else: | |
usb_spec.operation = vim.vm.device.VirtualDeviceSpec.Operation.add | |
# check if the device is provided as a VirtualUSB object or as a string | |
# the string would be the usb path from the vSphere server. It looks like this: | |
# path: 1/2/3/4... verison: 2 | |
if str == type(device): | |
usb_spec.device = vim.vm.device.VirtualUSB() | |
usb_spec.device.backing = vim.vm.device.VirtualUSB.USBBackingInfo() | |
usb_spec.device.backing.deviceName = device | |
else: | |
usb_spec.device = device | |
usb_changes.append(usb_spec) | |
# here the device gets attached or removed | |
vm_spec.deviceChange = usb_changes | |
e = vm.ReconfigVM_Task(spec=vm_spec) | |
# wait until the task is done | |
while e.info.state == vim.TaskInfo.State.running: | |
time.sleep(1) | |
# some error "handling" | |
if e.info.state == vim.TaskInfo.State.error: | |
msg = "Error adding {0} to {1}" | |
if remove == True: | |
msg = "Error removing {0} from {1}" | |
if str == type(device): | |
print(msg.format(device, vm.name)) | |
else: | |
print(msg.format(device.backing.deviceName, vm.name)) | |
print("--------------------------") | |
print("VCenter error message") | |
print(e.info.error) | |
print("--------------------------") | |
return False | |
return True | |
for host in hosts_in_datacenter: | |
usb_devices_connected_to_host = [] | |
usb_devices_connected_to_vm = [] | |
first_virtual_machine = host.vm[0] | |
for resource_container in cluster_resource_container.host: | |
if host.name != resource_container.name: | |
continue | |
host_info = cluster_resource_container.environmentBrowser.QueryConfigTarget(host) | |
if len(host_info.usb) < 1: | |
print('No USB device is connected to host' + host.name) | |
else: | |
print('----------------------------------------------------') | |
print('List of connected usb devices to host ' + host.name) | |
print('---------------------') | |
for usb in host_info.usb: | |
usb_devices_connected_to_host.append(usb.physicalPath) | |
print(usb.description, usb.physicalPath) | |
print('---------------------') | |
for device in first_virtual_machine.config.hardware.device: | |
if not isinstance(device, vim.vm.device.VirtualUSB): | |
continue | |
usb_devices_connected_to_vm.append(device.backing.deviceName) | |
for usb_device in usb_devices_connected_to_host: | |
if usb_device not in usb_devices_connected_to_vm: | |
addOrRemoveKey(first_virtual_machine, usb_device) | |
print('Usb device {} was connected to vm: "{}"'.format(usb_device, first_virtual_machine.name)) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment