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.

Lost VMs or Containers? Too Many Consoles? Too Slow GUI? Time to learn how to "Google" and manage your VMware and clouds in a fast and secure HTML5 App.

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

  9. Sai
    August 2nd, 2013 at 09:54 | #9

    Nice Article.

    Did you see any limitations in using startProgramInGuest(npa, spec);

    Example:
    Execute a powershell which starts a new process?
    Execute a powershell script which executes msiexec.exe to install a new software on to the guest?

    Any idea if these kind of operations allowed

  10. August 5th, 2013 at 01:05 | #10

    Hi Sai,

    Glad you like it. I have not tried the PowerShell commands as you suggested. I believe it should not a problem. You may want to include full path to the PowerShell interpreter, not just the command itself.

    Good luck and let me know any tips/tricks to make it work.

    Steve

  11. apapap
    September 27th, 2013 at 03:37 | #11

    Hi Steve,

    Seems interesting!!!!

    I am trying to run “ipconfig” on “cmd” i.e. the windows command prompt.

    I tried the following code:

    GuestProgramSpec spec = new GuestProgramSpec();
    spec.programPath = “C:\\Windows\\System32\\cmd.exe”;
    spec.arguments = “ipconfig > \”C:\\ipconfig.txt\” “;

    Please check if this is the correct way to execute commands using the library on the command prompt.

    Is this library only restricted to “Windows”?
    Also, can we connect to linux machines and execute commands there?

  12. Sharu
    October 1st, 2013 at 14:55 | #12

    Hi Steve,

    When I execute the above program,the process get started but not visible in the foreground.I mean if I start Firefox one process gets created running in the background.Is there any way to make these programs visible running in guest machine.

  13. Bud
    October 14th, 2013 at 15:28 | #13

    Hey Steve,

    Have you run into issues where output redirecting in Windows guests (2008 R2 in my case) does not work when using startProgramInGuest?

    As an example, I’m passing the programPath as “C:\\Windows\\System32\\hostname.exe”, with arguments as “> C:\\testout.txt”. Regardless of the output path, the redirection of output to a file never seems to work.

    Thanks!

  14. October 14th, 2013 at 21:47 | #14

    Hey Bud,

    The redirection works only in a Shell command, not from any program. So if you change the program path to the cmd.exe and run your hostname as part of the command parameters, it should then work.

    Good luck!

    Steve

  15. Bud
    October 23rd, 2013 at 09:03 | #15

    Steve – that’s super helpful. We’ll give that a shot. Thank you!

  16. October 23rd, 2013 at 10:49 | #16

    You are very welcome Bud, let me know if it works or not.

    Steve

  17. Samy
    November 15th, 2013 at 10:25 | #17

    Hi Steve.. i tried to run your program.. it gives an error..
    i debugged it.. the following line gives an error..
    “long pid = gpm.startProgramInGuest(npa, spec);”

    The error is “Exception in thread “main” java.rmi.RemoteException: VI SDK invoke exception:com.vmware.vim25.InvalidRequest”

    Please help! I am waiting for your reply!

    Thanks,
    Samy.

  18. November 15th, 2013 at 14:27 | #18

    Hi Samy, as the exception name suggests, the arguments passed into the API are not valid… What did you pass in?

    Steve

  19. Samy
    November 16th, 2013 at 03:08 | #19

    Dear Steve,
    Server: ESXi 5.1
    I am using Vsphere Client 5.1..
    My quest os is Windows 7 and ubuntu..
    My requirement is”i want to open a ShortCut that i created in guest os desktop for script file.. when i click the desktop shortcut the script is running..”
    i tried my requirement with your code.. it didn’t work.. so first i tried to open a notepad in guest os..then i got the exception error which i mentioned above.. i mentioned the program also.. So if you help for my requirement.. it will be very helpful..

    Thank you,
    Samy.

  20. November 16th, 2013 at 03:48 | #20

    I don’t expect your requirement would work. Why not call your scripts directly? Also remember to include shell executable in your parameter.

    Good luck,

    Steve

  21. Prabhu
    November 18th, 2013 at 08:53 | #21

    Samy :
    Dear Steve,
    Here is the complete program..
    Can you tell me the mistake what i did?Please correct it.. it will be helpful for me!!
    package com.vmware.vim25.mo.samples.vm;
    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;
    import java.rmi.RemoteException;
    public class Openshortcut
    {
    public static void main(String[] args) throws Exception
    {
    ServiceInstance si = new ServiceInstance(new URL(“https://192.168.80.140/sdk”), “root”, “xyxyxy”,true);
    Folder rootFolder = si.getRootFolder();
    ManagedEntity[] mes = new InventoryNavigator(rootFolder).searchManagedEntities(“VirtualMachine”);
    if(mes==null || mes.length ==0)
    {
    return;
    }
    String vmname = “VM Win 7″;
    GuestOperationsManager gom = si.getGuestOperationsManager();
    VirtualMachine vm = (VirtualMachine) new InventoryNavigator(
    rootFolder).searchManagedEntity(“VirtualMachine”,vmname);
    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 = “xyxyxy”;
    npa.password = “xyxyxy”;
    GuestProgramSpec spec = new GuestProgramSpec();
    spec.programPath = “C:\\Windows\\system32\\notepad.exe”;
    GuestProcessManager gpm = gom.getProcessManager(vm);
    long pid = gpm.startProgramInGuest(npa, spec);
    System.out.println(“pid: ” + pid);
    si.getServerConnection().logout();
    }
    }
    Thanks,
    Samy.

  22. Samy
    November 19th, 2013 at 05:03 | #22

    Dear Steve,

    One Humble Request please remove my old comments which contains program examples from your blog..

    Please remove sir,

    I am waiting for your actions,

    Thank you,
    Samy.

  23. Sandipan Sen
    January 2nd, 2014 at 09:51 | #23

    Hi Steve,
    I’m new to the vsphere api. I was trying your above code found and NullPointerException in the following line:
    GuestOperationsManager gom = si.getGuestOperationsManager();

    Cant find the root of the problem. Help from you would be highly appreciated.

    Thanks,
    Sandipan

  24. January 2nd, 2014 at 12:23 | #24

    Hi Sandipan,

    What version of vSphere are you using? There seems to be a bug in vSphere 5.1.

    Steve

  25. Sandipan Sen
    January 3rd, 2014 at 01:03 | #25

    Hi Steve,
    I have tried to execute your program with with different versions of vijava(like vsphere 5.5(beta),vsphere5.2) but every time si.getGuestOperationsManager() is returning a null value.
    Is there in any other alternative way of executing programs in guest OS.
    I have Esxi 4.1 box and it has a free license.

    I’m really at my wits end. Please help
    Thanks,
    Sandipan

  26. January 3rd, 2014 at 14:50 | #26

    You need to try a different version of vSphere server. The bug is on the server side, not vijava API. ESXi 4.1 does not support guest related API. Try 5.0 instead.

    Steve

  27. Alex M
    January 28th, 2014 at 06:21 | #27

    Hi Steve

    Help, please, in understanding.

    I permanently get: com.vmware.vim25.NoPermission on long pid = gpm.startProgramInGuest(npa, spec);
    whats can be wrong.

    Thanks
    Alex

  28. January 28th, 2014 at 10:36 | #28

    As the exception says, your login user does NOT have permission to execute the command. Try it with root user to see if you’ll still get the exception.

    Steve

  29. Alex M
    January 28th, 2014 at 11:03 | #29

    Thanks, but if all was be so easy, I’ll resolved this. User is Administrator(i mean it consist in Administrator group )on the particular host. Maybe this some settings for VM in vSphere, maybe something should be enable for “inGuest” manipulation.

  30. Pankaj
    April 30th, 2014 at 06:59 | #30

    Hi Steve,

    Is there any that I can get output of command executed in Guest Vm into a variable. for example instead of program pid, output of executed program.

    I don’t want to write in a file in Guest Vm.

    Similary facility is available in VIX. we can get commnd output.

  31. April 30th, 2014 at 12:28 | #31

    Good question. I don’t remember it’s possible. I think you can use a temporary file.

    Steve

  32. Evan
    July 14th, 2014 at 08:45 | #32

    Hi Steve,

    I am trying to change the linux password using the code below but it does not change the password and i get no errors. Any idea what I am doing wrong?

    Thanks,
    Evan

    GuestProgramSpec GPS = new GuestProgramSpec();
    GPS.Arguments = “echo -e \”evan\\nevan\” | passwd root”;
    GPS.ProgramPath = “/”;
    GuestProcessManager s = (GuestProcessManager)vc.GetView(GOM.ProcessManager, null);
    s.StartProgramInGuest(TempVM.MoRef, NPA, GPS);

  33. July 14th, 2014 at 14:52 | #33

    You want to run the bash instead of the command directly.

    Steve

  34. Evan
    July 15th, 2014 at 00:53 | #34

    Thanks for the reply, Steve. I’m not 100% sure what you mean? could you give me an example please.

  35. Evan
    July 15th, 2014 at 01:20 | #35

    Nevermind got it!!!

    #!/bin/bash \n echo -e \”evan\nevan\” | passwd root

  36. Peter
    September 18th, 2014 at 02:40 | #36

    Hi Steve,
    I am trying to run program in guest operating system on VMware and I need your help.
    You konw, there are three ways can authenticate a guest (NamePasswordAuthentication, SSPIAuthentication, TicketedSessionAuthentication)
    I wanna using TicketedSessionAuthentication or SSPIAuthentication to authenticate a guest, what should I do ? how do I get the ticket for a guest.

    I am waiting for your actions.

    Thank you,
    Peter.

  37. Enigma
    November 19th, 2014 at 07:20 | #37

    Hi,
    Any help regarding TicketedSessionAuthentication way?
    tried getting the vm ticket and setting it to TicketedSessionAuthentication but getting NotSupported when trying to acquireCredentialsInGuest.

  38. November 19th, 2014 at 22:06 | #38

    Do you have VMware Tools installed in the guest OS from which you want to get ticket?

    Steve

  39. Enigma
    November 23rd, 2014 at 05:17 | #39

    Hi Steve,
    Yes I do. I indeed get what seems to be a valid ticket from the AcquireTicket API from the VM itself. I then build a TicketedSessionAuthentication while setting the ticket to this auth’.
    With this auth’ I try to call acquireCredentialsInGuest through GuestAuthManager (taken from GuestOperationsManager). The acquireCredentialsInGuest returns NotSupported.
    Maybe the flow I’m doing is wrong?

    Thanks

  40. November 23rd, 2014 at 20:33 | #40

    What OS do you have? Do you have latest VMware Tools for the OS?

    Steve

  41. Enigma
    November 25th, 2014 at 03:58 | #41

    Hi Steve,
    Thanks for your replies. OS is windows server 2008 R2.
    VM tools 9.4.5

  42. Marco
    June 19th, 2015 at 03:12 | #42

    Hi steve,
    I have the same problem that reported Sharu. I am using Python APIs, and when I launch a command it works perfectly, but if I launch an application with a GUI (like notepad), it runs (I can see it in process manager) but it does not shows any GUI (it’s not minimized, it really have no window).
    I use: vim.vm.guest.ProcessManager.WindowsProgramSpec()

    Anyway I know it’s possible to launch an application with the gui on a vm using i.e. vmrun command.

    Any idea?

    Thank you very much.

  43. Marco
    June 19th, 2015 at 06:44 | #43

    PS: I solved it. You need to set interactiveSession = True on the GuestAuthentication object, or your command will be lauched by defaut with session id=0

  44. sanyam
    October 1st, 2015 at 22:54 | #44

    What is the reason of the Exception: java.rmi.RemoteException, msg: VI SDK invoke Exception, com.vmware.vim25.SystemError. I get this while running a program in guest operating System using Vsphere API-startProgramInGuest? The program actually runs in the vm even though this message is displayed in the command window of the controller vm but have no idea what cause this!

  45. October 2nd, 2015 at 00:17 | #45

    Don’t know what happened exactly. Do you have VMware Tools insalled? Is it a Windows Guest? Have you changed the password to yours? Do you have PowerShell script in the location as shown in the code?

    Steve

  46. Sanyam
    October 5th, 2015 at 01:32 | #46

    yes, it is a windows operating system with VMware tools installed. The password is not changed. We are using gradle framework to run program in guest. The error log says “error getting process details on vm CST-W7…. for pid xyz, Exception.java.rmi.remoteException, msg: VI SDK invoke exception: com.vmware.vim25. systemError.

  47. David T
    July 5th, 2016 at 13:47 | #47

    Steve,

    I was wondering if instead of using VI Java SDK, can you do this with the base level SDK that is provided by vSphere? Can you run, execute and list processes using the standard vSphere SDK?

    Thanks,
    David

  48. July 5th, 2016 at 23:03 | #48

    Hi David, I believe so. You may want to check with VMware though.
    -Steve

  49. David T
    July 7th, 2016 at 10:45 | #49

    Hey Steve,

    Looks like I was able to get it working by using the standard SDK, my question now is:

    I’m currently just running cmd.exe in interactive mode, which I can see the cmd.exe booting up on my guest box, but I’m trying to just run a simple echo hello to see if that command would run in cmd.exe but I can’t seem to get it working. I have tried multiple things:

    GuestProgramSpec spec = new GuestProgramSpec();
    spec.setProgramPath(“C:\\Windows\\System32\\cmd.exe”);
    1. spec.setArguments (“echo hello”);
    2. spec.setArguments (“-command \”echo hello\””);
    3. spec.setArguments (“-cmd \”echo hello\””);
    4. spec.setArguments (“echo hello > output.txt”);

    None of these commands get executed for some reason. I don’t even see the output.txt on the last command. Am I running these command wrong?

  50. clove
    July 25th, 2016 at 13:50 | #50

    I am facing a similar using pyvmomi … the power shell u r opening doesnot open as Admin i mean the same that we do with run as admin.
    Is there a way to do that.
    I need the power shell to be opened as Run as Admin

  1. March 1st, 2012 at 09:53 | #1
  2. March 5th, 2012 at 00:37 | #2
  3. May 12th, 2016 at 14:56 | #3