This guide will show you a quick way to see which Virtual Machine NIC is connected to which Virtual Switch in Hyper-V. This is particularly helpful for VMs that have two or more virtual network adapters.

Prerequisites

  • Basic knowledge of Hyper-V and Windows Networking
  • The Hyper-V module for Windows PowerShell
  • Any supported version of the Windows Operating System

Current scenario (example)

If you have a VM with multiple virtual network interface cards (NIC), it can be challenging to know which NIC is connected to which virtual switch. If you created the VM using the default naming convention, they are all named "Network Adapter" in Hyper-V.

In the examples I provide below, I worked with a VM, named "Proxy2," that has two NICs: one connected to the virtual switch ExternalLan and one connected to the virtual switch Private.

NIC summary host GUI

NIC summary host GUI

The PowerShell equivalent to see the NIC-related summary is:

Get-VMNetworkAdapter -VMName "Proxy2" | Select-Object VMName,SwitchName,Name 

Both NICs have the same name (Network Adapter), as shown in the screenshot below.

NIC summary host PowerShell

NIC summary host PowerShell

If we look at the NICs from inside the VMs in the Network Connections applet (ncpa.cpl), there's not too much information there either. The first NIC is named "Ethernet," and all other NICs are named "Ethernet," followed by a number ("Ethernet 2," in this case).

NIC summary Guest GUI

NIC summary Guest GUI

Using PowerShell inside the VM shows the same (little) information:

Get-NetAdapter 
NIC summary Guest PS

NIC summary Guest PS

With only this information, it is difficult to know whether, for example, the interface "Ethernet 2" is connected to the Private virtual switch or to the ExternalLan. Fortunately, there is a simple solution.

Desired scenario: VMs with NIC names that are easily identifiable

There are three simple steps to follow to make your VM's NICs easy to identify. Here is an overview, before we discuss each step in more detail.

Turn on Device Naming for the NIC, which enables seeing the name of the NIC inside the VM. This only works for supported operating systems. I hope that in the future all the operating systems supported by Hyper-V will support this, and the setting will be turned on by default. But for now, at least, this feature works on all the supported editions of Windows (both Client and Server).

On the Hyper-V host, change the name each of the VM's NICs to a more relevant name.

In the VM, I will rename the NICs from "Ethernet x" to the name I assigned in the previous step. It is easier than it sounds, and it will be clearer once we work with an actual example.

Below, we explain each step in more detail.

Step 1: Enable Device Naming

Using the GUI

Before renaming a VM's NICs, there is one thing you need to do, which allows you to "see" the (new) name of the NIC inside the VM as well. This task is accomplished by turning on the "DeviceNaming" attribute of the NIC, using the Hyper-V GUI (or the Cluster Manager console if your VMs are clustered). To turn on Device Naming in the GUI:

  1. Select the Network Adapter and click the "+" sign to expand its properties.
  2. Select Advanced Features.
  3. Scroll to the Enable device naming property and enable it (here you also see the explanation of this setting).
  4. Click Apply to apply the setting and repeat this for all the other NICs of the VM.
Device Naming GUI

Device Naming GUI

Using PowerShell

Of course, you can achieve this in PowerShell, using the DeviceNaming switch with the commands Add-VMNetworkAdapter (for a new NIC) or Set-VMNetworkAdapter (for an existing NIC). Here is how to turn on Device Naming for all the NICs of the VM "Proxy2":

Get-VMNetworkAdapter -VMName "Proxy2" |Set-VMNetworkAdapter -DeviceNaming On 
Device naming PS

Device naming PS

That is all. Just one single line for all the NICs. Of course, you could do this for all the VMs in a single line, which can save you a lot of clicks.

Step 2: Change the name of the NICs in the Hyper-V host

In this step, you will change the name of the NICs to something more relevant than "Network Adapter."

I prefer to name each NIC according to the virtual switch the NIC is connected to. In our case, the NIC connected to the ExternalLan virtual switch will be called "ExternalLan," and the NIC connected to the Private virtual switch will be called "Private." I admit it is not the most creative solution, but it is simple to automate and better than "Network Adapter" for every NIC attached to the VM.

Of course, you may use different names that make more sense to you. For instance, you might rename the NIC connected to an "external" to "Internet" and the NIC connected to an isolated network could be called "Corporate" or "Internal." I will provide examples for both scenarios.

You can assign a different name to a NIC either when you create it and add it to a VM (Add-VMNetworkAdapter) or when you reconfigure an existing one (Set-VMNetworkAdapter).

This means you can easily perform this on your existing VMs without having to remove and then add new NICs.

Note: You need to use PowerShell to change the name of a NIC; there is no way to rename it via the GUI.

Note: If you just turned on Device Naming, you will need to reboot the VM.

Scenario 1: Rename each NIC to the name of the virtual switch it is connected to

