11 September 2011

Find VM by NIC MAC Address with PowerShell -- Fast Like!

There is the occasion on which it would be handy to find a VM based on a known MAC address. Say, for example, there is a duplicate IP address on the network, and the network team informs you of the offending MAC addresses. Unfortunately, there is not a simple/easy way to go about this.

There are some places on the web that discuss this topic, but none were satisfactory. Some were overly complex, storing objects and data without need. Others were written with the ease of writing being considered. While these will work, they do not suffice if the size of the environment is larger. Memory usage climbs in the PowerShell session, and the time-to-run grows far past what is necessary and desirable.

Yet another problem was the reliance of some scripts on VMware Tools to get the information. Granted, VMs would ideally have Tools current and running, but, we all know that in the real world, that just does not always happen.

So, we wrote a little nugglet that will get the VM(s) that have VirtualEthernetCard(s) with the given MAC address:
## Script function: find all VMs with one or more NIC with the given MAC address
## Author: vNugglets.com -- Aug 2011

## MAC addr of NIC(s) to find
$strMacToFind = "00:50:56:83:00:69"
## return the .NET View object(s) for the VM(s) with the NIC w/ the given MAC
Get-View -Viewtype VirtualMachine -Property Name, Config.Hardware.Device | ?{$_.Config.Hardware.Device | ?{($_ -is [VMware.Vim.VirtualEthernetCard]) -and ($_.MacAddress -eq $strMacToFind)}}

This is pretty straight forward to use: just set the variable for the MAC address to find, and then run the next line of code. This returns the .NET View object(s) for the VM(s) that have a NIC with the given MAC address. One could then do as they pleased with the objects.

To just report the info about the VM(s) with a NIC with the given MAC address, one could add a simple Select-Object statement. The following returns a list of matching VMs' names and their associated NICs' MAC addresses:
Get-View -Viewtype VirtualMachine -Property Name, Config.Hardware.Device | ?{$_.Config.Hardware.Device | `
?{($_ -is [VMware.Vim.VirtualEthernetCard]) -and ($_.MacAddress -eq $strMacToFind)}} | `
Select name, @{n="MAC(s)"; e={($_.Config.Hardware.Device | ?{($_ -is [VMware.Vim.VirtualEthernetCard])} | %{$_.MacAddress}) -join ","}}

The output would be something like:
Name     MAC(s)
----     ------
myVM     00:50:56:83:00:69,00:0c:29:00:08:01

PS C:\>

As for speed: this method of finding VMs with a given MAC address took around 25 seconds when run in a test environment of about 3200 VMs. Fast. Enjoy.

Update (30 Oct 2011 -- response to comment):
To use a similar technique to find a VMHost with a given MAC address, you can look at the Config.Network.Pnic property of a HostSystem .NET View object.  To find a VMHost with a given MAC, and quick like, use:
## to find a VMHost with given MAC address:
$strMacOfNICOnVMHostToFind = "00:0e:0c:00:00:01"

Get-View -ViewType HostSystem -Property Name, Config.Network.Pnic | ?{$_.Config.Network.Pnic | ?{$_.Mac -eq $strMacOfNICOnVMHostToFind}} | select Name, @{n="MAC(s)"; e={($_.Config.Network.Pnic | %{$_.Mac}) -join ","}}

The output is similar to the output above, but the Name will be of the given VMHost, and MAC(s) will be that host's MAC addresses. Enjoy, "Anonymous" commenter.

7 comments:

  1. Any idea if this could be altered to find out what HOST is running vmkernal on a given mac address?

    ReplyDelete
  2. Yes, Anonymous, it would be pretty easy to get the VMHost based on a given MAC address. It is a similar concept to the original code. I updated the post with a piece to get a VMHost based on a MAC address. Enjoy

    ReplyDelete
  3. Thanks, great script. Runs in about 40 seconds on my environment. Over 3600 VMs currently on that vcenter.

    ReplyDelete
    Replies
    1. Hello, Anonymous- Glad you enjoyed the script, and thanks for sharing your results. Always good to hear other people's experiences with the things about which we have written.

      Delete
  4. Worked perfect for me. Thanks.

    ReplyDelete
  5. where should I run this script? in the Vcenter server or in ESX servers? i know is silly question since looks most of people know where to run it but I want to take the risk and ask.

    thanks a lot.

    ReplyDelete
    Replies
    1. Hello, Unknown-

      You can run this code from . So, your workstation, your tools server, etc. You just need to have PowerShell and PowerCLI installed, network connectivity to the vCenter server, and credentials for the vCenter server.

      You connect to the vCenter server in PowerShell like:
      PS C:\> Connect-VIServer -Server myvcenter.dom.com -Credential $myCreds

      Then, you can invoke the code in this post.

      How's that work out for you?

      Cheers,
      Matt

      Delete