Home > Virtualization, vSphere API > Run Program in Guest Operating System on VMware

Run Program in Guest Operating System on VMware

February 27th, 2012 Leave a comment Go to comments

Integrating VIX API into vSphere API is a great decision VMware made for its vSphere 5.0 release. Instead of working on two separate APIs, you now have one to deal with. It also solves the portability issue of VIX APIs which is tied to a specific platform – VIX has three versions for Windows, 32-bit Linux, and 64-bit Linux.

In the same week of vSphere 5.0 release, I added the support of vSphere 5 in vSphere Java API. Later on, I wrote an article on how VIX is implemented in the open source API. The article did not include any sample but high level introduction, design decisions, and a few API signatures.

I knew it’s not enough – we engineers like samples. Here is the first of a few samples I write to illustrate the usage of the APIs. In the future, I will create a higher level abstraction as part of the API, like what you can get from PowerCLI’s Invoke-VmScript cmdlet. (Update: it’s done. Check out the sample using the higher level API)

The follow sample is a simple VI Java code that runs a PowerShell script in a Windows guest OS. Note that the path of the PowerShell on your machine could be different. Please verify it and the PowerShell script file before you run the program.

import java.net.URL;

import com.vmware.vim25.GuestProgramSpec;
import com.vmware.vim25.NamePasswordAuthentication;
import com.vmware.vim25.mo.Folder;
import com.vmware.vim25.mo.GuestAuthManager;
import com.vmware.vim25.mo.GuestOperationsManager;
import com.vmware.vim25.mo.GuestProcessManager;
import com.vmware.vim25.mo.InventoryNavigator;
import com.vmware.vim25.mo.ManagedEntity;
import com.vmware.vim25.mo.ServiceInstance;
import com.vmware.vim25.mo.VirtualMachine;

public class GuestRunProgram
{
  public static void main(String[] args) throws Exception
  {
    ServiceInstance si = new ServiceInstance(new URL("https://8.8.8.8/sdk"), "Administrator", "doublecloud.org", true);
    Folder rootFolder = si.getRootFolder();

    ManagedEntity[] mes = new InventoryNavigator(rootFolder).searchManagedEntities("VirtualMachine");
    if(mes==null || mes.length ==0)
    {
      return;
    }

    GuestOperationsManager gom = si.getGuestOperationsManager();

    VirtualMachine vm = (VirtualMachine) mes[0];

    if(!"guestToolsRunning".equals(vm.getGuest().toolsRunningStatus))
    {
      System.out.println("The VMware Tools is not running in the Guest OS on VM: " + vm.getName());
      System.out.println("Exiting...");
      return;
    }

    GuestAuthManager gam = gom.getAuthManager(vm);
    NamePasswordAuthentication npa = new NamePasswordAuthentication();
    npa.username = "Administrator";
    npa.password = "vijava";

    GuestProgramSpec spec = new GuestProgramSpec();
    spec.programPath = "C:\\Windows\\SysWOW64\\WindowsPowerShell\\v1.0\\powershell.exe";
    spec.arguments = "-command \"c:\\temp\\policy.ps1\"";

    GuestProcessManager gpm = gom.getProcessManager(vm);
    long pid = gpm.startProgramInGuest(npa, spec);
    System.out.println("pid: " + pid);

    si.getServerConnection().logout();
  }
}

Before you run the code, make sure your VMware Tools is installed in the guest OS, and up to date. To find it out, you can go to the guest OS and click on the VMware Tools icon on the taskbar. It should tell you the versions and build number. In my case, the version is 8.6.0 build 425873.

Alternatively, you can right click on the virtual machine and select “Install/Upgrade VMware Tools.” The wizard will guide you through the installation or upgrading.

Now you’ve seen the code and hopefully have run the program. You may ask, “Wait a second, how can I get the standard output of the command I run remotely?”

A great question indeed! Unfortunately there is no direct support for you to get back the output other than the process ID. But we techies are creative at problem solving. The workaround is to redirect the output of the command to a file, and then download the file. Please stay tuned for next sample on how to download a file from a guest OS.

  1. Steve
    March 13th, 2012 at 10:43 | #1

    Hi, love the API and using it to help with deployment of test systems.

    Is there any way to tell when a GuestProgram has finished? You also hint at a way of getting the result from a command but dont include any sample code

    Cheers
    Steve

  2. March 13th, 2012 at 10:53 | #2

    Thanks Steve,
    Glad you like it. To tell whether a process is done, please consider this method defined in GuestProcessDirector:
    public GuestProcessInfo[] listProcesses(long[] pids)
    If you can get return back, then it’s still up running; otherwise it’s done.
    Good luck!
    Steve

  3. Felipe Krause
    February 28th, 2013 at 16:12 | #3

    Hi,
    Great post, I would like to know if there is a way to create a temporary file to save the output form the command dinammically?

    Thanks,
    Felipe

  4. February 28th, 2013 at 19:42 | #4

    I think you can use > output.txt after your command.
    Steve

  5. Felipe Krause
    March 1st, 2013 at 11:55 | #5

    @Steve Jin

    It does not work. I already did that, and no file is created with the output.

    Any idea?

  6. Felipe Krause
    March 1st, 2013 at 11:57 | #6

    @Felipe Krause

    The cmd line from GuestProcessInfo is:

    GuestProcessInfo.cmdLine: “C:\Windows\system32\hostname.exe” > C:\output.txt

    the ” is put by default.

  7. Felipe Krause
    March 1st, 2013 at 12:22 | #7

    Now it is working:

    GuestProgramSpec spec = new GuestProgramSpec();
    spec.programPath = POWERSHELL_EXE;
    //spec.programPath = cmd;
    spec.arguments = “-command “+cmd+” > “+C_CMDEXEC_OUTPUT_TXT;

    **I did not realize before, but I need to start the cmd with the powershell. Using only the cmd + output will not work.

  8. March 1st, 2013 at 14:09 | #8

    Thanks for sharing. The pipeline works only within a shell environment. PowerShell definitely fits that.

    Steve

  1. March 1st, 2012 at 09:53 | #1
  2. March 5th, 2012 at 00:37 | #2