Invoke-VMScriptPlus v3

My InvokeVMScriptPlus function serves me well while interacting with the guest OS on a VM. And I’m apparently not the only one that uses the function. This post introduces Invoke-VMScriptPlus v3.

The original Invoke-VMScriptPlus post, and the addition of PS Core support, described in the Invoke-VMScriptPlus v2 post, keep being some of my most read posts. Time for another update.

In this v3 version, I introduce some new features to the function.

  • PSv6 and PSv7 support
  • Use files (input and output) from within your scripts
  • improved sudo support

Update November 18th 2019

  • Added NoIPinCert switch

The Code


The following annotations will only document the additions to the v2 version of the function. Refer to the blog posts mentioned in the introduction to see the annotations of the previous versions of the function.

Line 177-178: Addition/change of the script types. Now includes powershellv6 and powershellv7.

Line 184: A switch that allows the caller to ask for sudo support. In practice the function will pipe, via an echo command, the guest credential’s password to each sudo command in the script.

Line 189-190: New parameters InFile and OutFile. They permit files to be copied to/from the script environment.

Line 191: The NoIPforCert switch

Line 196-228: Internal helper function to send files from the caller’s environment to the guest OS.

Line 230-258: Internal helper function to receive files from the guest OS into the caller’s environment.

Line 239-244: If the NoIPforCert switch is $true, the IP address in the URI returned by the ESXi node (where the VM is running) will be converted to the FQDN of the ESXi node.

Line 276-277: New she-bang entries for PowerShell v6 and v7. Note that at the time this post was published, that v7 was still in preview.

Line 298-302: Additional ‘ready’ test. If this property is not $true, the VMware Tools inside the guest OS are not ready to accept any GuestOperations related calls.

Line 333: For any Windows guest OS, the function currently only accepts BAT, PS, PSv6 and PSv7 scripts.

Line 344: For any Linux (this includes MacOS) guest OS, the function accepts all scripttypes, except BAT and PowerShell (meaning PS pre-v6).

Line 371-377: sudo support. Each line of the user’s script containg the sudo command, will be prefixed with an echo command, which will provide the password to the sudo prompt.

Line 382: In this version of the function, all files will be stored in a temporary directory in the guest OS.

Line 435-442: The function allows the caller to copy one or more files, from the caller’s environment to the temporary folder in the guest OS. Since these files will be in the same folder as the actual script, the script can reference these files.

Line 499-513: The function supports for a Windows guest OS, the use of PSv5.*, PSV6 and PSv7.

Line 568-575: The function allows the caller to copy one or more files, from the folder, where the script ran in the guest OS, to the caller’s enviroment. This allows an alternative method to send data back to caller besides the stdin channel.

Line 580-584: When the KeepFiles switch is not used, the function will remove the temporary directory in the guest OS, where all the script related files are stored.


The following section will show some examples of how to use the new features introduced in the v3 of the Invoke-VMScriptPlus function.


One of security measure on many Linux systems is that you need to use sudo to run commands with elevated privileges.

This is a typical example of such a case.

The OS returns the following error.

Elevated privileges required

Ok, let’s place sudo in front of that.

But that just makes the next issue obvious. How to answer to a prompt in a script. The method to solve this quite simple. Echo the password and then pipe it to the sudo command.

But this not always a practical solution, and probably not very safe either. To avoid having to handle this in the code you sent to the guest OS, the Invoke-VMScriptPlus function has the Sudo switch.

It will extract the password from the GuestCredential parameter value, and insert the echo with the password on each line in your code that starts with sudo.

PowerShell v7

At the moment, of this writing, PowerShell v7 is still a preview.
Since you can install PSv6 and PSv7 side-by-side, you can run your scripts in either version.

This is a handy way to test your scripts for readiness for PSv7.

With the ScriptType parameter, you easily define against which PowerShell version your script should run. First we use powershellv6.

This results in.


And then the same, but with powershellv7.

And now we get.


The Invoke-VMScriptPlus function captures the output of your script on the stdin stream. But sometimes you would like to produce multiple outputs, or output in a specific format.

The same goes for your input to your script. You can pass input along to your script, for example with a here-string, but this at least requires extra steps to run your script.

For that reason, this v3 version of Invoke-VMScriptPlus, added two new parameters, Infile and OutFile.

Each of these parameters allow you to specify one or more files in your local environment that will be passed and/or retrieved to the environment where your script runs in the guest OS of the target VM.

A somewhat contrived example on what this allows you to do.

In short, the script creates an input file, then runs a script on the target VM, passing along the input file.
The script on the target VM creates a number of files, which are returned to the caller when the script completes.

This is the output from the above code.

This is a handy feature when your script requires an existing file as input and produces multiple output files.


When the function needs to retrieve files from the guest OS, the ESXi node on which the VM is running, provides a URI. This URI normally contains the IP address of the ESXi node.

This can cause an issue when using certificates, and not bypassing the certificate check. The reason is sometimes that the IP address of the ESXi node is not included as a Subject Alternate Address (SAN) in the certificate. This is visible through the following error message. Note that the following output also shows some verbose output to demonstrate when this is happening, and also to show that the error occurs when doing a GET with an URI that contains the IP address.

No IP SAN in certificate

To avoid this error, the Invoke-VMScriptPlus function, by default, translates this IP address into the FQDN of the ESXi node. The following verbose output shows the adapted URI for the GET

In some environments these automatic conversion of the IP address to the FQDN might cause an issue. One reason for this to happen might be that the ESXi node is added with it’s IP address. Another might be that the DNS query to get the FQDN of the ESXi node fails.
Especially for those occasion, the function now has this NoIPforCert switch. This switch, when set, instructs the function to NOT translate the IP address in the URI to the FQDN.

A sample call that uses this switch can look like this.


Version: 3.1
24.4 KiB
One Comment

    Cloud-init - Part 4 - Running Scripts - LucD notes

    […] avoid those issues I have written my Invoke-VMScriptPlus function. Besides fixing the above-mentioned issues, it also adds some extra features that come in […]

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.