Hyper-V 2019: The v-switchening

This is a follow up post to my several prior posts about both Hyper-V 2019 as an OS, using the Hyper-V hypervisor for virtualization and my server hardware of choice, the Dell R520. I have a summary and conclusions clarifying the things I learned as I wrote this post at the bottom. Any corrections/comments etc are welcome.

This post is a continuation of my previous post about setting up my Hyper-V 2019 installation storage pool. See the prior post for some explanations of some of the concepts mentioned here. See the bottom of this post for further references.

I have my storage server setup with its 5x 10TB disks 8x 10TB disks installed in the pool. Now I can finally start trying to setup actual virtual machines.

My main experience with virtualization has come through the more consumer-level virtualization options like VirtualBox (although I did once set up a headless VirtualBox host with a minimal Linux).

VirtualBox could be tricky to setup at times, but there was never anything like completely taking over a physical NIC to the point of having to reinstall the OS. Which is what happened to me the first time I tried to setup a VM with Hyper-V server.

Apparently you must setup a “virtual switch” for all the virtual machines to “connect” to. This is some kind of abstraction that sits on top of a physical NIC.

So I don’t know if two physical NICs is actually required for this OS or not. Seems like that’s a thing the OS installer would note in some way. By the way the hardware you have is missing a component to do the thing this is exists for. You know. Minor detail.

It sort of makes sense logically: the OS is made to run 2 or more virtual machines at once that will be running 24/7 and using different amounts of bandwidth. Connect these VMs to a “switch” to try and separate out the traffic.

But this concept extends into a “network switch” physical NIC and a “host” dedicated physical NIC (which could be thought of as a “management” port).

There’s probably scenarios where one NIC could be be used. But I want to run multiple virtual machines at once anyway. So as long as I’m doing that I may as well create the virtual switch with PowerShell. And probably at least the first virtual machine as well.

Since I have been only some-what confident of knowing what kind of virtual switch I want to use I have been trying to do further research.

I was pretty sure I wanted an external virtual switch as this similar in concept to what VirtualBox has. But I wanted to make sure.

I found an article about Hyper-V virtual switches on this site that seemed pretty good. Here is an excerpt from their explanation of an “external virutal switch”:

A Hyper-V virtual switch in external mode allows communications between virtual adapters connected to virtual machines and the management operating system. It uses single or teamed physical adapters to connect to a physical switch, thereby allowing communications with other systems.

I think I can re-word and/or paraphrase this paragraph: the virtual machine virtual NIC will have its own network IP address, indistinguishable from a physical NIC on a physical motherboard as far as the router can tell. This will then be connected to the virtual switch.

This makes sense to me and this is the way I want it set up. It appears as though a virtual NIC can be created for the purposes of managing the host OS and connected to the virtual switch along side the virtual NICs for the VMs connected to the same virtual switch. An extra dimension of complexity and power from VirtualBox but I think I like it.

I’m so impressed with the information in the article I found above I’m going to borrow the image they created and use it here (full credit to this article on altaro.com).

Virtual NICs connected to a virtual switch in Hyper-V. Full credit to altaro.com
Virtual NICs connected to a virtual switch in Hyper-V. Full credit to altaro.com

My Dell R520 server conveniently has 2 on board NICs, albeit both 100 Mbps (for link speed). I decided to use NIC #2 as the “management” NIC and 1 as the one the VMs can all share.

I’ve learned from the above mentioned article that the -AllowManagementOS flag apparently has to be set to false for good reasons. I’m still thinking about the explanation so I may or may not understand why. But this is what the article says.

Update later: I think I understand now but will have to come back to it. Not really necessary to understand at the moment since I have two physical NICs.

Some how I was lead to believe the New-VMSwitch cmdlet could specify the type as external since types internal and private can both be specified. But this is not the case. It would appear external switches have to be setup kind of…indirectly…I guess?

The first thing I have to do is see what PS returns as identification for the two NICs, which is easy enough:

Get-NetAdapter | select Name, InterfaceDescription

Which conveniently gives me a formatted table:

Name InterfaceDescription
---- --------------------
NIC1 Broadcom NetXtreme Gigabit Ethernet
NIC2 Broadcom NetXtreme Gigabit Ethernet #2

Now I know I want the VMs to use NIC1 and host OS management to be NIC 2.

I’m still a little hazy on how if at all necessary the MinimumBandwidthMode setting is, but since it’s mentioned in both the article I’m referencing and the Microsoft documentation I’m going to include it with the recommended setting.

I ran the below with the -whatif option to see the results (I think I’m going to use that “whatif” a lot more).

New-VMSwitch -Name ExternalSwitch1 -AllowManagementOS $false -NetAdapterName NIC1 -MinimumBandwidthMode Weight

This appears to have worked although it seems like it took quite a while. Or my creating a virtual switch disconnected me from the management method I was using (WAC) so it only seemed like it was still loading.

