Click here to Skip to main content
14,359,465 members

Automating VMWare Tasks in C# with the VIX API

Rate this:
4.98 (31 votes)
Please Sign up or sign in to vote.
4.98 (31 votes)
13 Feb 2009MIT
A VMWare C# tasks library.


I've been playing with VMware lately, both Workstation and VMware Infrastructure (VI). The company has really stepped up with the new SDKs and the level of programmable interfaces, making some excellent implementation decisions that enable developers to drive virtual machines programmatically with an asynchronous, job-based programming model. Unfortunately that turns out to be too complicated for 99.9% of scenarios and most developers want to use a simple object-oriented interface for common VMWare tasks. The VMWareTasks library implements that interface and makes programming against virtual machine a no brainer. This article explains how to use the library and discusses some of its implementation details.


There're two types of VMWare APIs.

  • VMWare Virtual Infrastructure SDK: a set of tools and APIs to manage a VMWare Infrastructure environment. A toolkit has also been released that contains managed wrappers on top of the SOAP interface provided by a VMWare deployment. It's focused on VMWare ESX or VirtualCenter management and is beyond the scope of this article.
  • VMWare VIX API. The VIX API allows developers to write programs and scripts that automate virtual machine operations, as well as the guests within virtual machines. It runs on both Windows and Linux and supports management of VMware Server, Workstation, and Virtual Infrastructure (both ESX and vCenter). Bindings are provided for C, Perl, and COM (Visual Basic, VBscript, C#). In this post, I'll focus on the C# implementation.

Using the Library

In order to use the library or build or run the source code, you must install the following VMWare software.

In your project, add a reference to Vestris.VMWareLib.dll and a namespace reference.

using Vestris.VMWareLib;

You can now connect to a local VMWare Workstation or a remote ESX server and perform VMWare tasks. Here's an example that creates, restores, powers on and removes a snapshot on a VMWare Workstation.

// declare a virtual host
VMWareVirtualHost virtualHost = new VMWareVirtualHost();
// connect to a local (VMWare Workstation) virtual machine
// open an existing virtual machine
VMWareVirtualMachine virtualMachine = virtualHost.Open("C:\Virtual Machines\xp\xp.vmx");
// power on this virtual machine
// login to the virtual machine
virtualMachine.Login("Administrator", "password");
// run notepad
virtualMachine.RunProgramInGuest("notepad.exe", string.Empty);
// create a new snapshot
string name = "New Snapshot";
// take a snapshot at the current state
virtualMachine.Snapshots.CreateSnapshot(name, "test snapshot");
// power off
// find the newly created snapshot
VMWareSnapshot snapshot = virtualMachine.Snapshots.GetNamedSnapshot(name);
// revert to the new snapshot
// delete snapshot


The following sections describe VMWareTasks library implementation details. It's absolutely not necessary to understand those in order to use the library.

Connecting to VMWare in pure VIX API

Connecting synchronously to either a local VMWare Workstation or an ESX server is virtually identical. The ESX server requires a URL to the SOAP SDK (eg. https://esxserver/sdk) and a username and password.

public IHost ConnectToVMWareWorkstation()
		string.Empty, 0, string.Empty, string.Empty);

public IHost ConnectToVMWareVIServer(string hostName, int hostPort, 
			string username, string password)
    return Connect(Constants.VIX_SERVICEPROVIDER_VMWARE_VI_SERVER,  
			hostName, hostPort, username, password);

public IHost Connect(int hostType, string hostName, int hostPort, 
			string username, string password)
    VixLib vix = new VixLib();
    IJob vmJob = vix.Connect(Constants.VIX_API_VERSION, hostType, 
		hostName, hostPort, username, password, 0, null, null);
    // You need to get the IHost object that represents the host 
    // where your VM is located.
    // Since COM allocates the object you need to use this funky mechanism 
    // to extract the IHosts array.
    object[] properties = { Constants.VIX_PROPERTY_JOB_RESULT_HANDLE };
    // Wait for the operation to complete
    object hosts = VmwareVixInterop.Wait(vmJob, properties);
    object[] hostArray = hosts as object[];
    return (IHost) hostArray[0];

You have to declare an array of properties that you want the job to produce, start a VMWare job and examine the results for the host handle. You can see how cumbersome this is! The API was originally designed for C, then extended to COM with a very limited object model: a number of interfaces were declared, but no corresponding COM classes have been implemented. Also, because the job interface is generic, there're no strongly typed results.

We can easily fill this gap in our C# implementation.

Transforming Error Codes into Exceptions

The first task for wrapping any API is to implement error handling. Our managed implementation must translate error codes into managed exceptions. VIX API provides an implementation for the IVixLib interface which contains a couple of helper methods (very C-programmer). We'll be interested in IVixLib.ErrorIndicatesFailure and IVixLib.GetErrorText combined with a new class, VMWareException.

public abstract class VMWareInterop
    public static VixLib Instance = new VixLib();

    public static void Check(ulong errCode)
        if (Instance.ErrorIndicatesFailure(errCode))
            throw new VMWareException(errCode);

Aside from the abstract VMWareInterop, our goal is to produce concrete classes that wrap various aspects of VMWare functionality.

Base VMWareVixHandle

VMWare COM API returns interface pointers such as ISnapshot. The objects also implement IVixHandle which gives access to a set of object properties. We will base-class everything on VMWareVixHandle.

public class VMWareVixHandle<T>
    protected T _handle = default(T);

    protected IVixHandle _vixhandle
            return (IVixHandle) _handle;

    public VMWareVixHandle()


    public VMWareVixHandle(T handle)
        _handle = handle;

    public object[] GetProperties(object[] properties)
        object result = null;
        VMWareInterop.Check(_vixhandle.GetProperties(properties, ref result));
        return (object[]) result;

    public R GetProperty<R>(int propertyId)
        object[] properties = { propertyId };
        return (R) GetProperties(properties)[0];

Implementing VMWareJob

Since all operations in VMWare are job-based, let's wrap up a job. If we use the COM API directly, we would have to call IVixLib.Wait passing a job handle. In an object-oriented library, this operation belongs inside the job, plus a job is also a VMWareVixHandle.

public class VMWareJob : VMWareVixHandle<IJob>
    public VMWareJob(IJob job)
        : base(job)


    public void Wait()

One very common problem in VMWare API implementations that transform an asynchronous job into a synchronous one is to use the blocking wait above. This is a bad design decision since this call may never return. VMWare server may timeout or someone can pull the network cable, leaving your program hanging. I originally wrote a busy wait where all externally visible wait functions were based on the following InternalWait.

private void InternalWait(int timeoutInSeconds)
    if (timeoutInSeconds == 0)
        throw new ArgumentOutOfRangeException("timeoutInSeconds");

    // active wait for the job to finish
    bool isComplete = false;
    while (!isComplete && timeoutInSeconds > 0)
        VMWareInterop.Check(_handle.CheckCompletion(out isComplete));
        if (isComplete) break;

    if (timeoutInSeconds == 0)
        throw new TimeoutException();

A more elegant implementation combines a callback mechanism provided by VixCOM with every asynchronous API and a blocking wait with a timeout. Wait is now signaled and there's no CPU spin waiting for completion of an asynchronous API call.

public class VMWareJobCallback : ICallback
    #region ICallback Members

    private EventWaitHandle _jobCompleted = new EventWaitHandle(
         false, EventResetMode.ManualReset);

    public void OnVixEvent(IJob job, int eventType, IVixHandle moreEventInfo)
        switch (eventType)
            case VixCOM.Constants.VIX_EVENTTYPE_JOB_COMPLETED:

    public bool TryWaitForCompletion(int timeoutInMilliseconds)
        return _jobCompleted.WaitOne(timeoutInMilliseconds, false);

    public void WaitForCompletion(int timeoutInMilliseconds)
        if (!TryWaitForCompletion(timeoutInMilliseconds))
            throw new TimeoutException();


This and some generic code in VMWareJob can now be used inside Connect. I have modified VMWareJob to require a VMWareCallback in order to prevent callers from ever having a blocking wait.

VMWareJobCallback callback = new VMWareJobCallback();
VMWareJob job = new VMWareJob(VMWareInterop.Instance.Connect(
	hostName, hostPort, username, password, 0, null, callback), callback); 


With VMWareJob and VMWareException, it's now possible to implement VMWareVirtualHost and connect to it. Note references to default timeouts (a collection of constants) and some facilities in VMWareJob that add strong typing into VMWare job results.

public class VMWareVirtualHost
    private IHost _host = null;

    public VMWareVirtualHost()


    public void ConnectToVMWareWorkstation()

    public void ConnectToVMWareWorkstation(int timeoutInSeconds)
            string.Empty, 0, string.Empty, string.Empty, timeoutInSeconds);

    private void Connect(int hostType, string hostName, 
	int hostPort, string username, string password, int timeout)
        int serviceProvider = (int)serviceProviderType;
        VMWareJobCallback callback = new VMWareJobCallback();
        VMWareJob job = new VMWareJob(VMWareInterop.Instance.Connect(
            Constants.VIX_API_VERSION, serviceProvider, hostName, hostPort,
            username, password, 0, null, callback), callback);

        _handle = job.Wait
<ihost />(Constants.VIX_PROPERTY_JOB_RESULT_HANDLE, timeout);
        _serviceProviderType = serviceProviderType;

VMWareVirtualHost can now implement opening of an actual virtual machine and return an instance of VMWareVirtualMachine.

public VMWareVirtualMachine Open(string fileName, int timeoutInSeconds)
    VMWareJobCallback callback = new VMWareJobCallback();
    VMWareJob job = new VMWareJob(_handle.OpenVM(fileName, callback), callback);
    return new VMWareVirtualMachine(job.Wait<ivm2>

Based on this model, we can code many functions of VMWareVirtualMachine, VMWareSnapshot, etc. The rest is implementation details.

Image 2

Advanced Implementation Details

Yielding Property Arrays

One of the peculiar VIX COM API constructs is the combination that returns arrays of properties. This is done with two functions: GetNumProperties and GetNthProperties. The first returns the number of property arrays returned by the job and the second fetches a property array at a given index. The first obvious step is to wrap the functions within the job class.

public T GetNthProperties<T>(int index, object[] properties)
    object result = null;
    VMWareInterop.Check(_handle.GetNthProperties(index, properties, ref result));
    return (T) result;

public int GetNumProperties(int property)
    return _handle.GetNumProperties(property);

We can now write such properties as RunningVirtualMachines.

public IEnumerable<VMWareVirtualMachine> RunningVirtualMachines
        VMWareJobCallback callback = new VMWareJobCallback();
        VMWareJob job = new VMWareJob(_handle.FindItems(
            Constants.VIX_FIND_RUNNING_VMS, null, -1, callback),
        object[] properties = { Constants.VIX_PROPERTY_FOUND_ITEM_LOCATION };
        for (int i = 0; i < job.GetNumProperties((int) properties[0]); i++)
            yield return this.Open(
                (string) job.GetNthProperties<object[]>(i, properties)[0]);

This is nice, but still not good enough. Let's combine the number of results and the results themselves in a YieldWait method.

public IEnumerable <object[]> YieldWait(object[] properties, int timeoutInSeconds)
    for (int i = 0; i < GetNumProperties((int)properties[0]); i++)
        yield return GetNthProperties<object[]>(i, properties);

This results in a nice improvement over the previous implementation.

public IEnumerable<VMWareVirtualMachine> RunningVirtualMachines
        VMWareJobCallback callback = new VMWareJobCallback();
        VMWareJob job = new VMWareJob(_handle.FindItems(
            Constants.VIX_FIND_RUNNING_VMS, null, -1, callback),
        foreach (object[] runningVirtualMachine in job.YieldWait
		(properties, VMWareInterop.Timeouts.FindItemsTimeout))
            yield return this.Open((string) runningVirtualMachine[0]);

Dates and Times

Date/time in VMWare VIX is expressed in UNIX EPOCH (number of seconds since January 1st, 1970).

DateTime currentDateTime = new DateTime(1970, 1, 1, 0, 0, 0, 0).AddSeconds((int) dt);

Source Code and Patches

This project lives on CodePlex at You can find the latest information about this library at You're encouraged to submit patches for added functionality and bug fixes.


  • 12/22/2008: Initial article, version 1.0
  • 02/11/2009: Revised "Using VMWareTasks" and described implementation of a blocking job wait
  • 02/12/2009: Moved to CodePlex, version 1.1


This article, along with any associated source code and files, is licensed under The MIT License


About the Author

Team Leader Application Security Inc.,
United States United States
Daniel Doubrovkine has been in software engineering for twelve years and is currently development manager at Application Security Inc. in New York City. He has been involved in many software ventures, including Xo3 and Vestris Inc, was a development lead at Microsoft Corp. in Redmond, and director of Engineering at Visible Path Corp. in New York City. Daniel also builds and runs a foodie website,

Comments and Discussions

PraiseGood Work Pin
srilekhamenon31-May-17 20:51
professionalsrilekhamenon31-May-17 20:51 
QuestionvirtualHost.Open for Remote VM in a Storage Cluster of Vsphere Pin
volks-mail30-Aug-16 22:56
membervolks-mail30-Aug-16 22:56 
QuestionShutdown the Host Pin
Member 106858408-Apr-15 23:49
memberMember 106858408-Apr-15 23:49 
QuestionAutomating VMWare Tacks From Remote Desktop Pin
NitishSharma17-Feb-13 14:40
memberNitishSharma17-Feb-13 14:40 
QuestionHow to revert child snap shot in Vmware using C# Pin
Biju Krishnan9-Jan-13 0:35
memberBiju Krishnan9-Jan-13 0:35 
QuestionGet the name of a snapshot Pin
markus133717-Aug-12 2:47
membermarkus133717-Aug-12 2:47 
AnswerRe: Get the name of a snapshot Pin
dB.17-Aug-12 5:11
memberdB.17-Aug-12 5:11 
QuestionNeed help on VMWare automations Pin
Vijaykumar Vadnal16-Jul-12 3:08
memberVijaykumar Vadnal16-Jul-12 3:08 
AnswerRe: Need help on VMWare automations Pin
dB.16-Jul-12 4:08
memberdB.16-Jul-12 4:08 
QuestionCant connect Pin
Chad Z. Hower aka Kudzu15-Jun-12 14:43
memberChad Z. Hower aka Kudzu15-Jun-12 14:43 
Questionstrong named or VS 2010 version? Pin
Chad Z. Hower aka Kudzu15-Jun-12 11:57
memberChad Z. Hower aka Kudzu15-Jun-12 11:57 
AnswerRe: strong named or VS 2010 version? Pin
dB.15-Jun-12 12:06
memberdB.15-Jun-12 12:06 
QuestionMulty-Thread functionality Pin
PaulMinsk9-Feb-12 2:20
memberPaulMinsk9-Feb-12 2:20 
AnswerRe: Multy-Thread functionality Pin
dB.9-Feb-12 5:09
memberdB.9-Feb-12 5:09 
GeneralMy vote of 4 Pin
Asim Javed17-Jan-12 3:01
memberAsim Javed17-Jan-12 3:01 
GeneralMy vote of 5 Pin
Hari Om Prakash Sharma23-Oct-11 23:40
memberHari Om Prakash Sharma23-Oct-11 23:40 
QuestionLogin WinXP/Win7 Pin
Markuss2125-Aug-11 2:27
memberMarkuss2125-Aug-11 2:27 
AnswerRe: Login WinXP/Win7 Pin
dB.25-Aug-11 6:24
memberdB.25-Aug-11 6:24 
GeneralRunProgramInGuest Pin
icmonicky22-May-11 20:58
membericmonicky22-May-11 20:58 
GeneralRe: RunProgramInGuest Pin
dB.23-May-11 2:02
memberdB.23-May-11 2:02 
GeneralMy vote of 5 Pin
jim lahey13-Apr-11 5:30
memberjim lahey13-Apr-11 5:30 
QuestionIs .vmx file only one way to get a virtual machine? Pin
surite7-Jul-10 0:57
membersurite7-Jul-10 0:57 
dB.7-Jul-10 2:08
memberdB.7-Jul-10 2:08 
Generalunable to connect to VMserver from aspx page Pin
nkoleilat31-May-10 22:54
membernkoleilat31-May-10 22:54 
dB.1-Jun-10 2:34
memberdB.1-Jun-10 2:34 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Praise Praise    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.

Posted 22 Dec 2008


101 bookmarked