Use the following workflow for running a program in a guest using vSphere GuestOperations to keep things secure and captures maximum output for debugging:
Ensure the VM is ready for guest operations
The virtual machine must be powered on, and vim.vm.GuestInfo.guestOperationsReady must be set.
Create a temporary directory from which to run the command and capture any output. This provides a secure sandbox for output which is easy to clean up.
The API is CreateTemporaryDirectoryInGuest(), which returns the new directory.
Create a temporary file in the new temporary directory. This is used to capture stdio. If stdout and stderr should be distinct, create two files.
The API is CreateTemporaryFileInGuest() using the results from step 2 as the directoryPath param.
Returns the new temp file(s).
Use InitiateFileTransferToGuest to copy a script into the guest to run the command. This can be useful if there's a series of commands to run, or the arguments are complex.
Redirect output to the temporary file(s) from step 3 if necessary.
Note: On some Linux distributions, /tmp will not allow a program to be run from it because of the noexec mount option. For those case, ensure to create the temporary directory in step 2 on a file system without noexec.
Start the guest program, redirecting output to the temporary files.
The API is StartProgramInGuest(). Use the temporary directory from step 2 as the working directory. Paths need to be absolute.
Its safest not to depend on the environment variables.
Stdio redirection can be done in the GuestProgramSpec arguments.
On Windows, if stdio is being redirected, prefix "cmd /c" so stdio redirection can be used.
The return value is a pid.
Poll by calling ListProcessInGuest() passing in the pid until the exitCode and endTime become valid, which indicates the program has completed. The poll interval is best specified based on the program being run -- a quick cmdline app could check every second, something that can take minutes should delay a lot longer to minimize the stress on the system. Check at least every 5 minutes, which is how long the results will last.
If the command generates output, or stdio is needed for debugging a failure, copy out the files.
The API is InitiateFileTransferFromGuest.
Remove the temporary directory and any intermediate files.
Call DeleteDirectoryInGuest on the directory created in step 2 with the recursive flag set.