You retrieve a property of a managed object by appending the property name to the URL, after the managed object reference. Property names always begin with a lowercase letter, matching the name in the vSphere Web Services API Reference.

For example, you can retrieve the string property HostProfile.validationState with a URL similar to this:
https://vcenter_fqdn/sdk/vim25/8.0.1.0/hostprofile_mo_ref/validationState
Note: You cannot modify properties directly. To modify properties of a managed object, you must invoke a method of the managed object or a related managed object that affects its state on the server.

Retrieving Nested Properties

You can retrieve a top-level property by naming it in the URL, but nested properties are not directly accessible. Many top-level properties are data objects or arrays, containing nested properties of interest. To access nested properties, first retrieve the top-level property, then deserialize the JSON in the response body. After deserialization, you can access the nested properties of the data object or array in the client.

For example, code this request:
GET https://vcenter_fqdn/sdk/vim25/8.0.1.0/vm_mo_ref/runtime
Then extract and display the nested property like this:
data_object = json.loads(response_body)
state = data_object['powerState']
print('VM powerState = ' + state)
The nested property displays.
VM powerState = poweredOff

Retrieving Managed Object Reference Properties

Managed objects often have properties to reference other managed objects. In these cases, you can use a GET request to obtain the managed object reference, but to access the properties or methods of the other managed object you must issue a new GET request, using the managed object reference in the request URL.

If you need to follow a chain of managed object references, you can avoid extra requests by using the PropertyCollector managed object. The purpose of the PropertyCollector is to delegate the search functions to the server, where they can be done more efficiently.

Using the Property Collector to Retrieve Object Properties

You can use the PropertyCollector to retrieve properties from one or more managed objects, whether or not they are related to each other, if you can specify the set of objects in your request. The PropertyCollector provides a flexible interface by which you can specify search criteria to execute in the server.

To specify a property retrieval, several approaches are available to you. A few of them are:
  • Provide a managed object reference and a set of its properties that you want to retrieve.
  • Provide a managed object reference as a starting point for a search that traverses inventory paths to find related managed objects and return their properties.
  • Provide a reference to a previous search set as a starting point for a traversal search, often directed to the managed objects contained in the set.

This example shows a hybrid approach where you first locate a Datacenter managed object by using the SearchIndex method. Then you use that managed object as a starting point to traverse to VirtualMachine objects in the data center's virtual machine folder. If there are subfolders within the virtual machine folder, the search specifications traverse the subfolders recursively.

The goal of this example is to report whether the virtual machines are powered on or powered off. That information is in the VirtualMachine.runtime.powerState property.

The powerState property is a nested property of the virtual machine, so you need to locate the VirtualMachine managed objects and specify a property within the runtime data object belonging to each VirtualMachine. The JSON protocol has the ability to retrieve the entire runtime data object as a single property, but the PropertyCollector is able to extract the nested property in a single query.

Use the following procedure to build a server-side specification that retrieves the power states of virtual machines in the data center's virtual machine folder.

