Home > dvSwitch, E1000E, Guest OS, PowerShell, vSphere, Windows 8, Windows Server 2012 > Work with E1000E NICs in PowerCLI

Work with E1000E NICs in PowerCLI

November 16th, 2012 Leave a comment Go to comments

Now that Windows 8 and Windows Server 2012 are readily available , we all want to do some exploring. But if you want to automate the creation of some test VMs for this, you are in for a surprise.

The current PowerCLI 5.1 Release 1 doesn’t accept the E1000E NIC as a Type on the New-NetworkAdapter cmdlet. Users start hitting this limitation, as can be seen on this PowerCLI Community thread. You can go for the E1000, but why settle for less if you can easily script the use of the E1000E NIC from PowerCLI?

So even though Eric “the Scoop Meister” Sloof debunked the myth that the E1000/E1000E is faster than the VmxNet3, the E1000E is the default NIC type that vSphere gives you when you create a VM for a Windows Server 2012 or Windows 8 VM. Note that the E1000 apparently uses slightly more CPU resources than the E1000E. With the function in this post you can now automate this behavior.

Update November 17th 2012: In KB2006859 it seems to say that the VMXNET3 NIC doesn’t work with Windows Server 2012 or Windows 8. And there have been several blogs (including mine) that picked up this info. But after you apply the September 2012 patch to your ESXi servers, you can also use a VMXNET3 NIC for both Windows OS. See here and here for more info.

Thanks to reader alcapapower for drawing my attention to this (see his remark in the comments below).

The Script

function New-E1000ENic
{
<#
.SYNOPSIS  Add an E1000E NIC to one or more VMs
.DESCRIPTION The function will add an E1000E NIC card to
  each VM that is passed.
.NOTES  Author:  Luc Dekens
.PARAMETER VM
  One or more virtual machines. This parameter accepts
  pipeline input.
.PARAMETER StartConnected
  Wether or not the device is connected when the VM starts
.PARAMETER MacAddress
  MAC address from the allowed range
.PARAMETER WakeOnLan
  Wether or not WOL is enabled on the NIC
.PARAMETER NetworkName
  Name of the network. This can be a portgroup name from a
  VirtualSwitch or from a DistributedSwitch
.PARAMETER DistributedSwitch
  Can only be used in combination with the PortKey.
.PARAMETER PortKey
  The port on the DistributedSwitch where the NIC shall
  connect to.
.EXAMPLE
  PS> New-E1000ENic -VM MyVM -NetworkName pg1
.EXAMPLE
  PS> Get-VM VM | New-E1000ENic -NetworkName pg1
.EXAMPLE
  PS> New-E1000ENic -VM MyVM -DistributedSwitch sw1 -PortKey 100
#>
  param(
    [CmdletBinding(DefaultParametersetName='VirtualSwitch')]
    [Parameter(Mandatory=$true,ValueFromPipeline=$true)]
    [PSObject[]]$VM,
    [Switch]$StartConnected = $false,
    [String]$MacAddress,
    [Switch]$WakeOnLan = $false,
    [Parameter(ParameterSetName='NetworkName')]
    [String]$NetworkName,
    [Parameter(ParameterSetName='DistributedSwitch'Mandatory=$true,)]
    [PSObject]$DistributedSwitch,
    [Parameter(ParameterSetName='DistributedSwitch'Mandatory=$true,)]
    [PSObject]$PortKey
  )

  begin{
    $spec = New-Object VMware.Vim.VirtualMachineConfigSpec
    $dev = New-Object VMware.Vim.VirtualDeviceConfigSpec
    $dev.Operation = "add"
    $dev.Device = New-Object VMware.Vim.VirtualE1000e
    $dev.Device.Connectable = New-Object VMware.Vim.VirtualDeviceConnectInfo
    $dev.Device.Connectable.StartConnected = $StartConnected
    $dev.Device.WakeOnLanEnabled = $WakeOnLan
    switch ($PsCmdlet.ParameterSetName){
      "NetworkName" {
        $pg = Get-VirtualPortGroup -Name $networkName
        if($pg.ExtensionData -is [VMware.Vim.DistributedVirtualPortgroup]){
          $dvPort = New-Object VMware.Vim.VirtualEthernetCardDistributedVirtualPortBackingInfo
          $dvPort.port = New-Object VMware.Vim.DistributedVirtualSwitchPortConnection
          $dvPort.port.switchUuid = $pg.VirtualSwitch.ExtensionData.Uuid
          $dvPort.port.portgroupKey = $pg.Extensiondata.Key
          $dev.Device.Backing = $dvPort
        }
        else{
          $dev.Device.Backing = New-Object VMware.Vim.VirtualEthernetCardNetworkBackingInfo
          $dev.Device.Backing.DeviceName = $NetworkName
        }
      }
      "DistributedSwitch" {
        if($DistributedSwitch.GetType().Name -eq "string"){
          $DistributedSwitch = Get-VirtualSwitch -Distributed -Name $DistributedSwitch
        }
        $pg = Get-VirtualPortGroup -Distributed -VirtualSwitch $DistributedSwitch |
        where {$_.ExtensionData.Portkeys -contains $PortKey}
        if(!$pg){
          Write-Warning "Portkey $PortKey not found on $DistributedSwitch.Name"
          exit
        }
        $dvPort = New-Object VMware.Vim.VirtualEthernetCardDistributedVirtualPortBackingInfo
        $dvPort.port = New-Object VMware.Vim.DistributedVirtualSwitchPortConnection
        $dvPort.port.switchUuid = $dvSw.ExtensionData.Uuid
        $dvPort.port.portgroupKey = $pg.Extensiondata.Key
        $dvPort.port.portKey = $PortKey
        $dev.Device.Backing = $dvPort
      }
    }
    if($MacAddress){
      $dev.Device.MacAddress = $MacAddress
    }
    $spec.deviceChange += $dev
  }

  process{
    foreach($client in $VM){
      if($client.GetType().Name -eq "string"){
        $client = Get-VM -Name $client
      }
      if($client.Version -eq "v8"){
        $client.ExtensionData.ReconfigVM($spec)
        if($PortKey){
          $spec.DeviceChange[0].Device.Backing.port.PortKey =
            [int]$spec.DeviceChange[0].Device.Backing.port.PortKey + 1
        }
      }
      else{
        Write-Warning "$client.Name is not HW version 8"
      }
    }
  }
}

