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.
Any idea if this could be altered to find out what HOST is running vmkernal on a given mac address?
ReplyDeleteYes, 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
ReplyDeleteThanks, great script. Runs in about 40 seconds on my environment. Over 3600 VMs currently on that vcenter.
ReplyDeleteHello, 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.
DeleteWorked perfect for me. Thanks.
ReplyDeletewhere 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.
ReplyDeletethanks a lot.
Hello, Unknown-
DeleteYou 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