vmware-pythonThere is a lot of attention for PowerCLI for the day to day automation of your VMware infrastructure. But what if you don’t have
or want Windows machines? When you are using your Mac or Linux machine for maintenance you have to create a virtual machine with Windows especially for PowerCLI.

Use Python

Or you could just use Python. Next to PowerCLI VMware released vSphere API bindings for various programming languages. The vSphere API Python bindings is one of them. The benefit of using Python for your VMware management is that it is cross platform. You can’t compare it to PowerCLI easily. Retrieving the specifications for a virtual machines takes a little more code than in PowerCLI. However, for the sake of cross platform support I think it is a small price to pay.

If you’re already familiar with Python and virtualenv, jump to “Installing the vSphere API Bindings

What is Python

Python was created by Guido van Rossum. According to Wikipedia Python is:

a widely used high-level, general-purpose, interpreted, dynamic programming language. Its design philosophy emphasizes code readability, and its syntax allows programmers to express concepts in fewer lines of code than possible in languages such as C++ or Java. The language provides constructs intended to enable clear programs on both a small and large scale.

I do think Python is easy to read, but coming from other languages the ‘Pythonic way’ is not always what you would expect. For example the whole ‘EAFP – easier to ask for forgiveness than permission’, although it is comparable to the ‘Try..Catch..Finally’ construct in PowerShell. The only thing I had to really get used to (and still struggle with) is the way indentation works to tell what is part of a loop or function compared to the ‘{..}’  in PowerShell. For example a loop in PowerShell looks like:

ForEach ($number in 1,2,3,4,5) {
      Write-Host "The number is $number"
}

And it would return

The number is 1
The number is 2
The number is 3
The number is 4
The number is 5

While  in Python you would do the following to get the same result.

for number in [1,2,3,4,5]):
    print ("The number is {}".format(number))

If you forget the indentation the command would fail.

File "<stdin>", line 2
print (number)
^
IndentationError: expected an indented block

If you want to know more about the language itself, check out the interactive tutorial at learnpython.org.

Installing Python

On most Linux versions and on Mac Python is already installed. Check with python –version  which version you are running. If it is not current, upgrade to 2.7 or 3.
For a complete installation guide see the Hitchhiker’s Guide to Python
For Windows you can download from the Python site at https://www.python.org/downloads/ and install it like a regular program.

If you need specific packages/libraries you can install them with the Python package manager, pip.

pip install <name>

Virtual environments

To prevent conflicts between the modules and packages you need for your script/program and modules and packages already on your system you can create a virtual environment. A virtual environment for Python is a tool to keep the dependencies required by different projects in separate places, by creating virtual Python environments for them. With the tool virtualenv you create such a virtual environment. It creates a directory with all relevent tools and libraries, like the Python executable.

With virtualenv .env  you create a virtual environment.

If you get -bash: virtualenv: command not found  you need to install virtualenv with pip, just like the packages you need for your scripts:

pip install virtualenv

After creating your virtual environment you activate it with source .env/bin/activate (Linux/Mac) or .env/Scripts/activate (Windows), assuming that you created the environment in .env.

Deactivating a virtual environment is easy: deactivate . After this everything is pointing to the system wide Python installation. Libraries and packages will be installed in the system wide library folders.

Installing the vSphere API Python bindings

Installing the vSphere API Python bindings in your virtual environment is easy. Install it with pip install pyvmomi

Writing your first script

If you’re completely new to Python you can check out learnpython.org. It contains an interactive tutorial that teaches you the ins and outs of Python.

The logic of the scripts for pyvmomi is pretty much the same every time:

  • Connect to a vCenter server and get a service instance
  • Retrieve information
  • Navigate the hierarchy, starting at the root folder
  • Manipulate the managed objects

The script below retrieves all virtual machines in your vCenter and returns the name and the status of the VMware tools.

In short, the script:

  • Connects to vCenter service_instance = connect.SmartConnect( .. )
  • Retrieves information content = service_instance.RetrieveContent()
    • Which object to search for viewType = [vim.VirtualMachine]
    • Create a container view containerView = content.viewManager.CreateContainerView ( .. )
    • Navigate the hierarchy, starting at the root folder container = content.rootFolder
  • Loop through all virtual machines and print tools status
    for child in children:
                if child.summary.guest is not None:
                    try:
                        tools_version = child.summary.guest.toolsStatus
                        print("VM: {}, VMware-tools: {}".format(child.name, tools_version))

Save the script below, change the variables host, user, password and port to your situation and run it with python <scriptname>.py

#Ensure Python 2/3 compatibility
from __future__ import (absolute_import, division,
                        print_function, unicode_literals)
from builtins import *

import atexit

from pyVim import connect
from pyVmomi import vmodl
from pyVmomi import vim


host="vcenterserver"
user="administrator@vsphere.local"
password="password"
port=443


# If you use self signed certificates Python will not connect.
# This will give you an error for the check, but continues.
import ssl
try:
    _create_unverified_https_context = ssl._create_unverified_context
except AttributeError:
    # Legacy Python that doesn't verify HTTPS certificates by default
    pass
else:
    # Handle target environment that doesn't support HTTPS verification
    print ("There was an error with the SSL certificates. Continuing..")
    ssl._create_default_https_context = _create_unverified_https_context

def main():
    try:
        service_instance = connect.SmartConnect(host=host,
                                                user=user,
                                                pwd=password,
                                                port=port)

        # What to do when exiting
        atexit.register(connect.Disconnect, service_instance)

        
        content = service_instance.RetrieveContent()

        container = content.rootFolder  # starting point to look into
        viewType = [vim.VirtualMachine]  # object types to look for
        recursive = True  # whether we should look into it recursively

        # Create a view
        containerView = content.viewManager.CreateContainerView(
            container, viewType, recursive)

        # Loop through all obhects to return name and VMware tools version
        children = containerView.view
        for child in children:
            if child.summary.guest is not None:
                try:
                    tools_version = child.summary.guest.toolsStatus
                    print("VM: {}, VMware-tools: {}".format(child.name, tools_version))
                except:
                    print("Vmware-tools: None")

    except vmodl.MethodFault as error:
        print("Caught vmodl fault : " + error.msg)
        return -1

    return 0

# Start program
if __name__ == "__main__":
    main()

Making the script version proof

At the moment there are two versions of Python, namelijk Python 2 and Python 3. Python 3 is the version we all should be going to, but Python 2 is widely spread and is default in a lot of operating systems, like Mac and Linux distributions.

To make sure your script runs on Python 3 as well as on Python 2 you can install the ‘future’ module and add a couple of lines to your scripts:

First: pip install future

Then in your script:

from __future__ import (absolute_import, division,
                        print_function, unicode_literals)
from builtins import *

I Want to know more about Python and pyvmomi