A quick one today on PowerCLI. A colleague asked about how to retrieve a list of VTEPs assigned to a host. I was asked because they though PowerNSX may actually do this but low and behold, good old PowerCLI can do the trick.
The use of Get-VMHostNetworkAdapter will help here.
The first example will Get all vSphere hosts and for all host check their network adapters. The toggle of VMKernel will only return VMKernel interfaces. From there the command will search the name property and ignore vmk0.
Name Mac DhcpEnabled IP SubnetMask DeviceName ---- --- ----------- -- ---------- ---------- vmk1 00:50:56:65:65:b3 False 172.16.110.201 255.255.255.0 vmk1 vmk1 00:50:56:6e:84:f3 False 172.16.110.203 255.255.255.0 vmk1 vmk1 00:50:56:6e:e5:bb False 172.16.110.204 255.255.255.0 vmk1 vmk1 00:50:56:6d:8b:dd False 172.16.110.202 255.255.255.0 vmk1 vmk1 00:50:56:60:a6:16 False 172.16.111.204 255.255.255.0 vmk1 vmk1 00:50:56:6e:90:26 False 172.16.111.201 255.255.255.0 vmk1 vmk1 00:50:56:62:33:21 False 172.16.111.203 255.255.255.0 vmk1 vmk1 00:50:56:6d:e9:1b False 172.16.111.202 255.255.255.0 vmk1
This returns all other VMKs. I know for a fact that vmk1 is my current VTEP vmk but what if I had VSAN, FT, or other VMKs in use? What if auto-deploy was assigning them different and across different clusters the VTEP was assigned to a different VMK?
I know for a fact that in this case VMK1 is my VXLAN subnet. Alternative is to match on known subnets from the IP Pool assigned to the VTEP interfaces in Host Preparation. These can be pulled from IP pools or DHCP leases. This works if the VMK differ per cluster.
The second example will Get all vSphere hosts and for all host check their network adapters. The toggle of VMKernel will only return VMKernel interfaces. From there the command will search the IP property and match any with 172.16.11*
PowerCLI C:\> Get-VmHost | Get-VMHostNetworkAdapter -Vmkernel | ? {$_.IP -match ("172.16.11")} Name Mac DhcpEnabled IP SubnetMask DeviceName ---- --- ----------- -- ---------- ---------- vmk1 00:50:56:65:65:b3 False 172.16.110.201 255.255.255.0 vmk1 vmk1 00:50:56:6e:84:f3 False 172.16.110.203 255.255.255.0 vmk1 vmk1 00:50:56:6e:e5:bb False 172.16.110.204 255.255.255.0 vmk1 vmk1 00:50:56:6d:8b:dd False 172.16.110.202 255.255.255.0 vmk1 vmk1 00:50:56:60:a6:16 False 172.16.111.204 255.255.255.0 vmk1 vmk1 00:50:56:6e:90:26 False 172.16.111.201 255.255.255.0 vmk1 vmk1 00:50:56:62:33:21 False 172.16.111.203 255.255.255.0 vmk1 vmk1 00:50:56:6d:e9:1b False 172.16.111.202 255.255.255.0 vmk1
The third example will get a specific cluster first. It will get Mgmt01. Get-VmHost will then return all vSphere hosts in that cluster and for all hosts found check their network adapters. The toggle of VMKernel will only return VMKernel interfaces. From there the command will search the IP property and match any with 172.16.11*. This reduces the number of hosts being looked up if you have lots of clusters and lots of hosts in each cluster.
PowerCLI C:\> Get-Cluster Mgmt01 | Get-VmHost | Get-VMHostNetworkAdapter -Vmkernel | ? {$_.IP -match ("172.16.11")} Name Mac DhcpEnabled IP SubnetMask DeviceName ---- --- ----------- -- ---------- ---------- vmk1 00:50:56:65:65:b3 False 172.16.110.201 255.255.255.0 vmk1 vmk1 00:50:56:6e:84:f3 False 172.16.110.203 255.255.255.0 vmk1 vmk1 00:50:56:6e:e5:bb False 172.16.110.204 255.255.255.0 vmk1 vmk1 00:50:56:6d:8b:dd False 172.16.110.202 255.255.255.0 vmk1
The fourth example will append the host name. The Get-VmHostNetworkAdapter -Vmkernel command will get every hosts VMK interface. The toggle of VMKernel will only return VMKernel interfaces. Select will allow me to customer the output from the command. The fields selected are Vmhost, name, ip, and mac. This customises the out put and then is run over the where is command. The where is ( ? ) command will search the IP property and match any with 172.16.11*.
PowerCLI C:\> Get-VmHostNetworkAdapter -VMkernel | select vmhost,name, ip, mac | ? {$_.IP -match ("172.16.11")} VMHost Name IP Mac ------ ---- -- --- mgt-esxi1.corp.local vmk1 172.16.110.201 00:50:56:65:65:b3 mgt-esxi2.corp.local vmk1 172.16.110.203 00:50:56:6e:84:f3 mgt-esxi3.corp.local vmk1 172.16.110.204 00:50:56:6e:e5:bb mgt-esxi4.corp.local vmk1 172.16.110.202 00:50:56:6d:8b:dd compute01-esxi1.corp.local vmk1 172.16.111.204 00:50:56:60:a6:16 compute01-esxi2.corp.local vmk1 172.16.111.201 00:50:56:6e:90:26 compute01-esxi3.corp.local vmk1 172.16.111.203 00:50:56:62:33:21 compute01-esxi4.corp.local vmk1 172.16.111.202 00:50:56:6d:e9:1b
The fifth example would exporting the above to a CSV. The command above coupled with | export-csv C:\VTEP.csv does the trick.
Get-VmHostNetworkAdapter -VMkernel | select vmhost,name, ip, subnetmask, mac, devicename | ? {$_.IP -match ("172.16.11")} | export-csv C:\VTEP.csv
PowerCLI helping documentation for the win!
Great Post! Thought I would share a little about what I did, for the same exact reason. The code below will only return the vmk interfaces that belong to the ‘vxlan’ TCP/IP stack, which should give you a result without having to filter anything else out (https://gist.github.com/vScripter/ff80797baaed06f42e542f5ae3c0dd16).
###
$vtepReportPath = “$Home\Desktop\ESXi_VTEP_Report.csv”
$vtepFinalReport = @()
Get-VMHostNetworkAdapter -VMKernel | Foreach-Object {
$vtepInterfaceQuery = $null
$vtepInterfaceQuery = $_.ExtensionData | Where-Object {$_.Spec.NetStackInstanceKey -eq ‘vxlan’}
foreach ($vtep in $vtepInterfaceQuery) {
$objVtepInt = @()
$objVtepInt = [PSCustomObject] @{
VMHost = $_.VMHost
Interface = $vtep.Device
MacAddress = $vtep.Spec.Mac
IPv4Address = $vtep.Spec.Ip.IpAddress
SubnetMask = $vtep.Spec.Ip.SubnetMask
DHCP = $vtep.Spec.Ip.Dhcp
MTU = $vtep.Spec.Mtu
TsoEnabled = $vtep.Spec.TsoEnabled
NetworkStack = $vtep.Spec.NetStackInstanceKey
PinnedPnic = $vtep.Spec.PinnedPnic
} # end $objVtepInt
$vtepFinalReport += $objVtepInt
} # end foreach $vtep
} # end foreach-object
$vtepFinalReport | Export-Csv -Path $vtepReportPath -NoTypeInformation -Force
####
I also created a more robust function that will achieve the same thing, but it pulls an inventory using API calls (Get-View), which runs much faster, particularly in larger environments. (https://gist.github.com/vScripter/a2e5712b8350c909c8c15df26cf3a075).
Nice stuff man. I received an update not long after the post talking about ExtensionData. Super handy!
Appreciate your write up on this and your example. Very nice.