Learning vCO – Beginner Actions, World 1-2

Previously, I went over a very simple example of creating a VCO Action from top to bottom. Combining two input strings into one is quite the thrill ride, but let’s see if we can’t do some expanding and exploration of what we can do with Actions.

Suffice to say, Actions can be as simple or as complicated as you require. In this post, we’ll build a more complicated Action for a more specific use case. There’s a little JavaScript in here, but don’t worry – it will be well commented and should be easy to understand.

The Case

A pretty common issue as environments get larger is managing to keep VMware Tools up to speed. A simple Action you could create would dig into a VM and tell you whether it is current or not – and you could integrate that into a larger workflow that could mount up the VMware Tools and initiate an upgrade during a maintenance window.

The Action

From the Actions tab in VCO, go to your module and right-click, choosing to Add Actions.
Let’s name it something obvious…


There are a number of ways to approach the creation of this Action, but let’s say that our input parameter inputVM will be the VM itself (that is, type VC:VirtualMachine) and the return type will be a boolean, indicating whether the VMware Tools are up to date or not.


With the ins and outs defined, it’s time to write out the code. If you’re inexperienced with JavaScript or the vSphere API in general, prepare to meet your new best friend, the API Explorer. It is accessible within any scripting window, or from the main client menu under the Tools option.

Accessing API Explorer from the main client interface.
Accessing API Explorer from the main client interface.

The Explorer contains a comprehensive look at every object type – its properties and methods, a hyperlink to the types that they both expect for execution, and what they will return when called or accessed. You can drill down deeply into each object type and see what you can extract from it, and also find out what you need to build custom objects to pass to vSphere / vCenter’s API.

To Search the API Explorer, click the magnifying glass above the API Explorer.

API Explorer inside of an Action or Workflow.
API Explorer inside of an Action or Workflow.

Since you want to find out what you can get from a VC:VirtualMachine object type, search for that. When you double-click it, the parent window finds the object you clicked. It’s a little clunky, but you’ll get used to it. You can click the little arrow to the side to expand the VcVirtualMachine type and see what it has to offer.

API Explorer - Searching for type VirtualMachine.
API Explorer – Searching for type VirtualMachine.

As you can see, lots of potential goodies for you to automate or key off of.
In this case, we’re just trying to find the VMware Tools status, so go down the VcVirtualMachine property list until you find the guest property.

The Guest Information property of VcVirtualMachine.
The Guest Information property of VcVirtualMachine.

Notice at the bottom, it shows the return type of the property of inputVM.guest is VcGuestInfo. If you click that, it will take you to that type definition, and you’ll be able to see what other properties are available. Inside the VcGuestInfo list, there are a number of properties that will give you data about the status of VMware Tools. In this case we’re looking for the toolsVersionStatus property.

API Explorer - Finding the Tools Version property.
API Explorer – Finding the Tools Version property.

This property is a string, but if you look at the text, it will tell you where to find the possible values – in this case under the type VcVirtualMachineToolsVersionStatus. Click that link to see the available values that this property can return.

API Explorer - The Virtual Machine Guest Status Codes.
API Explorer – The Virtual Machine Guest Status Codes.

You now can see what the possible values are and what they represent in each situation.
So after drilling down in the API Explorer to get this data, how do we work with it?

The Code

All you really need to know is, you can access the value of the VMware Tools status using this code in your Action:

System.log("The VMware Tools status for the VM is: "+inputVM.guest.toolsVersionStatus)

It’s really that simple, at least for this particular property. With that in mind, let’s make a couple of different versions of the Action.

First Pass

You can use a simple bit of code here – this just says if it’s not current, return false. If it is current, return true.

if(inputVM.guest.toolsVersionStatus == "guestToolsCurrent") {
  // the VMware Tools are current and up to date.
  return true;
} else {
  // the VMware Tools are not where they should be.
  return false;

Pretty simple right?

But what if you want to go a little further with additional checks?

For example, a VM that isn’t powered on will be able to execute the above action, but it will just say “guestToolsNotInstalled” – which may or may not be true! Let’s re-write it a bit using some more exploration of the API.

Second Pass

In the API Explorer, go back to the VcVirtualMachine type that we started with. There’s nothing that obviously tells you the current power state here, but if you dig you’ll find the runtime property that mentions power state, leading you to the VcVirtualMachineRuntimeInfo type.

Keep drilling, and you’ll find the powerState property, giving you a list of all possible states. Let’s use this to make our Action a little more effective.

// is our VM powered on?
if(inputVM.runtime.powerState == "poweredOn") {
  // it's powered up, so let's check the tools info
  if(inputVM.guest.toolsVersionStatus == "guestToolsCurrent") {
    // the tools are current!
    return true
  } else {
    // tools are not current
    return false
} else {
  // the VM isn't powered up, so let's return false
  return false

You can just keep building on this Action if you want, or do what I do: keep it simple.
Actions and Workflows are easier to debug if your code is simpler!

Let’s add this action into a workflow with some basic decision making logic.

The Workflow

Go to the Workflows Tab, open your folder and right-click, choosing New Workflow, and name it.

The new Workflow for your Action.
The new Workflow for your Action.

After you do so, you’ll be in the Workflow Designer – choose the Schema Tab.

In the left menu, search for your Action, and drag/drop it into the Schema.

Adding the Action to your Workflow Schema.
Adding the Action to your Workflow Schema.

After that, you will again get the prompt to setup the parameters within the workflow. Click Setup, and configure it like the below:

Binding the Action's inputs and actionResult to your Workflow.
Binding the Action’s inputs and actionResult to your Workflow.

This automatically connects the inputVM parameter as an Input to the workflow, and also configures an Attribute called toolsStatus that is bound to the output of your Action. Easy!  Keep in mind, you can name the attribute whatever you want!

Once that is done, we will add a Decision element to the workflow. This allows us to create a fork in the road based on the value of an attribute, which in this case is whether the Attribute toolsStatus value is TRUE, or FALSE.

Search for a Decision element in the left window, and drag/drop it after the Action in your Schema.

Your schema, with the Decision element.
Your schema, with the Decision element.

Once the element is added, click the pencil icon above it to edit the settings. There isn’t much to change here, so go to the Decision tab. Click the link there to choose which Attribute in the workflow you wish to check on. It should be toolsStatus in this case – no binding is required for this element.

Setting up the Decision element.
Setting up the Decision element.

You now have a Workflow that can act based on the output of your Action. A few ideas to try:

  • Add the built-in workflow to Upgrade Tools, or Upgrade Tools at Next Reboot on the FALSE workflow path
  • Write a log entry indicating the tools are up to date on the TRUE workflow path

Setting these particular capabilities up are drag and drop affairs, just like adding your Actions and Scriptable Tasks. I realize it sounds lame, but the only limit to what you can do is imagination – you just have to consider your use cases and impact of your design. If you want the workflow to automatically install upgraded tools, can it be rebooted right after if needed? There are many things to consider.

In the next post, we will dive a bit deeper into working with Arrays of objects, such as ESX Hosts or Virtual Machines. Thanks for reading, and hopefully if you’re just getting started with VCO, this was helpful!


  1. Hey, is there a way to get the current CPU of the VM? I tried using inputVM.runtime.VcVirtualMachineRuntimeInfo.maxCpuUsage but I get some weird number, like – 2364, not even sure what that is… but it aint percentage 🙂

    • Well, that property returns the upper limit of possible CPU usage in MHz. So if you want to get the physical CPU information, you’re better off getting it from the host object itself.

Leave a Reply