In this case, every NIC attached to the VM will be renamed to the name of the virtual switch it is connected to. Each command has a comment to explain what the command does.

# Name of the VM for which the NICs will be renamed
$VM = "Proxy2"

# Get a list of all the switches the $VM has NICs connected to
$VmSwitches = (Get-VMNetworkAdapter -VMName $VM).SwitchName

# Rename each NIC of the VM to the name of the virtual switch it is connected to
foreach ($C in $VmSwitches) { 
  Get-VMNetworkAdapter -VMName $VM `
  | Where-Object SwitchName -EQ $C `
  | Rename-VMNetworkAdapter -NewName $C -Verbose 
} 
Scenario 1 Host rename NICs

Scenario 1 Host rename NICs

The renamed VNICs (in the GUI):

Scenario 1 Result GUI

Scenario 1 Result GUI

The renamed VNICs (in PowerShell):

Get-VMNetworkAdapter -VMName "Proxy2" | Select-Object VMName,SwitchName,Name 
Scenario 1 Result PS

Scenario 1 Result PS

Scenario 2: Rename each NIC to custom names

In this case, every NIC attached to the VM will be renamed to the name of the virtual switch it is connected to. As in Scenario 1 above, each command has a comment to explain what the command does.

# Name of the VM for which the NICs will be renamed
$VM = "Proxy2"
# Rename the NIC connected to the ExternalLan virtual switch to a custom name
Get-VMNetworkAdapter -VMName $VM `
| Where-Object SwitchName -EQ "ExternalLan" `
| Rename-VMNetworkAdapter -NewName "Internet" -Verbose

# Rename the NIC connected to the Private virtual switch to a custom name
Get-VMNetworkAdapter -VMName $VM `
| Where-Object SwitchName -EQ "Private" `
| Rename-VMNetworkAdapter -NewName "Corporate" -Verbose 
Scenario 2 Host rename NICs

Scenario 2 Host rename NICs

The renamed VNICs:

Get-VMNetworkAdapter -VMName "Proxy2" | Select-Object VMName,SwitchName,Name

At the end of Step 2, the NICs attached to the VM have been renamed to more relevant names. In the next step, the NICs from inside the VM will be renamed to match the names we just defined.

Step 3: Change the name of the NICs inside the VM using PowerShell

So far, the NICs of our VM have been renamed with more relevant names. At this moment, the name of the NICs inside the VM are still something like (the boring) "Ethernet #xx."

Old NIC names

Old NIC names

You still need to change the NICs' names yourself inside the VM; they did not change automatically when you renamed them in the Hyper-V host.

You could accomplish this manually, but you would have to dig through one NIC at a time in Hyper-V, disconnect it or disable it inside the VM, and see what breaks.

With PowerShell, you do it all in one step. All the NICs inside the VMs are changed to have the same names as defined in Hyper-V. It's quick and easy, without "shooting in the dark" and hoping you selected the right NIC.

To accomplish this, use the command Get-NetAdapterAdvancedProperty, which exposes a lot of advanced information about each NIC. To sift through all the relevant information, you only need to look at the property "Hyper-V Network Adapter Name", as in the example below:

Get-NetAdapterAdvancedProperty -DisplayName "Hyper-V Network Adapter Name" 
Get NetAdapterAdvancedProperty

Get NetAdapterAdvancedProperty

You already see where we are going. The last step is to rename each NIC with the value from "DisplayValue." (Note: If you do not see any value, it means the NIC has not been renamed after you turned on Device Naming.)

The command below will rename the NICs.

# Virtual NICs added without the switch "DeviceNaming" set to On have no value set in DisplayValue, and will be ignored
foreach ($N in (Get-NetAdapterAdvancedProperty -DisplayName "Hyper-V Network Adapter Name" | Where-Object DisplayValue -NotLike "")) {
  $N | Rename-NetAdapter -NewName $n.DisplayValue -Verbose
} 
Renaming NICs

Renaming NICs

And that's it. Next time you check your network settings, you can easily identify which NIC is which.

Renamed NICs

Renamed NICs

Conclusion

It is good hygiene to use relevant, consistent names for your NICs inside the VMs, just like those for inside your physical machines. This is particularly helpful in the case of VMs with multiple NICs.

You may modify your deployment scripts to automatically turn on Device Naming for new VMs, and you may also apply them to existing VMs.

