Save to My DOJO
Table of contents
Retrieving a virtual machine’s IP addresses isn’t an especially difficult process, but it’s still something you might do often enough that it would be convenient to have a quicker way. For me, I don’t do it often, but I still like to have a single function. I’ve improved the one I use to make it more useful for a variety of purposes.
This article is part of the Hyper-V and PowerShell series.
The script is quite simple. It just needs a VM, either by name or by using a VM object. I gave it a few extra parameters.
Parameters
- Name: The name of the virtual machine whose IP addresses you wish to retrieve. Cannot be used with VM.
- ComputerName: The name of the host that contains the virtual machine whose IP addresses you wish to receive. Cannot be used with VM.
- VM: The VM object whose IP addresses you wish to receive. Cannot be used with Name or ComputerName.
- Type: There are three options, and you can use tab completion to cycle through them .”Any” shows all IP addresses. “IPv4” shows only IPv4 addresses. “IPv6” shows only IPv6 addresses.
- IgnoreAPIPA: Skips 169.254.0.0/16 IPv4 addresses and fe80::/64 IPv6 addresses.
Type Modification
By default, the “Type” is “Any”, so it will retrieve both IPv4 and IPv6 addresses if you don’t specify otherwise. If you prefer, you can modify line 85 to change the default to IPv4 or IPv6.
The Script
Copy the contents of the following script block into a text editor and save it as a .PS1 file. It’s written to expect Get-VMIPAddresses.ps1 as the name, but you can use anything you like:
<# .SYNOPSIS Lists the IP addresses for a virtual machine. .DESCRIPTION Lists the IP addresses for a virtual machine. Can optionally be limited to IPv4 or IPv6 addresses. .PARAMETER Name The name of the virtual machine whose IP addresses you wish to retrieve. Cannot be used with VM. .PARAMETER ComputerName The name of the host that contains the virtual machine whose IP addresses you wish to receive. Cannot be used with VM. .PARAMETER VM The VM object whose IP addresses you wish to receive. Cannot be used with Name or ComputerName. .PARAMETER Type "Any" shows all IP addresses. "IPv4" shows only IPv4 addresses. "IPv6" shows only IPv6 addresses. .PARAMETER IgnoreAPIPA Skips 169.254.0.0/16 IPv4 addresses and fe80::/64 IPv6 addresses. .OUTPUTS A string array of the virtual machine's IP addresses. .NOTES Author: Eric Siron Copyright: (C) 2014 Altaro Software Version 1.0 Authored Date: November 17, 2014 .LINKHyper-V and PowerShell: Get Hyper-V VM IP Addresses.EXAMPLE C:\PS> .\Get-VMIPAddresses -Name svtest Description ----------- Retrieves the IP addresses for the VM named svtest. .EXAMPLE C:\PS> .\Get-VMIPAddresses -Name svtest -ComputerName svhv2 Description ----------- Retrieves the IP addresses for the VM named svtest on host svhv2. .EXAMPLE C:\PS> .\Get-VMIPAddresses -Name svtest -Type IPv6 Description ----------- Retrieves only the IPv6 addresses used by svtest. #> #requires -Version 3 #requires -Modules Hyper-V [CmdletBinding()] param ( [Alias("VMName")] [Parameter(ValueFromPipeline=$true, ValueFromPipelineByPropertyName=$true, ParameterSetName='ByName', Mandatory=$true, Position=1)] [String]$Name, [Alias("VMHost")] [Parameter(ValueFromPipelineByPropertyName=$true, Position=2, ParameterSetName='ByName')] [String]$ComputerName = $env:COMPUTERNAME, [Parameter(ValueFromPipeline=$true, ValueFromPipelineByPropertyName=$true, ParameterSetName='ByVM')] [Microsoft.HyperV.PowerShell.VirtualMachine]$VM, [Parameter(ValueFromPipelineByPropertyName=$true)] [ValidateSet("Any", "IPv4", "IPv6")] [String]$Type, [Parameter(ValueFromPipelineByPropertyName=$true)] [Switch]$IgnoreAPIPA=$false ) BEGIN { New-Variable -Name DefaultType -Value "Any" -Option Constant # Change to IPv4 or IPv6 if desired } PROCESS { if([String]::IsNullOrEmpty($Type)) { $Type = $DefaultType } if($VM) { $ParameterSet = @{ 'VM'=$VM } } else { $ParameterSet = @{ 'VMName'="$Name"; 'ComputerName'="$ComputerName" } } $IPAddresses = (Get-VMNetworkAdapter @ParameterSet).IPAddresses switch($Type) { "IPv4" { $IPAddresses = $IPAddresses | where { $_ -match "\." } } "IPv6" { $IPAddresses = $IPAddresses | where { $_ -match ":" } } } if($IgnoreAPIPA) { $IPAddresses = $IPAddresses | where { $_ -notmatch "^(169.254)|(fe80)" } } $IPAddresses } END {}
Converting to a Function
This was written as a script that you call as needed. If you’d like to convert it to a function so you can place it into your PowerShell profile, encapsulate the entire contents of the BEGIN, PROCESS, and END blocks inside a function, preferably Get-VMIPAddresses. In order for the context-sensitive help to work, you’ll also need to move that inside the function block. For example:
#requires -Version 3 #requires -Modules Hyper-V function Get-VMIPAddresses { <# ... help info... #> BEGIN { ... begin block contents } PROCESS { ... process block contents } END {} }
In the next post in the series we will show you an easy way to get a Hyper-V VM MAC Address.
Not a DOJO Member yet?
Join thousands of other IT pros and receive a weekly roundup email with the latest content & updates!
18 thoughts on "Hyper-V and PowerShell: Get Hyper-V VM IP Addresses"
I like this! Going to test for teamed VM adapters.
Thank you, Eric!
This returns empty for most of my VMs. Digging in a bit, Get-VMNetworkAdapter is returning an empty response for IPAddresses for those VMs. Three VMs (2xWin2k8 and 1xUbuntu 14.04) work, multiple others (Ubuntu 14.04) are blank despite being up/online/communicating and using static IP assignments. Any hints?
If the virtual machine is online and working normally, the only way I know of that this can happen is if the “Data Exchange” integration service is not working. If that’s the case, “Get-VMIntegrationService” should show that, and running “Get-VM | fl *” will show other empty fields, such as “IntegrationServicesVersion”.
Thanks. There’s a manual step required for Ubuntu install as hyper-v client that apparently I knew at one time but had forgotten: (step #5 of the link below)
http://technet.microsoft.com/en-us/library/dn531029.aspx
After installing the hv-kvp-daemon on the newer VMs, the Get-VMIntegrationService is happy and the Get-VMIPAddresses script now works for all.
Well – almost all working (see below) – one of the VMs has two NICs (eth0/eth1 in Linux land). The Get-VMIPAddresses script appears to expect a unique VMName for every NIC/interface and so it outputs the info for the first interface twice. How should this work? Is it unusual/wrong that my two NICs show up as two rows from Get-VMNetworkAdapter? Or, should a different ID be used by the script with iterating the IPs for a given VM? Thanks!
Ferrell
Get-VMNetworkAdapter -All | FT -property VMName, IPAddresses, Status
vmtest2 {192.168.1.3, fe80::215:5dff:fe01:e013} {Degraded, ProtocolVersion}
vmtest2 {172.16.0.3, fe80::215:5dff:fe01:e014} {Degraded, ProtocolVersion}
PS C:ferrell> .Get-VMIPAddresses.ps1 vmtest2
192.168.1.3
fe80::215:5dff:fe01:e013
192.168.1.3
fe80::215:5dff:fe01:e013
I don’t have a VM with two interfaces, although I could test this later. Everything in the script that really matters happens on line 101. It only talks to each virtual machine one time. Before working on the above script, I would start by running “Get-VMNetworkAdapter -VMName VM-TO-CHECK | select AdapterId, IPAddresses” to see if that is outputting things the way you expect.
Eric,
Believe this may be applicable here. Came up with this last night. The table will look much better inside powershell 🙂
= = = =
RETURN IP ADDRESSES FROM VMNETWORKADAPTERS
= = = =
PS C:> Get-VMNetworkAdapter -all | Where-Object {$_.IsManagementOs -like “False
“} | ft IsManagementOs,VMName,Name,IPAddresses -AutoSize
IsManagementOs VMName Name IPAddresses
————– —— —- ———–
False MyVM-DC01 vNIC1-Mgmt {10.20.30.1, fe80::5957:7819:158d:a1b2}
False MyVM-SQL01 vNIC2-Mgmt {10.20.30.2, fe80::d51e:cd45:a82d:c3d4}
False MyVM-VMM01 vNIC3-Mgmt {10.20.30.3, fe80::3c06:630c:7afe:e5f6}
= = = =
END
= = = =
I like it!
Eric,
Believe this may be applicable here. Came up with this last night. The table will look much better inside powershell 🙂
= = = =
RETURN IP ADDRESSES FROM VMNETWORKADAPTERS
= = = =
PS C:> Get-VMNetworkAdapter -all | Where-Object {$_.IsManagementOs -like “False
“} | ft IsManagementOs,VMName,Name,IPAddresses -AutoSize
IsManagementOs VMName Name IPAddresses
————– —— —- ———–
False MyVM-DC01 vNIC1-Mgmt {10.20.30.1, fe80::5957:7819:158d:a1b2}
False MyVM-SQL01 vNIC2-Mgmt {10.20.30.2, fe80::d51e:cd45:a82d:c3d4}
False MyVM-VMM01 vNIC3-Mgmt {10.20.30.3, fe80::3c06:630c:7afe:e5f6}
= = = =
END
= = = =
Hi Eric,
The primary reason for this method is we are going to change the VLAN Subnet where the current VDI Machines resides and I’m thinking by doing this method, the moment the VMNetworkAdapter is disconnected and connected back, VMs suppose to get a new IP from the new vLAN.. Or the VMs will be connected back using their old IPs?
Is there another command to renew the IP of each VM instead of disconnecting the VMNetworkAdapter?
Regards,
From outside the VM, disconnecting the virtual adapter is the only way to convince it to try to get a new DHCP address. Anything else would have to be done inside the guest.
Hi Eric,
The primary reason for this method is we are going to change the VLAN Subnet where the current VDI Machines resides and I’m thinking by doing this method, the moment the VMNetworkAdapter is disconnected and connected back, VMs suppose to get a new IP from the new vLAN.. Or the VMs will be connected back using their old IPs?
Is there another command to renew the IP of each VM instead of disconnecting the VMNetworkAdapter?
Regards,