Modifying guest network interface with the Invoke-VMScript cmdlet


images

Set-VMGuestNetworkInterface

With the news that the ‘Set-VMGuestNetworkInterface’ cmdlet is to be deprecated in the next release of PowerCLI (http://blogs.vmware.com/PowerCLI/2014/11/announcement-future-cmdlet-deprecation.html), the question is how do I now modify the guest network interface?

The ability to perform this action can now be moved to the Invoke-VMScript cmdlet, which is a pretty cool way to invoke a script in the guest operating system of the virtual machine when VMware Tools is installed.

As per the description of the cmdlet you will need to satisfy the below:

To run Invoke-VMScript, the user must have read access to the folder containing the virtual machine and a VirtualMachine.Interaction.Console Interaction privilege. The virtual machines must be powered on and have VMware Tools installed. Network connectivity to the ESX system hosting the virtual machine on port 902 must be present to authenticate with the host or the guest OS, one of the HostUser/HostPassword (GuestUser/GuestPassword) pair and HostCredential (GuestCredential) parameters must be provided. The guest account you use to authenticate with the guest operating system must have administrator’s privileges.

To run this cmdlet against vCenter Server/ESX/ESXi versions earlier than 5.0, you need to meet the following requirements:

*You must run the cmdlet on the 32-bit version of Windows PowerShell.
*You must have access to the ESX that hosts the virtual machine over TCP port 902.
*For vCenter Server/ESX/ESXi versions earlier than 4.1, you need VirtualMachine.Interact.ConsoleInteract privilege.  For vCenterServer/ESX/ESXi 4.1 and later, you need VirtualMachine.Interact.GuestControl privilege.

As mentioned VMware Tools is required to be installed and the virtual machine to be powered on, in my use case modifying the guest network interface is a one of a number of script blocks in deployment script to customise a virtual machine and therefore in order to confirm that VMware Tools is running following a virtual machine power on event I run a statement in a script block until the Guest.ToolsStatus is retrieved as ‘toolsOK’ from the Get-View cmdlet, where the MoRef value for the virtual machine is retrieved from an associated array.

Do     
    {
    Start-Sleep -Seconds 10
    $GuestToolsStatus = (Get-View $VM.Id -Property Guest).Guest.ToolsStatus
    } 
Until ($GuestToolsStatus -eq toolsOk)

Now we want to modify the guest network interface, with the following requirements.

  • Configure IPv4 address
  • Configure subnet mask
  • Configure default gateway
  • Configure DNS servers

So, in order to modify the guest network interface I will be replacing the soon to be deprecated ‘Set-VMGuestNetworkInterface’ cmdlet with the ‘New-NetIPAddress’ and ‘Set-DnsClientServerAddress’ cmdlets in Windows Powershell.

In order to run the script inside the guest operating system and in this example a Microsoft Windows Server 2012 operating, I will create a ScriptText variable containing the syntax of the two cmdlets I wish to invoke.  Please not the ‘;’ separator to invoke multiple lines of commands in the text of the script.

$ScriptText = "New-NetIPAddress –InterfaceAlias Ethernet0 –IPAddress 10.0.0.5 -AddressFamily IPv4 –PrefixLength 24 -DefaultGateway 10.0.0.254;
Set-DnsClientServerAddress -InterfaceAlias Ethernet0 -ServerAddresses 10.0.0.1,10.0.0.2"

In the above example, we are modifying the network interface ‘Ethernet0’ to use the IPv4 address 10.0.0.5/24 with a default gateway 10.0.0.254 and the DNS servers 10.0.0.1 and 10.0.0.2.

Now, let’s actually run the command in the guest operating operating system, using the Invoke-VMScript cmdlet, where guest credentials are retrieved from paramaters supplied for my script.

Invoke-VMScript -VM $VM -ScriptText $ScriptText -GuestUser $GuestUser -GuestPassword $GuestPassword

As you can see this is a powerful way to invoke scripts inside the guest operating system. In the default state the script type invoked on a Microsoft Windows operating system is Powershell. However, you may specify the type to be Bat or for a Linux operating system Bash.

The script above, can be downloaded from https://github.com/dean1609/scripts/commit/1bd96807a899a3f8861ca676354eb129545fa1c9.

Advertisements

VMware Tools Upgrade fails with vix error code 21009

On remediating virtual machines using the Update Manager, a number of VMware Tools upgrades would fail reporting the following:

Error Upgrading VMware Tools
vix error code = 21009

On investigation of vix error codes at https://www.vmware.com/support/developer/vix-api/vix16_reference/errors/errors.html there was error code reference for the above. So now it was time to look at the vmware.log file for one of the impacted virtual machines, to which I found the following log entry

TOOLS INSTALL Error copying upgrader binary into guest. success = 0, HgfsStatus = 8

A quick search of the VMware KB, returned the following http://kb.vmware.com/selfservice/microsites/search.do?language=en_US&cmd=displayKC&externalId=1023459 where the cause of the issue is that the file ‘VMwareToolsUpgrader.exe’ located at ‘C:\Windows\Temp’ only has read-only permissions.

In order to resolve the issue, I removed the file ‘VMwareToolsUpgrader.exe’ from one of the virtual machines returning the error, and attempted to remediate from the attached baseline to which this completed with success.

Therefore, I was required to remove this file from each virtual machine where the file existed, this is where PowerCLI and in particular the Invoke-VMScript cmdlet come in very useful.

Firstly, we will establish a connection to the vCenter system.

If (-not (Get-PSSnapin VMware.VimAutomation.Core -ErrorAction SilentlyContinue)) 
    {
    Add-PSSnapin VMware.VimAutomation.Core | Out-Null 
    }

Connect-VIServer server1.domain.local | Out-Null

Now, we build a collection of virtual machines, in this instance we only require those with a Microsoft Windows guest operating system.

$VMs = Get-VM | Where-Object {$_.Guest.OSFullName -like "*Windows*"}

For each virtual machine retrieved in the collection we will perform an operation to create the script text required to remove the file and then pass the variable to the Invoke-VMscript cmdlet. In this instance the script type will be configured to be ‘Bat’ as a number of virtual machines in the collection may not have Windows Powershell installed, the default script type for the Invoke-VMScript cmdlet.

The script text as below will use conditional logic to determine if the ‘VMwareToolsUpgrader.exe’ file exists and delete the file.

IF EXIST C:\WINDOWS\Temp\VMwareToolsUpgrader.exe DEL C:\WINDOWS\Temp\VMwareToolsUpgrader.exe

I also want to produce output of each virtual machine the operation has been performed on and report the exit code, while also ignoring any Warnings generated where the VMware Tools service is no up to date.

ForEach ($VM in $VMs)

    { 

        $ScriptText = "IF EXIST C:\WINDOWS\Temp\VMwareToolsUpgrader.exe DEL C:\WINDOWS\Temp\VMwareToolsUpgrader.exe"
        
        $Script = Invoke-VMScript -ScriptText $ScriptText -VM $VM.Name -ScriptType Bat -WarningAction SilentlyContinue
        
        "" + $VM.Name + " completed with exit code " + $Script.ExitCode 
    }