Annotation

Line 39-44: The function supports two parametersets, NetworkName and DistributedSwitch. The parameters NetworkName and DistributedSwitch/PortKey belong to different parametersets and can not be used together.

Line 47-91: The VirtualMachineConfigSpec parameter for the ReconfigVM_Task method is the same for each call, except for the PortKey property (if it is used). For this reason the object is created and configured in the Begin section of the function.

Line 55: Depending on the parameterset used, different properties need to be set.

Line 58: If the NetworkName is for a portgroup on a DistributedSwitch other pproperties need to be set.

Line 71-73, 95-97: A simple implementation of Object By Name

Line 76-79: If the function gets a PortKey that can not be mapped to a PortGroup, the function will exit.

Line 99: The use of an E1000E NIC requires that the VM is at least on hardware version 8.

Line 101-104: If the function is used to add an E1000E NIC on multiple VMs, and if the PortKey parameter is used, the function will automatically take the next portnumber. Make sure that there are enough free ports available to accommodate all the VMs you pass to the function.

Sample run

The function can be used in several ways.

You can call it by passing a NetworkName parameter.

$vm = Get-VM -Name W2K12
New-E1000ENic -VM $vm -NetworkName Net1 -StartConnected


And you can also use the function in a pipeline construct.


Get-VM -Name W2K12* |
New-E1000ENic -NetworkName Net1 -StartConnected

The NetworkName parameter can also point to a portgroup on a DistributedSwitch

$vm = Get-VM -Name W2K12

New-E1000ENic -VM $vm -NetworkName dvPg1 -WakeOnLan -StartConnected


You can specify a specific port with the PortKey parameter. Note that this parameter always needs to be used together with the DistributedSwitch parameter.

$vm = Get-VM -Name W2K12
$dvSw = Get-VirtualSwitch -Distributed -Name dvSw1

New-E1000ENic -VM $vm -DistributedSwitch $dvSw -PortKey 101 -StartConnected

The function increments the PortKey by 1 if you call the function for more than 1 VM. Make sure there are enough free ports, starting from the port you pass in PortKey, to accommodate all the VM for which you call the function.

My dvSwitch scripting – Part 12 – Find free ports post might come in handy here :-)

Enjoy !

  1. November 30th, 2012 at 05:36 | #1

    I wrote a blog post about how to integrate VMXNET3 and PVSCSI drivers directly into the WS2012 and Windows 8 ISOs:

    http://derek858.blogspot.com/2012/10/inject-vsphere-drivers-into-windows.html

    Works like a charm on our ESXi 821926 servers.

    • November 30th, 2012 at 08:46 | #2

      Thanks for sharing Derek, great post and very useful info.

  2. junkydoll
    November 20th, 2012 at 01:31 | #3

    Hi Luc, great site.

    Not wanting to be picky, but your function name seems to be missing a zero …

    Cheers

    • November 20th, 2012 at 14:59 | #4

      @Junkydoll, thanks for spotting that.
      The name has been updated.

  3. November 17th, 2012 at 18:09 | #5

    Great script, but I have to disagree about the statement that the vmxnet3 vNIC doesn’t work with Windows Server 2012/Windows 8 even though that KB article suggests otherwise.

    I have a couple of Windows Server 2012 VMs with vmxnet3 which are running fine on ESXi 5.0 U1 and latest patches.

    Using vmxnet3 is also explicitly supported on 5.1 and 5.0 according to the official HCL:
    http://www.vmware.com/resources/compatibility/detail.php?deviceCategory=software&testConfig=16&productid=19174&releaseid=171&supRel=171,168
    http://www.vmware.com/resources/compatibility/detail.php?deviceCategory=software&testConfig=16&productid=13500&releaseid=168&supRel=171,168

    Btw the line number annotations seem a bit off – I can only see 88 lines of code in your script.

    • November 17th, 2012 at 21:05 | #6

      @alpacapowered, thanks for the feedback.

      The inline function help lines were missing, that should be corrected now.

      I just did another test;
      I patched my server to the latest build, ESXi 5.0.0 build 821926.
      I created a VM with a vmxnet3 card and installed Windows Server 2012 on there.
      This time the VM with Windows Server 2012 comes up without a problem.
      So it looks as if there is a fix in one of the September patches for the problem that existed with VMXNET3 and Windows Server 2012. Unfortunately the patch documentation doesn’t seem to list any specifics for these new Windows OS.

      In any case, I’ll update my post with this new information.
      Then

  1. No trackbacks yet.