A scripting “opportunity” came up this week. Apparently ESXi assigns a virtual (or “shadow”) MAC address to each of its physical adapters, over and above the native physical MAC. The request was to report on all of these MACs across a large number of hosts. Read on to see how this resulted in the Get-esxiShadowMAC function.
The scenario was that the network team were querying why they had large numbers of MAC addresses starting with 00:50:56 (VMware vendor code) in their MAC tables. What made these stand out was that the same MAC would appear across dozens of VLANs.
After ruling out the obvious virtual machine interfaces and VMKs, we came across this article:
To summarise, each PNIC on an ESXi system is assigned an additional virtual MAC. Amongst other things, this is the MAC address that ESXi uses when the VDS Health Check is invoked. It follows that this interface address would appear across many VLANs as part of a health check probe.
This is a PowerShell blog, what does this have to do with anything? I thought I’d take the opportunity to share a little bit of ad-hoc scripting I developed during our investigation. PNIC virtual MACs can be discovered by a variety of CLI tools, however I’ve picked out ESXCLI as it’s the easiest to wrap a PowerShell function around.
This is some example output when using ESXCLI (the virtual MAC is the second last line):
What it Does
The function will enumerate the hosts PNICs, then iterate through these in order. It will use ESXCLI via PowerCLI to grab the Virtual MAC property. It will then output an object for each instance of vmnic and its virtual MAC address. ESXCLI makes life easy here, as unlike a shell script or CLI commands its output is parsed automatically in PowerCLI. I can also invoke this directly from PowerCLI using Get-ESXCLi, shell scripts or CLI tools would involve some remote SSH and then parsing string output, not pretty.
The function takes an ESXi host object as input (usually obtained via Get-VMHost). This means there will need to be a connection to the target vCenter first. As an example:
Alternatively you can use pipeline input, handy for bulk operations:
The function also supports -Verbose output should there be a need for more details.
That’s about it, the completed function can be found here: