A question that comes up from time to time in the forums is about how to use the vmrun application with the runProgramInGuest command to install a Windows Installer (MSI) package in a virtual machine running Windows. In other words, someone needs to run something similar to the following command:
| vmrun -T ws -gu USERNAME -gp PASSWORD runProgramInGuest "C:\VMs\VM1\VM1.vmx" "C:\Windows\system32\msiexec.exe /i C:\app.msi" |
|---|
The runProgramInGuest command will be issued without error, but a look at the virtual machine's console will reveal a Windows Installer options screen displaying all of the switches that are available to the msiexec.exe application. Any approach or combination of single-quotes, double-quotes, slashes, backslashes, spaces or special characters thrown at vmrun and runProgramInGuest results in the same options screen or (even worse) the "Error: A file was not found" message.
After some quick research into this issue, I discovered a discussion on VMTN, where VMware employee mattrich states that "vmrun quotes each argument it passes to the guest." This is good to know. It is actually this behavior that creates the problem for the Windows Installer.
To verify that the behavior mattrich describes is correct, use the free Process Monitor utility from Sysinternals. On the virtual machine, launch Process Monitor and press Ctrl+L to bring up the filter menu. Working from the left, choose "Operation" from the first drop-down menu. Choose "is" from the second drop-down menu. Choose "Process Create" from the third drop-down menu and "Include" from the fourth drop-down menu. Now click the "Add" button. The new filter will now be listed in the bottom of the filter window. Click OK to continue.
Now use the vmrun application with the runProgramInGuest command to send the Windows Installer commands to the virtual machine again.
| vmrun -T ws -gu USERNAME -gp PASSWORD runProgramInGuest "C:\VMs\VM1\VM1.vmx" "C:\Windows\system32\msiexec.exe /i C:\app.msi" |
|---|
Viewing the detail column in Process Monitor, it becomes very apparent that each argument sent to the Windows host via runProgramInGuest is encapsulated in quotes, just like mattrich said. Using Start->Run in Windows, re-typing this same command (exactly as it appears in Process Monitor) will create the same output of a Windows Installer options screen. So there is definitely a problem; but how about a workaround?
There is actually an easy workaround that can be used to solve this problem. On the host, create a batch file by issuing the following command:
| echo C:\Windows\system32\msiexec.exe /i C:\app.msi > C:\sourcebatch.bat |
|---|
Now run the following command on the same host where the batch file is located:
| vmrun -T ws -gu USERNAME -gp PASSWORD copyFileFromHostToGuest "C:\VMs\VM1\VM1.vmx" "C:\sourcebatch.bat" "C:\destbatch.bat" |
|---|
This will copy the batch file C:\sourcebatch.bat from the host to the guest as C:\destbatch.bat. All that is left is to run the batch file on the virtual machine with:
| vmrun -T ws -gu USERNAME -gp PASSWORD runProgramInGuest "C:\VMs\VM1\VM1.vmx" cmd.exe "/c C:\destbatch.bat" |
|---|
After the install completes, one final command should be run (in the interest of cleaning up):
| vmrun -T ws -gu USERNAME -gp PASSWORD deleteFileInGuest "C:\VMs\VM1\VM1.vmx" "C:\destbatch.bat" |
|---|
This workaround certainly isn't as elegant as just running a single command would be, but it will get the task done. This approach is also interesting in that it solves a possible limitation of an existing product, by using additional functionality contained in the same product. I refer to a "possible limitation," because I am optimistic that someone will figure out the secret combination of characters to make vmrun runProgramInGuest work with msiexec.exe!