Recently I posted about “how did I get started with pyvmomi?”. I continued exploring this further and I thought to share my learning so far. After setting up the pyvmomi environment, first thing I wanted to learn was to get hold of all core vCenter inventory objects so that I can play around each of them. vCenter core inventory includes objects such as Datacenters, Clusters, Virtual Machines, Hosts, Datastores & Networks etc.
As an initial step, I was looking for a way to get below objects from VC inventory
-All Virtual Machines
-All Clusters
-All Hosts
-All Datacenters
There could be multiple ways to get above objects but below is the way I could achieve this.
[python]
from pyVim.connect import SmartConnect
from pyVmomi import vim
import ssl
# Get all the Vms from vCenter server inventory and print its name
# Below is Python 2.7.x code, which can be easily converted to python 3.x version
s=ssl.SSLContext(ssl.PROTOCOL_TLSv1)
s.verify_mode=ssl.CERT_NONE
si= SmartConnect(host="10.192.3.2", user="[email protected]", pwd="$h1vKamal",sslContext=s)
content=si.content
# Method that populates objects of type vimtype
def get_all_objs(content, vimtype):
obj = {}
container = content.viewManager.CreateContainerView(content.rootFolder, vimtype, True)
for managed_object_ref in container.view:
obj.update({managed_object_ref: managed_object_ref.name})
return obj
#Calling above method
getAllVms=get_all_objs(content, [vim.VirtualMachine])
#Iterating each vm object and printing its name
for vm in getAllVms:
print vm.name
[/python]
Output:
vmware@localhost:~$ python getAllVms.py
Database-server
NTP-Bangalore
Web-server
NTP-Pune
vmware@localhost:~$
You could see above, script listed all the VMs available in inventory. Let us look at another example, here we will get all the clusters from vCenter Inventory.
[python]
from pyVim.connect import SmartConnect
from pyVmomi import vim
import ssl
#Get all the Clusters from vCenter invetory and printing its name
#Below is Python 2.7.x code, which can be easily converted to python 3.x version
s=ssl.SSLContext(ssl.PROTOCOL_TLSv1)
s.verify_mode=ssl.CERT_NONE
si= SmartConnect(host="10.192.3.2", user="[email protected]", pwd="$h1vKamal",sslContext=s)
content=si.content
# Method that populates objects of type vimtype
def get_all_objs(content, vimtype):
obj = {}
container = content.viewManager.CreateContainerView(content.rootFolder, vimtype, True)
for managed_object_ref in container.view:
obj.update({managed_object_ref: managed_object_ref.name})
return obj
#Calling above method
clusters=get_all_objs(content, [vim.ClusterComputeResource])
#Iterating each cluster object and printing its name
for cluster in clusters:
print (cluster.name)
[/python]
Output:
vmware@localhost:~$ python getClusters.py
DRSCluster-USA
DRSCluster-Europe
DRSCluster-India
vmware@localhost:~$
If you notice, only important change from getAllVms and getClusters script is line #22, is not it cool? So now we were able to get all the VMs as well as all the clusters. Similarly we can get other core inventory objects such as datacenter, hosts, datastores, networks etc. Below is how line #22 will look for other vCenter/ESXi objects.
[python]
# For ESXi host
hosts=get_all_objs(content, [vim.HostSystem])
#For datacenters
dcs = get_all_objs(content, [vim.Datacenter])
#For datastores
datastores = get_all_objs(content, [vim.Datastore])
[/python]
By now we know how to get hold of vSphere inventory objects, let’s do something meaningful with these objects. I chose to call a method on one of clusters that we retrieved above. What is that method?
vCenter 6.0 has introduced one of interesting APIs on vSphere DRS cluster rules. i.e. findRulesForVM(). This method is called on individual cluster and it returns set of DRS VM-VM affinity rules (enabled or disabled) those are associated with given/input VM. Since this method returns VM-VM affinity rules, I first created some VM-VM rules on one of my clusters as follows.
Now that DRS rules are created, let us pass VM name as parameter to “findRulesForVM()” API and call this API on that cluster.
Updated code is available on VMware sample exchange portal here
[python]
from pyVim.connect import SmartConnect
from pyVmomi import vim
import ssl
#Get DRS VM-VM rules associated with a VM.
s=ssl.SSLContext(ssl.PROTOCOL_TLSv1)
s.verify_mode=ssl.CERT_NONE
si= SmartConnect(host="10.192.3.2", user="[email protected]", pwd="$vabc325pqr",sslContext=s)
content=si.content
def get_all_objs(content, vimtype):
obj = {}
container = content.viewManager.CreateContainerView(content.rootFolder, vimtype, True)
for managed_object_ref in container.view:
obj.update({managed_object_ref: managed_object_ref.name})
return obj
# Scanning a input VM inside inventory using special python construct i.e. List comprehension
# It will get all the Vms and check whether input VM is available inside inventory or not, finally it returns list with matching condition
vmToScan = [vm for vm in get_all_objs(content,[vim.VirtualMachine]) if "NTP-Bangalore" == vm.name]
# Scanning a input cluster inside invetory the way we did for VM above. here also we used list comprehension.
cluster = [cluster for cluster in get_all_objs(content,[vim.ClusterComputeResource]) if "DRSCluster-India" == cluster.name]
# Now we can call the method on input cluster by passing input VM as parameter, it returns array of rule objects associated with input VM.
ClusterRuleInfo=cluster[0].FindRulesForVm(vmToScan[0])
# Now iterate through rule objects and print the rule name
for rule in ClusterRuleInfo:
print rule.name
[/python]
Output:
vmware@localhost:~$ python findRules.py
Anti-Affine-NTP-Servers
Affine-Web-DB-Servers
Here is how vSphere web client “recent task” looks, you could see “Find Rules for vms” task.
Notes:
-For the sake of simplicity, I have hard-coded some values and simplified the code, please make changes as per your requirement.
-I have added required documentation inside above code itself.
-This code follows mostly python 2.7.x version, please make minor changes to work with python 3.x
If you need any help, please let me know and yes, please stay tuned for my upcoming blog posts on pyVmomi.
Vikas Shitole is a Staff engineer 2 at VMware (by Broadcom) India R&D. He currently contributes to core VMware products such as vSphere, VMware Private AI foundation and partly VCF . He is an AI and Kubernetes enthusiast. He is passionate about helping VMware customers & enjoys exploring automation opportunities around core VMware technologies. He has been a vExpert since last 11 years (2014-24) in row for his significant contributions to the VMware communities. He is author of 2 VMware flings & holds multiple technology certifications. He is one of the lead contributors to VMware API Sample Exchange with more than 35000+ downloads for his API scripts. He has been speaker at International conferences such as VMworld Europe, USA, Singapore & was designated VMworld 2018 blogger as well. He was the lead technical reviewer of the two books “vSphere design” and “VMware virtual SAN essentials” by packt publishing.
In addition, he is passionate cricketer, enjoys bicycle riding, learning about fitness/nutrition and one day aspire to be an Ironman 70.3
Hello, What is the python command lets for DrsVMHostRule. I am trying to write a pyton script where i can list all the Linux VM and add to DrsClusterGroup and also want to enable the DrsVMHostRule which can enable the rule.
Hi Sathya,
Sorry for late response. Here is Java equivalent for cteating VM-Host DRS rules. You can refer it and write equivalent in python: https://vthinkbeyondvm.com/drs-rules-part-i-how-to-create-vm-host-drs-affinity-rule-using-vsphere-api/
Let me know if you need any help
I like the post and that help me alot
Is there any python script or vpshere api to collect information like full folder path,datacenter and datastore for vm’s from multiple vcenters.
Yes, we can write a script, which can connect to multiple vCenters, call existing vSphere APIs to collect required info. Let me know your detailed use-case, I will see if there is existing script available or can help write such script.
Hi, I am trying to convert the VM to template how we can achieve this. Please help me
Hi Pavan,
You can use MarkAsTemplate() API to convert VM into Template.
This is vSphere API reference : http://pubs.vmware.com/vsphere-6-5/index.jsp?topic=%2Fcom.vmware.wssdk.apiref.doc%2Fvim.VirtualMachine.html , please search for “MarkAsTemplate” into this API reference. If you need additional help, please let me know
Hi,
Firstly, both your posts about pyvmomi were really good. It was really helpful for a beginner.
I have a use case currently where i have to create 100’s of vm’s (of small size~light weighted) with one nic(unique ip address for each vm). Then, i would like to power ON/OFF these vm’s at random times through out the day.
Can you please give me some quick pointers on which apis/methods to call and make this happen ?
Thanks,
Harish
In the first code chunk the below statement makes sense.
content=si.content
In the next code chunks, what is c.content?
content=c.content
Shouldn’t it be si.content , is it a typo? or am I missing something here?
Yes, it was typo. I have corrected it now. Thanks for pointing out.
Great article. How do u find specific hosts for the cluster?
Hi
I am getting this error:
ssl.SSLEOFError: EOF occurred in violation of protocol (_ssl.c:579)
Any help would we greatly appreciated.
getting this error
File “C:/Users/tkw/PycharmProjects/python/getallvms.py”, line 15
def get_all_objs(content, vimtype):
^
SyntaxError: invalid syntax
Process finished with exit code 1
I am not sure why I am getting no output on this?
from pyVim.connect import SmartConnect
from pyVmomi import vim
import ssl
# Get all the Vms from vCenter server inventory and print its name
# Below is Python 2.7.x code, which can be easily converted to python 3.x version
s = ssl.SSLContext(ssl.PROTOCOL_SSLv23) # For VC 6.5/6.0 s=ssl.SSLContext(ssl.PROTOCOL_TLSv1)
s.verify_mode = ssl.CERT_NONE
# s = ssl.SSLContext(ssl.PROTOCOL_TLSv1)
#s.verify_mode = ssl.CERT_NONE
si = SmartConnect(host=”10.50.1.20″, user=”[email protected]”, pwd=”Password123@”, sslContext=s)
content = si.content
# Method that populates objects of type vimtype
def get_all_objs(content, vimtype):
obj = {}
container = content.viewManager.CreateContainerView(content.rootFolder, vimtype, True)
for managed_object_ref in container.view:
obj.update({managed_object_ref: managed_object_ref.name})
return obj
# Calling above method
getAllVms = get_all_objs(content, [vim.VirtualMachine])
# Iterating each vm object and printing its name
for vm in getAllVms:
print
vm.name
Hi,
#getAllVms = get_all_objs(content, [vim.VirtualMachine])
How do the execute this command
Get-VMHost | Export-Csv C:\Users\memm\Desktop\test.csv
Hi Guys,
I am using my customer existing environment, where i have to collect the esxi host hba path status like dead, active , and i have to clear the dead paths by scanning the HBA’s and datatstore, can you help me with the script where i can achieve this ??
Hi,
I am using python 3.8 and and when executing the statement “from pyVmomi import vim” and not able to import the vim . Can you please help what can be the issue.