The Invoke-VMScript cmdlet is definitely one of the PowerCLI cmdlets that is indispensable when you need to do things inside the Guest OS of your VMs.

When you are interacting with a Windows based Guest OS you can run old-fashioned BAT files or use PowerShell scripts. When the Guest OS is Linux based, you currently only can run Bash scripts.

Most Linux flavours have a feature that is called SheBang, and which allows you to specify in the first line of your bash script, which interpreter shall be used to run the following lines of the script. Unfortunately, the current Invoke-VMScript cmdlet doesn’t allow one to use that feature.

Time to tackle that issue, and expand the possibilities for all VMs that have a Linux-based Guest OS. So I decided to write my Invoke-VMScriptPlus function.

Update October 14th 2017

  • Added here-document bash sample

When the PowerCLI Feature Request website was announced during VMworld session #SER2529BU, it was no surprise to me, to rather quickly see a request appearing to support other languages, besides bash.

First I did some tests, to check if I could get the Invoke-VMScript cmdlet to work with a SheBang line.

Unfortunately it doesn’t.

When a cmdlet doesn’t do what you are trying to achieve, there is always the vSphere API that can help. The GuestOperationsManager is the place to look. From there we can access methods to start and monitor a process in the guest  and to handle files inside the guest OS.
The StartProgramInGuest is the central method of the Invoke-VMScriptPlus function. The function uses the arguments property on the GuestProgramSpec object to redirect the stdio of the process.

The following flow-chart shows a high-level view of the logic that is used in the Invoke-VMScriptPlus function, and shows which method is used at which point.

The Code


Line 1: The function requires PowerShell v5 or higher

Line 2: The function requires the PowerCLI Core module

Line 4-48: The latest version of my OBN (Object By Name) class. It allows one to pass or the actual .Net object, or the name of the object, as an argument to a parameter. See also Home Made OBN

Line 132: Most Linux OS return output with only a LF. This switch can be used to convert the LF to a CRLF, when the resulting output of the script is returned.

Line 145-152: A hard-coded table with the supported interpreters, and their corresponding SheBang line.

Line 159-168: If the VM is not powered on, or if the VMware Tools are not running, the function will return with a result.

Line 173-176: Tests if there is a SheBang line in the ScriptText. If not, it will add a line based on the ScriptType value.

Line 193-207: The function uses two temporary files to store the script and the script’s output.

Line 210-219: The ScriptText is copied to the temporary file. This is done over HTTPS with the Invoke-WebRequest cmdlet.

Line 222-231: The file containing the ScriptText needs to be made “executable”

Line 235-256: Script execution is started, and the function waits till the process completes.

Line 236: The function uses the Arguments property to redirect stdio to the second temporary file

Line 260-265: The output is fetched, again with an Invoke-WebRequest.

Line 270-273: Clean up the temporary files

Line 275-295: Return an object containing the script output and further info about the script execution

Sample Use

The use of the function Invoke-VMScriptPlus is quite similar to the use of the original Invoke-VMScript.

Some examples.


And the result

Here document

One feature that is often used in bash, is the so-called here document.

Unfortunately the Invoke-VMScript cmdlet doesn’t seem to support that feature for bash scripts. Code like this …

… produces an error like this.

But due to the way the Invoke-VMScriptPlus function transfers the script text to the guest, this feature is working without a glitch.

The same code as above, except that Invoke-VMScript is replaced by Invoke-VMScriptPlus.

… now produces the expected result.


In this example we are not adding the SheBang line in the ScriptText, but through the ScriptType value, the function will add this line.

And the result.
Notice how the Invoke-VMScriptPlus function added the SheBang line.


During the VMworld Breakout session, where this function was first demonstrated, we showed additional examples in the following video.

Since there are many Linux flavours out there, and since I obviously couldn’t test them all, I would appreciate it if you can send me feedback about which Linux flavours/versions work, and which don’t.

If there are requests for other languages, feel free to forward me your requests.





    Thanks for your work. Good job.
    Is it possible to inject patameters to defined bash script?


      Not in the current version I’m afraid.
      But you should be able to pass environment variables with the ScriptEnvironment variable in the newer version of the function.
      See Invoke-VMScriptPlus V2


        Sorry for question, but How to deploy/install Invoke-VMScriptPlus V2?


          You have a couple of options.
          The simplest is to store the code from the blog post in a .ps1 file.
          Then add the end of the .ps1 file, call the function with Invoke-VMScriptPlus (with the required parameters).

Leave a Reply

Your email address will not be published. Required fields are marked *


This site uses Akismet to reduce spam. Learn how your comment data is processed.