function Get-VMByAddress { <# .Description Find all VMs w/ a NIC w/ the given MAC address or IP address (by IP address relies on info returned from VMware Tools in the guest, so those must be installed). Includes FindByIPWildcard, so that one can find VMs that approximate IP, like "10.0.0.*" .Example Get-VMByAddress -MAC 00:50:56:00:00:02 VMName MacAddress ------ ---------- dev0-server 00:50:56:00:00:02,00:50:56:00:00:04 Get VMs with given MAC address, return VM name and its MAC addresses .Example Get-VMByAddress -IP 10.37.31.120 VMName IPAddr ------ ------ dev0-server2 192.168.133.1,192.168.253.1,10.37.31.120,fe80::... Get VMs with given IP as reported by Tools, return VM name and its IP addresses .Example Get-VMByAddress -AddressWildcard 10.0.0.* VMName IPAddr ------ ------ someVM0 10.0.0.119,fe80::... someVM2 10.0.0.138,fe80::... ... Get VMs matching the given wildcarded IP address #> [CmdletBinding(DefaultParametersetName="FindByMac")] param ( ## MAC address in question, if finding VM by MAC; expects address in format "00:50:56:83:00:69" [parameter(Mandatory=$true,ParameterSetName="FindByMac")][string]$MacToFind_str, ## IP address in question, if finding VM by IP [parameter(Mandatory=$true,ParameterSetName="FindByIP")][ValidateScript({[bool][System.Net.IPAddress]::Parse($_)})][string]$IpToFind_str, ## wildcard string IP address (standard wildcards like "10.0.0.*"), if finding VM by approximate IP [parameter(Mandatory=$true,ParameterSetName="FindByIPWildcard")][string]$AddressWildcard_str ) ## end param Process { Switch ($PsCmdlet.ParameterSetName) { "FindByMac" { ## return the some info for the VM(s) with the NIC w/ the given MAC Get-View -Viewtype VirtualMachine -Property Name, Config.Hardware.Device | Where-Object {$_.Config.Hardware.Device | Where-Object {($_ -is [VMware.Vim.VirtualEthernetCard]) -and ($_.MacAddress -eq $MacToFind_str)}} | select @{n="VMName"; e={$_.Name}},@{n="MacAddress"; e={($_.Config.Hardware.Device | Where-Object {$_ -is [VMware.Vim.VirtualEthernetCard]} | %{$_.MacAddress} | sort) -join ","}} break; } ## end case {"FindByIp","FindByIPWildcard" -contains $_} { ## scriptblock to use for the Where clause in finding VMs $sblkFindByIP_WhereStatement = if ($PsCmdlet.ParameterSetName -eq "FindByIPWildcard") {{$_.IpAddress | Where-Object {$_ -like $AddressWildcard_str}}} else {{$_.IpAddress -contains $IpToFind_str}} ## return the .Net View object(s) for the VM(s) with the NIC(s) w/ the given IP Get-View -Viewtype VirtualMachine -Property Name, Guest.Net | Where-Object {$_.Guest.Net | Where-Object $sblkFindByIP_WhereStatement} | Select @{n="VMName"; e={$_.Name}}, @{n="IPAddr"; e={($_.Guest.Net | %{$_.IpAddress} | sort) -join ","}} } ## end case } ## end switch } ## end process } ## end function
A few examples of using the function to find VMs by various addresses (as shown in the comment-based help, too):
PS vN:\> Get-VMByAddress -MAC 00:50:56:00:00:02 VMName MacAddress ------ ---------- dev0-server 00:50:56:00:00:02,00:50:56:00:00:04 PS vN:\> Get-VMByAddress -IP 10.37.31.120 VMName IPAddr ------ ------ dev0-server2 192.168.133.1,192.168.253.1,10.37.31.120,fe80::... PS vN:\> Get-VMByAddress -AddressWildcard 10.0.0.* VMName IPAddr ------ ------ someVM0 10.0.0.119,fe80::... someVM2 10.0.0.138,fe80::... ...
There are several places on the web that talk about getting VMs' IPs, getting their MAC addresses, exporting them, and so on, but this is for getting VMs based on the given address. Note: Since IP address info in vCenter is gotten from guest OSes via VMware Tools, this function is going to rely on that info. And, since the function uses everyone's favorite cmdlet, Get-View, and the calls with this cmdlet are properly tuned, you know that it is going to be FaF!
I tried this script in my env but doesn't work. Seems that it isn't usable out of the box. Could you help me?
ReplyDeleteHello, Alessandro-
DeleteWhat bad news! Yes, we can help, if you help us help: what are some details about your environment (host / vCenter / PowerShell / PowerCLI versions), what is the example command that you are running, and, what symptom(s) do you get when this call seems to not work?
Awesome function! Strangely when I run Get-View -ViewType VirtualMachine -Property Name, Guest.Net the Guest IP addresses aren't returned inside the GuestInfo. Only when I get all of the VM properties, i.e no "filter" for just the Name and Guest.Net properties, do I get the IP Addresses within the Guest.Net object. Interested to know if others are able to limit the properties returned to just Name and Guest.Net and still have the IP Addresses returned??
ReplyDeleteGet-VM | where {$_.Guest.IPAddress -match "IP Here"}
ReplyDeleteReplace "IP Here" with the IP you're searching for in quotes. Since -match is used, you can also wildcard search using this by simply searching for only that which will match. Thus, 172.16.1. will search for all addresses 172.16.1.0-255. .16.1.254 will find all addresses ending in .16.1.254 with any first octet.
This is terrible.
ReplyDeleteuse -filter with get-view and set filter as a variable.
I manage over 6000 vms and piping get-vm is not an option as it would take FOREVER. THe fastest and most efficient way to do something like this would be the following:
$filter = @{'Guest.IPAddress' = "$IP"}
get-view -ViewType VirtualMachine -Filter $filter |
select Name,
@{n='GustOS';e={$_.Summary.Config.GuestFullName}},
@{n='Host';e={get-vmhost -id $_.runtime.host}},
@{n='IP';e={$_.Guest.IPAddress}}
replace $IP with the IP you wish to search for and of course change what you like to select out of it, i chose the name, host it lives on and the guest os.
Here is the function wrapped around it:
Function Get-VMfromIP {
[CmdletBinding()]
param(
[parameter(Mandatory=$true,Position=0)]
[System.Net.IPAddress]$IP
)
$filter = @{'Guest.IPAddress' = "$IP"}
get-view -ViewType VirtualMachine -Filter $filter |
select Name,
@{n='GustOS';e={$_.Summary.Config.GuestFullName}},
@{n='Host';e={get-vmhost -id $_.runtime.host}},
@{n='IP';e={$_.Guest.IPAddress}}
}
Now just execute Get-VMfromIP -IP
You can thank me later :)
example above would be Get-VMfromIP -IP 10.10.0.1
ReplyDeleteOr whatever IP you are searching for...sorry it didnt show up in my original comment.
Hr when I use it wrapped in the function I get nothing back:
ReplyDeletePS C:\Powershell> .\Get-VMfromIP.ps1 -IP 10.10.0.1
PS C:\Powershell>
However when I hardcode the IP it works perfectly. Any suggestions?
Thanks for sharing!
ReplyDeleteI did change a couple things though. I did a search/replace on the following variables:
$MacToFind_str --> $MAC
$IpToFind_str --> $IP
$AddressWildcard_str --> $AddressWildcard
That way when tabbing through values in a powershell session, the results match up with the syntax you have mentioned in the examples.