Note: For simplicity, this procedure ignores vApps.
  1. Build a PropertySpec data object to identify the managed object type (VirtualMachine) and the nested property name (runtime.powerState).
    propSet = [ {'_typeName': 'PropertySpec', 
                 'type': 'VirtualMachine', 'pathSet': ['runtime.powerState'], 'all': False}]

    The all property, if True, overrides the pathSet property and collects all properties of the managed object. This behavior is useful if you want to maintain a client-side copy in synch with the server-side managed object.

  2. (Optional) If it helps to clarify the inventory paths to the virtual machines, sketch VirtualMachine objects and their parent managed objects, all the way up the chain to the starting Datacenter managed object.
    Part of inventory showing traversal paths

    For each path between managed objects, note the name of the property in the parent object that links to the child object. You must create a TraversalSpec (or a SelectionSpec reference to a TraversalSpec) to follow each of those links to the next managed object. The VirtualMachine managed objects whose properties you want to retrieve do not need TraversalSpec objects.

  3. Working backwards from VirtualMachine objects to Datacenter object, create a named TraversalSpec data object for each path segment.
    traverse_folder = {'_typeName': 'TraversalSpec'}
    traverse_folder['name'] = 'traverse_folder'
    traverse_folder['type'] = 'Folder'
    traverse_folder['path'] = 'childEntity'
    traverse_folder['skip'] = False
    
    dc_to_vmfolder = {'_typeName': 'TraversalSpec'}
    dc_to_vmfolder['name'] = 'dc_to_vmfolder'
    dc_to_vmfolder['type'] = 'Datacenter'
    dc_to_vmfolder['path'] = 'vmFolder'
    dc_to_vmfolder['skip'] = True

    You do not need a TraversalSpec for the VirtualMachine object, because it is a leaf object in the traversal tree. You do need a TraversalSpec for the Datacenter object and the Folder object, so the PropertyCollector will know how to traverse down the chain to the child objects. The skip property is an optimization. It tells the PropertyCollector that the next managed object after the traversal can be traversed without checking the PropertySpec.

    Note: The TraversalSpec.selectSet[] property is not yet set. You will use it to link the specs together.
  4. If your data center might have nested folders inside its VM folder, create a SelectionSpec data object that specifies the name of the TraversalSpec for Folder objects, so the PropertyCollector can follow the childEntity path recursively for any nested folders it finds.
    folder_recursion = {'_typeName': 'SelectionSpec', 'name': 'traverse_folder'}
  5. Link the TraversalSpec objects together by using the selectSet[] property to build a managed object traversal chain.
    traverse_folder['selectSet'] = [folder_recursion]
    dc_to_vmfolder['selectSet'] = [traverse_folder]
  6. Create an ObjectSpec data object to specify starting from your Datacenter managed object, and to direct the PropertyCollector to the TraversalSpec that leads to the top-level VM folder.
    objectSet = [{'_typeName': 'ObjectSpec',
                  'obj': dc_moref, 'skip': False, 
                  'selectSet': [dc_to_vmfolder] }]

    The skip property in the ObjectSpec is different from the skip property in a TraversalSpec. In the ObjectSpec, it tells the PropertyCollector that the starting object is not one of the managed objects it is looking for.

  7. Combine the PropertySpec and the ObjectSpec into a PropertyFilterSpec that will be a parameter to the PropertyCollector.RetrievePropertiesEx method.
    specSet = [{'_typeName': 'PropertyFilterSpec',
                'propSet': propSet, 'objectSet': objectSet}]
  8. Specify the RetrievePropertiiesEx method parameters in the request body.
    import json
    param_dict = {'options': {'_typeName': 'RetrieveOptions',
                              'maxObjects': 1000}, 'specSet': specSet}
    request_body = json.dumps(param_dict).encode('utf-8')
  9. Send the request, using the POST verb.
    from urllib.request import urlopen, Request
    import ssl
    moref = si_content['propertyCollector']
    method = 'RetrievePropertiesEx'
    url = make_url(domain, mo=moref, m_p=method)
    request_headers = {}
    request_headers['vmware-api-session-id'] = token
    request_headers['Content-Type'] = 'application/json'
    headers['Content-Type'] = 'application/json'
    # Skip certificate verification on test systems only:
    unverified_context = ssl._create_unverified_context()
    request = Request(url, headers, data=body)
    with urlopen(request, context=unverified_context) as response :
      response_headers = response.headers
      response_body = response.read()
    json_body = json.loads(response_body)
    print(json_body)

The results are returned in a RetrieveResult data object, which encloses an array of ObjectContent data objects. Each ObjectContent contains a managed object reference and a corresponding array of named properties found by the PropertyCollector that match your PropertySpec. For this example, the managed object references identify VirtualMachine objects, and the property name-value pairs show the powerState of each VirtualMachine.