I decided to part with my PowerShell vibe a minute and use VM Manager: I associated the virtual switch with a VM I had already created and installed the OS (Windows Server 2019 180 day trial). I figured this would be the best way to see if the OS was really on the network.

Well it took much longer than I expected. I might have some poor VM performance or it could be that’s just how long server 2019 takes. I’ll worry about that later. When the OS was finally installed I saw that it did have its own NIC and that it was on the network and internet. I’m not sure yet what if anything I’ll do with this Server 2019 installation. I gave it 12 gigs (12,000 MBs technically) of RAM, you’d think that’d be enough (and also 2 of the Xeon’s 4 cores).

In PowerShell when I tried to view the available virtual NICs the result came back with the same name as the virtual switch. Which was confusing at first as I thought there would be differentiation between a virtual switch and and virtual NIC.


I decided to delete what virtual machines I had on the server and start over. In the time since I started this post I have started working on Windows installations with an “answer file” so I don’t have to click OK or listen to Cortana during installation (skipping past that is so nice!).

First I wanted to confirm my virtual switch. Which is pretty convenient because it just consists of type Get-VMSwitch. In this case that command came back with

Name            SwitchType NetAdapterInterfaceDescription
----            ---------- ------------------------------
ExternalSwitch1 External   Broadcom NetXtreme Gigabit Ethernet

Well not exactly pretty but it gives me the information I need.

And now I would like to rename the virtual switch to something a little friendlier. I will do this with the cmdlet Rename-VMSwitch:

Rename-VMSwitch "ExternalSwitch1" -NewName "VSwitchExt"

Re-assessing what I have already setup and looking at Hyper-V manager for a more visual confirmation I think I’m starting to realize: per above I assigned this virtual switch to (physical) NIC 1 and right now when I run a ipconfig the only NIC even acknowledged as existing is (physical) NIC2 with an IP of 192.168.1.137. Which is what I’m using to connect to the host (management) OS.

So I think what I have to do is create a virtual NIC and connect it to the virtual switch which is connected to the virtual switch. Per that diagram above. (note: I found out below I don’t have to go out of my way to create a virtual NIC as it is automatically created when a VM is created).

Operating on the possibility this is accurate I confirmed there are currently no virtual NICs with:

Get-VMNetworkAdapter -All

And indeed nothing is listed.

I found the cmdlet Add-VMNetworkAdapter so I think I’m getting close. The list examples and references all seem to revolve around adding a virtual NIC to a virtual machine. It does seem to have a an easy parameter for connecting that virtual NIC to a specific virtual switch however. So it could be this is all I need.

I also found the cmdlet Connect-VMNetworkAdapter which seems to have the sole purpose of connect virtual network adapters to virtual switches. Not sure if that redundancy is on purpose or it just came up as new versions of PS were developed. Or I’m missing something.

Example 3 of the page explaining Connect-VMNetworkAdapter doesn’t even specify the name of the virtual NIC, it just says connect it:

PS C:\> Get-VMSwitch InternetAccess | Connect-VMNetworkAdapter -VMName Test1

I find this confusing because I thought creating the virtual NIC would be expected to be a separate operation for reason. But from the above example I think just creating a virutal machine brings a NIC along with it automatically. Or I’m reading too much into it. Either way I think I’m ready to use PS to create a new VM.

I went out on a limb and assumed cmdlet New-VM is probably the one to create VMs. Now it’s just a matter of deciding which options I wanted to create it with

I think I’m going to create one without creating a VHD first, then attach that VHD to the VM later. No reason, just trying to keep it simple. I think I could actually create a VHD on the fly with simple flag too. Same with the ISO. I think I have at least one working Win ISO.

First I’ll start with a simple line to create the VM with a modest 8GB of RAM. I’m hoping if nothing else it will make the installation go that much faster. I am almost positive specifying a host like this will make VM-related files be stored in the right place rather than my relatively small capacity SSD C: drive.

New-VM -Name "Win10-1903VM" -MemoryStartupBytes 8GB -NoVHD -Path s:\Hyper-V

This actually went remarkably smoothly and quickly. Which I should not be surprised about really.

As I think I was expecting, when I now run Get-VMNetworkAdapter -All it does show a virtual NIC attached to the virtual machine. And actually under “switch name” it looks like it’s blank. Actually I think my copy/paste of the output isn’t going to format so good but take my word for it.

Name            IsManagementOs VMName       SwitchName MacAddress   Status IPAddresses
----            -------------- ------       ---------- ----------   ------ -----------
Network Adapter False          Win10-1903VM            000000000000        {}

This is what I was expecting, really: having to attach the virtual NIC to the virtual switch separately.

I found this Connect-VMNetworkAdapter cmdlet that looks like it will do just the trick.