10 Comments
  1. Gino 3 years ago

    Hi there,

    Great post !

    I didn't know about this Device Naming Feature … I did some kind of equivalent HV NIC / VM NIC matching by using Powershell Direct, but this gave me some new ideas, thanks !

    Unfortunately, I work on 2012R2 HV too, and no Device Naminf feature and no Powershell Direct … 🙁

    Do you know another way of doing this in 2012R2 HV ?

    Regards

    • Author

      Hi, Gino.

      According to this Microsoft article, the feature was introduced in WS2016. It's a feature for Gen2 Hyper-V VMs. I couldn't find any workaround for earlier versions (like WS2012R2).

      Regards. Emanuel

  2. Gino 3 years ago

    Hi Emmanuel and thank you for your reply.

    I'm an IT Trainer and wanted to write some Powershell scripts that deploy a VMs Infrastructure automatically depending on the training I have to deliver. This script is driven by 3 csv files (switches, vms, nics). 

    My true problem with 2012R2 was not naming but matching VM Network cards with right HV switches for 'routers like' VMs.

    When you start a VM with several nics for the 1st time, order is random, there is no logic … ?

    So the VM nics are mixed the wrong way relatively to switch creating order.

    I found a way to get my job done by modifying my script to :

    – create a 'Dummy' internal switch

    – connect one VM Network card at a time on the 'Dummy' switch allowing the HV Host to communicate with the VM with WinRM

    – Grab the VM internal nics names and MacAddress with winrm

    – Connect each VM Nic to the right switch

    But I'm still trying to know if there is another way to know which VM Nic is connected to which HV switch (winrm is slow …)…

    • Author

      Hi, Gino.

      One thing I could think of is to retrieve the MAC address from the host, and then use that information to identify the NIC.

      Get-VMNetworkAdapter -VMName VM1 | Select-Object SwitchName, MacAddress

      I haven't tested in WS2012 (I don't have hosts with WS2012), but if it works, I think that should help you.

      Regards. Emanuel

      • Gino ROVERSELLI 3 years ago

        Hi Emanuel

        Thank you and Yes I use this command to get SwitchName and MacAddress but it's not sufficient to be sure nics are connected to the right switch.

        the problem is with routers ; for example, with powershell, I create a 3 NIC router VM from my 2012R2 master vhdx. Before starting the VM. I inject a powershell script that creates, configure and rename the needed nics inside my VM according to switch names..

        From Hyper-V point of view, same thing, one HVNIC is connected to a Paris switch, another one to a London switch and the last one to a WAN switch. 

        When I start the VM, the nics inside the VM don't match, everything is random, there is no logic.

        The nics inside the VM are not detected and named in the same order as they are created or connected to a switch. I spent some hours trying to find some logic but there is not …

        Sometimes the first created VMNetadapter is named "…..Microsoft Hyper-V #3" or "…..Microsoft Hyper-V #2". Sometimes it is on the right switch but it's only luck. this is a non sense.

        So I Had another idea. I used a command like yours to get switch names and MacAddress and wanted to inject these parameters in the VM boot script.

        Unfortunately, you can't get any MACAddress from Hyper-V unless you already started the VM !

        That's why I use WinRM. It's impossible for me to get the right matchines Nics/Switch whithout communicating with the VMs from the HV host.

        Thanks for your help anyway

        • Author

          Hi, Gino.

          I had no idea the MACs are not "seen" until the VM is powered on.

          I guess a workaround would be to assign the MACs manually from a pool.

          You would need to figure a way to avoid duplicate MACs, but probably a shared CSV file would be enough. You may populate it when you're planning your infrastructure or as you add VMs in the environment).

          If I could pick, I'd just use more recent OS'es, but is it safe to guess the restriction is not technical? (I don't know if a happy or sad emoticon is more suitable here…)

          • Leos Marek (Rank 4) 3 years ago

            Its correct that MAC is assigned on first Power on.

            However, I dont really understand what Gino is trying to do. The thing you mention, that NICs are not detected by Windows in the same order as you see them in Hyper-V – that totally normal tho. There is no "order" property or something that would allow Windows to map the devices as you see them. If you want to do this, then you need to start the VM first and add the NIC adapters one by one. Then Windows should create the same way as you see it in the VM.

            If I deploy a VM with 3 NICs, I am assigning the switch in the VM properties. So you already know which NIC is connected to which switch. Then I can simply power on the VM, grab the MAC addresses, and push a script to the VM that does proper configuration.

            L

            • Author

              Leos, that sounds like a better idea. I was trying to stick to Gino's restrictions, but your workaround sounds easier than static MACs (which would accumulate to a messy problem in time).

    • Leos Marek (Rank 4) 3 years ago

      PS – You dont need a VM NIC to be connected to any switch to utilize Invoke-Command -VMname from Hyper-V host. This does not work over network from Hyper-V to the VM.

      So, you can simply create a VM with 3 NICs, leave them Not Connected, start your VM, grab your mac addresses, invoke your command to the VM and then connect the NICs to switches.

      Hope that helps.

Leave a reply to Emanuel Halapciuc (Rank 3) Click here to cancel the reply

Please enclose code in pre tags

Your email address will not be published. Required fields are marked *

*

© 4sysops 2006 - 2023

CONTACT US

Please ask IT administration questions in the forums. Any other messages are welcome.

Sending

Log in with your credentials

or    

Forgot your details?

Create Account