PowerCli: Creating VMK-if on the vmotion netstack on a DVS (with the correct gateway IP configured)

Good scripts are created out of frustration: And here’s a good example of this statement!

I wasn’t able to find a script which was able to create a VMK-interface connected to a DVS, being a part of the vmotion netstack AND with a default gateway configured at the netstack-level (and not the VMK-if.

The majority of the scripts (which I stole shameless from my collegeau Wesley Geelhoed) were able to add a new VMK-interface, connected to a VMware Standard vSwitch (VSS) and migrate afterwards. And also the majority of the script which I found online were able to configure the default gateway on the VMK-interface itself (as an override) instead of configuring it on the netstack self.

So behold, first the explanation of the script (scroll down for the full blown script)

First let’s select the ESXi host and retrieve some needed variables.

$vmhost = get-vmhost | Out-GridView -Title "Select ESXi host" -OutputMode Single
$IP = Read-Host -Prompt "IP address"
$IPSubnetMask = Read-Host -Prompt "IP Subnetmask"
$IPgateway = Read-Host -Prompt "IP Gateway"
$DvSwitch = Get-VDSwitch | Out-GridView -Title "Select DVS" -OutputMode Single
$DvPortGroup = Get-VDPortgroup -VDSwitch $DvSwitch | Out-GridView -Title "Select vMotion portgroup" -OutputMode Single

In my situation I use a csv.file which contains all necessary information and import it with the import-csv cmdlet and use a foreach loop. For the sake of simplicity I used the code-block above in this blog.

As the native PowerCLI cmdlets are not able to configure the most items, we must use the get-esxcli cmdlet: I use version 2, as it is more flexible when I’m writing the script:

$esxcli = Get-EsxCli -VMHost $vmhost -V2

Let’s start with creating the “vmotion” netstack:

$esxcli.network.ip.netstack.add.invoke(@{netstack = "vmotion"})

For connecting a VMK-interface to a Distributed vSwitch port, we need to assign an PortId.
So I first create a dummy VMK interface, retrieve the required information, and destroy it immediately afterwards.

$vmk1 = New-VMHostNetworkAdapter -VMHost $vmhost -PortGroup $DvPortGroup  -virtualSwitch $vSwitch 
$np = ($DvPortGroup  | get-vdPort | ? {$_.ProxyHost -match $vmhost.name})
$esxcli.network.ip.interface.remove.Invoke(@{dvportid = $np.Id;dvsname = $np.Switch})

now let’s create the vMotion VMkernel interface, connect it to the dvSwitch and set IP address, subnet and MTU:

$esxcli.network.ip.interface.add.Invoke(@{dvsname = $np.Switch.Name;netstack = "vmotion";interfacename = $np.ConnectedEntity.Name;dvportid = $np.Id; mtu = "9000"})
$esxcli.network.ip.interface.ipv4.set.Invoke(@{interfacename = ‘vmk1’; ipv4 = $ip; netmask = $IPSubnetMask; type = ‘static’})

and as a last step, add the default gateway to the vmotion-netstack:

$esxcli.network.ip.route.ipv4.add.invoke(@{netstack="vmotion";gateway=$IPgateway;network="default"})

And you’re done!

Below the whole script

#define variable
$vmhost = get-vmhost | Out-GridView -Title "Select ESXi host" -OutputMode Single
$IP = Read-Host -Prompt "IP address"
$IPSubnetMask = Read-Host -Prompt "IP Subnetmask"
$IPgateway = Read-Host -Prompt "IP Gateway"
$DvSwitch = Get-VDSwitch | Out-GridView -Title "Select DVS" -OutputMode Single
$DvPortGroup = Get-VDPortgroup -VDSwitch $DvSwitch | Out-GridView -Title "Select vMotion portgroup" -OutputMode Single

#connect to esxcli
$esxcli = Get-EsxCli -VMHost $vmhost -V2

#create vmotion netstack
$esxcli.network.ip.netstack.add.invoke(@{netstack = "vmotion"})

#retrieve free DVS port id
$vmk1 = New-VMHostNetworkAdapter -VMHost $vmhost -PortGroup $DvPortGroup -virtualSwitch $DvSwitch 
$np = ($DvPortGroup  | get-vdPort | ? {$_.ProxyHost -match $vmhost.name})
$esxcli.network.ip.interface.remove.Invoke(@{dvportid = $np.Id;dvsname = $np.Switch})

#create vMotion VMkernel interface and set IP address
$esxcli.network.ip.interface.add.Invoke(@{interfacename = 'vmk1'; dvsname = $np.Switch.Name; netstack = 'vmotion'; dvportid = $np.Id; mtu = '9000'})
$esxcli.network.ip.interface.ipv4.set.Invoke(@{interfacename = ‘vmk1’; ipv4 = $IP; netmask = $IPSubnetMask; type = ‘static’})
#configure default gateway on vmotion netstack (not on the VMK-interface)
$esxcli.network.ip.route.ipv4.add.invoke(@{netstack="vmotion";gateway=$IPgateway;network="default"})

Again, I want to thank my collegeau Wesley Geelhoed, as his blog really helped me!

2 Comments

  1. Kavsa
    January 7, 2024

    Hi there, this can be very helpful but How on earth did you manage to create a vmk on a DVport group on a switch in the first place? Ive tried it and it does not allow me too. the only way is on the standard switch using esxcli
    i cannot progress past the line vmk1 = New-VMHostNetworkAdapter -VMHost $vmhost -PortGroup $DvPortGroup -virtualSwitch $DvSwitch

    says the argument -portgroup is null. cannot validate argument on parameter -portgroup
    But I have clearly set the variable? for it using get-vdportgroup -name $portgroupname -vdswitch $vds

    much appreciated

    Reply
    1. admin
      January 7, 2024

      Hi Kavsa,

      You are sure asking me something. It’s 4,5 years ago that I developed this script.
      I don’t have a test-environment available at this moment, but I think I have an idea where it goes wrong.
      could you replace:
      vmk1 = New-VMHostNetworkAdapter -VMHost $vmhost -PortGroup $DvPortGroup -virtualSwitch $DvSwitch
      with
      vmk1 = New-VMHostNetworkAdapter -VMHost $vmhost -PortGroup $DvPortGroup.name -virtualSwitch $DvSwitch

      Please let me know

      Reply

Leave a Reply

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

Scroll to top