But first I am going to need to rename that virtual NIC to something more descriptive than “Network Adapter”.

The cmdlet Set-VMNetworkAdapter has a -name parameter that actually says it will change the name. But I couldn’t find an example of how to do it. So I searched and found Rename-VMNetworkAdapter. An entire separate cmdlet just to rename an adapter. Alright then.

So I’ll give it a more obvious name:

Rename-VMNetworkAdapter -VMName Win10-1903VM -NewName Win10VMNIC

With that out the way, it’s time to finally connect the virtual NIC to the virtual switch.

Connect-VMNetworkAdapter -VMName Win10-1903VM -Name Win10VMNIC -SwitchName VSwitchExt

As I had hoped, where the “switch name” column was blank before it now has the name of the switch for my output of Get-VMNetworkAdapter -All.

It doesn’t have an IP, I assume because the OS isn’t installed to request one. And actually the MAC is assigned all 0’s (zeros) as well. Not sure if that will come up or not.

Next I will create a VHD file. Not sure if I should make it a VHD or VHDX. I guess for now I’ll go with X. Not planning on keeping this VM anyway. Also, if nothing is specified the VHD is assumed to be dynamic e.g. starts off minimal size and only grows to the size of the data stored on it. So this will not be a 250 gig binary blob in other words.

I also have to specify a specific location to store the VHDs, on my S: drive.

New-VHD -Path S:\Hyper-V\VHDs\win7vm.vhdx -SizeBytes 250GB

Now I just have to attach this VHDX to the VM.

After a bit searching I found cmdlet Add-VMHardDiskDrive which seemed like the right cmdlet for the job.

Get-VM Win10-1903VM | Add-VMHardDiskDrive -Path S:\Hyper-V\VHDs\win7vm.vhdx -ControllerType IDE -ControllerNumber 0

Now there’s just the matter of the ISO inserted into the virtual DVD drive and I think I’m ready to boot up the VM.

I think Set-VMDvdDrive will do the trick. I’ve stored the ISO on my SSD for faster (hopefully) load speeds.

Set-VMDvdDrive -VMName Win10-1903VM -Path C:\install\Win764.ISO

Now all I have to do is power it on. And wait for it to install which could take a while.

Once again what seems like an intuitive cmdlet is used, Start-VM.

Start-VM -Name Win10-1903VM

I’m not sure how long it took for win 7 to install itself but once it was installed I did a few tests. Short story shorter the VM has an external IP – outside of the host as opposed to a NAT that is – outside devices can ping the VM and the VM can ping outside devices. In other words this exactly what I was trying to accomplish.

Finally, I’ll go ahead and stop the VM:

Stop-VM -Name Win10-1903VM

This performed a safe “ACPI” shutdown on the OS.

Summary of commands:

These will likely just have to run once:

  • rename the virtual switch:
    Rename-VMSwitch “ExternalSwitch1” -NewName “VSwitchExt”
  • rename the virtual NIC of a specific VM:
    Rename-VMNetworkAdapter -VMName Win10-1903VM -NewName Win10VMNIC
  • Create a new virtual switch and associate it with a physical NIC:
    New-VMSwitch -Name ExternalSwitch1 -AllowManagementOS $false -NetAdapterName NIC1 -MinimumBandwidthMode Weight
  • Connect a VM’s virtual NIC to a virtual switch:
    Connect-VMNetworkAdapter -VMName Win10-1903VM -Name Win10VMNIC -SwitchName VSwitchExt

Summary and conclusion:

The catalyst for doing this post was the confusion about creating virtual machines with Hyper-V manager and being confused about why said virtual machine did not get its own IP versus being behind the host’s IP.

Thanks to the diagram I found and some experimenting I’ve learned that when 2 or more network interfaces are available on the host one can be assigned entirely to the VMs while the other is solely dedicated to the host or “management” OS. This is mainly used for network traffic isolation and the inherent security that come with that.

The virtual switch is created and associated with one of the network interfaces then the virtual network cards of the VMs are “connected” to the virtual switch which is associated with the specific network interface.

It is possible to use a single network interface for both the VMs and the management/host OS necessary. That is probably what I’ll do for my duplicate/back up VM host since it only has one on board NIC.

I’m actually still sure how to accomplish most of these only using Hyper-V manager but now that I understand what’s happening a little better conceptually it shouldn’t be that necessary.

Setup for fresh server setup:

  • create a virtual switch, set to “external” for network/internet access
    • give vswitch with descriptive name
    • associate vswitch with a physical NIC
      • NIC associating will vary depending on number of physical interfaces available
      • if only one NIC may as well set AllowManagementOS to $true
  • create virtual machine
    • this will come with virtual NIC by default
    • may want to rename that virtual NIC to something more descriptive
  • Use “connect” command to “connect” virtual NIC to virtual switch


References and Resources

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Google photo

You are commenting using your Google account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s