John Howard - Senior Program Manager in the Hyper-V team at Microsoft

Senior Program Manager, Hyper-V team, Windows Core Operating System Division.

Hyper-V: How to remove disabled virtual network adapters from the parent partition

Hyper-V: How to remove disabled virtual network adapters from the parent partition

  • Comments 9
  • Likes

In May, I mentioned that we introduced a checkbox in the Hyper-V UI for Windows 7 and Windows Server 2008 R2 which determines whether a virtual NIC is created in the parent partition for External Virtual Networks. (To get a better understanding of Hyper-V networking and what this means, take a look at this article.)

Many customers follow our best practice of having at least two physical NICs, one for use by the parent partition (aka Management Operating System), and one or more for use by virtual machines. But using the “v1” UI, there’s no option to not have the parent virtual NIC created. Two common ways to resolve this are to disable the virtual NIC it in “Network Connections” on the control panel, or unbinding all protocols from the virtual NIC. The disabling option tends (in my experience) to be the more common choice of the two.

There are, of course, several scripts out there to create what I termed a “dedicated” network (ie one which is dedicated for use only by virtual machines) last year. Ben has a couple of samples here in both VBScript and PowerShell, and Robert has a sample here. These are better approaches to disabling NICs or removing protocol bindings.

To date, I haven’t come across a script which removes disabled virtual NICs in the parent partition. So here is one such example. This will hopefully assist you in being more “compliant” with our best practice recommendations in an existing Hyper-V deployment.

Obviously with any script which does destructive things, I urge caution and that you make careful note of your configuration before running it, and remember the standard disclaimer on my blog.

//
// VirtualSwitchManagementService object.  Logical wrapper class for Switch Management Service
//
function
VirtualSwitchManagementService(
    Server,
    User,
    Password
    )
{
    //
    // Define instance fields.
    //    
    this.m_VirtualizationNamespace  = null;
    
    this.m_VirtualSwitchManagementService = null;
        
 
    //
    // Instance methods
    //        
    VirtualSwitchManagementService.prototype.DeleteInternalEthernetPort = 
    function(
        InternalEthernetPort
        )
 
    /*++
    Description:
        Deletes an internal ethernet port
        
    Arguments:
        InternalEthernetPort - Msvm_InternalEthernetPort to delete
        
    Return Value:
        SWbemMethod.OutParameters object.
    --*/
 
    {
        var methodName = "DeleteInternalEthernetPort";
 
        var inParams = this.m_VirtualSwitchManagementService.Methods_(methodName).inParameters.SpawnInstance_();
        
        inParams.InternalEthernetPort = InternalEthernetPort.Path_.Path;
        
        return this.m_VirtualSwitchManagementService.ExecMethod_(methodName, inParams);
    }
 
    //
    // Utility functions
    //
    
    VirtualSwitchManagementService.prototype.WaitForNetworkJob = 
    function(
        OutParams
        )
 
    /*++
    Description:
        WMI calls will exit with some type of return result.  Some will require 
        a little more processing before they are complete. This handles those 
        states after a wmi call.
    Arguments:
        OutParams - the parameters returned by the wmi call.
    Return Value:
        Status code
    --*/
 
    {
        if (OutParams.ReturnValue == 4096)
        {
            var jobStateStarting        = 3;
            var jobStateRunning         = 4;
            var jobStateCompleted       = 7;
    
            var networkJob;
 
            do
            {
                WScript.Sleep(1000);
                
                networkJob = this.m_VirtualizationNamespace.Get(OutParams.Job);
 
            } while ((networkJob.JobState == jobStateStarting) || 
                     (networkJob.JobState == jobStateRunning));
 
            if (networkJob.JobState != jobStateCompleted)
            {
                throw(new Error(networkJob.ErrorCode,
                                networkJob.Description + " failed: " + networkJob.ErrorDescription));
            }
            
            return networkJob.ErrorCode;
        }
 
        return OutParams.ReturnValue;
    }
    
    
    //
    // Aggregate functions
    //
    VirtualSwitchManagementService.prototype.DeleteInternalEthernetPortAndWait = 
    function(
        InternalEthernetPort
        )
    /*++
    Description:
        Deletes an internal ethernet port
        
    Arguments:
        InternalEthernetPort - Msvm_InternalEthernetPort to delete
        
    Return Value:
        SWbemMethod.OutParameters object.
    --*/
    
    {
        var outParams = this.DeleteInternalEthernetPort(InternalEthernetPort);
 
        var wmiRetValue = this.WaitForNetworkJob(outParams);
 
        if (wmiRetValue != 0)
        {
            throw(new Error(wmiRetValue, "DeleteInternalEthernetPortAndWait failed"));
        }
    }
 
    //
    // Constructor code
    //
    
    if (Server == null)
    {
        Server = WScript.CreateObject("WScript.Network").ComputerName; 
    }
    
    //
    // Set Namespace fields
    //
    var locator = new ActiveXObject("WbemScripting.SWbemLocator");
 
    this.m_VirtualizationNamespace = locator.ConnectServer(Server, "root\\virtualization", User, Password);
    
    //
    // Set Msvm_VirtualSwitchManagementService field
    //
    var physicalComputerSystem = 
            this.m_VirtualizationNamespace.Get(
                    "Msvm_ComputerSystem.CreationClassName='Msvm_ComputerSystem',Name='" + Server + "'");
 
    var list = physicalComputerSystem.Associators_(
                        "Msvm_HostedService",
                        "Msvm_VirtualSwitchManagementService",
                        "Dependent");        
 
    this.m_VirtualSwitchManagementService = list.ItemIndex(0)
}
 
 
//
// main
// 
 
var wshShell = WScript.CreateObject("WScript.Shell");
 
var g_NvspWmi   = null;
var g_CimV2     = null;
 
Main();
 
function Main()
{
    g_NvspWmi   = new VirtualSwitchManagementService();
 
    WScript.Echo("Looking for root\\cimv2...");
    var locator = new ActiveXObject("WbemScripting.SWbemLocator");
    g_CimV2 = locator.ConnectServer("", "root\\cimv2", "", "");
        
    WScript.Echo("");
    WScript.Echo("Looking for internal (parent) virtual nics...");
    var list = g_NvspWmi.m_VirtualizationNamespace.ExecQuery("SELECT * FROM Msvm_InternalEthernetPort");
    for (i = 0; i < list.Count; i++)
    {
        var next = list.ItemIndex(i);
 
        // find correpsonding Win32_NetworkAdapter
        var adapters = g_CimV2.ExecQuery("SELECT * FROM Win32_NetworkAdapter WHERE GUID='" + next.DeviceID + "'");
        for (j = 0; j < adapters.Count; j++)
        {
            var adapter = adapters.ItemIndex(j);
            if (adapter.NetEnabled == false)
            {
                WScript.echo("Deleting '" + next.ElementName + "' because it is disabled.");
                g_NvspWmi.DeleteInternalEthernetPortAndWait(next);
            }
            else
            {
                WScript.echo("Not deleting '" + next.ElementName + "' because it is enabled.");
            }
        }
    }
 
    WScript.Echo("");
    WScript.Echo("Finished!");
}


The script should be saved with a .js extension to run it from the command line. Or you can get it as a text file from here.

One thing I would note is that after running the script, you’ll notice in the “v1” UI when you select an External Virtual Network, the message “This virtual network switch cannot be configured. You might not have permission to perform this task, or it might have been reconfigured in the parent partition” is displayed. This limits your ability to change the network type to an Internal or Private network. However, you can still remove the network if necessary.

Virtual Network Manager


Another point to note is that if you are running Hyper-V v1 RTM on Windows Server 2008 SP1, have disabled virtual NICs in the parent partition, then apply Service Pack 2, disabled NICs are re-enabled after applying the service pack. Hence, I would recommend you remove disabled virtual NICs from the parent partition if you have no need for them prior to applying SP2.

And for completeness, if you ever need to completely remove all virtual networks from your system (it crops up as a question every now and then), there’s a useful script you can find here. Obviously though, I recommend extreme caution before running that script.

Cheers,
John.

And again, thanks to Keith for his assistance :)

Comments
  • John -

    While Hyper-V Server R2 seems to fill a void, it is also lacking some serious management tools.  For example, no device management such as Device Manager - no way to really install device drivers for devices that work with Server 2008 and not Hyper-V Server 2008 R2?

    Information is spread all over the net like road kill and very little of it is helpful..

    You've taken a good shot at things..but where are the tools from MS to manage this nifty system?

    Ron Mitchell

  • Ron - R2 introduces a new script, sconfig which goes much of the way to filling the void. Co-incidentally, Jeff posted up an article on our team blog just today on it: http://blogs.technet.com/virtualization/archive/2009/07/07/windows-server-2008-r2-core-introducing-sconfig.aspx

    Also, this article is the best resource on how to otherwise generally remotely manage a server core box (including Hyper-V Server 2008 R2). http://technet.microsoft.com/en-us/library/cc753802(WS.10).aspx#bkmk_deployingservercore The devices bit is quite a long way down.

    Thanks,

    John.

  • It worked great! I had a disabled virtual network adapter for another reason: I was fiddling with the virtual network stuff, because my VM's would get access to the internet like all other pc's. I tried bridging, one NIC, two NICs, etc.

    It turned out that the simplest of all setups works. One NIC, one virtual network and no bridge of any kind. So the "best practise" seems bogus to me, because it doesn't allow my VM's to get anywhere on the network. Besides, it would occupy an extra port on the switch, which is nonsense.

    Anyway, after fiddling, I ended up with a virtual network that doesn't show in the Hyper-V manager, but it *does* show in the network connections in the control panel. Disabled or enabled doesn't make any difference; Hyper-V thinks it doesn't exist. So, I disabled it. Because logically, I cannot delete it from the network connections, not from the device manager.

    But this script deleted that useless good for nothing device, so now I have one working virtual network again.

    Thanks!

  • What about NIC teaming in Server Core with Hyper V?  I'm finding what Ron mentions above aobut documentation hard to find, scattered, and incomplete.  

    Thanks,

    Greg

  • Greg - a paper is in the process of being published, but for now, you need to refer to documentation supplied by the OEMs themselves.

    Thanks,

    John.

  • Finally I am rid of that Virtual Switch and can reset my network config! THANK YOU!

  • Hi John

    I have an issue that no one at Microsoft CTS has ever seen and is having a very difficult time with.

    I have a mutlti-site failover cluster running hyper-v on each node (2 nodes). Each node has 2 x quad NIC cards. Five of the NICs are used for physical connections to networks. One NIC is bound with MS virtual switch protocol and is used by three VMs at this point. So, in the Failover Cluster Manager console in the Networks section I see five different networks but I don't see the one NIC bound with MSVSP, which is the  way it’s supposed to be, correct?

    Here's the issue:

    I went to create a second virtual switch using one of the two remaining unused NICS in the node and all of a sudden a sixth entry showed up under Networks in the Failover Cluster Manager console. It is automatically called Cluster Network 1. Even after I deleted it from the virtual networks within the node it still remains an no one at MS support knows how to remove it or even why this has happened.

    Can you shed any light on this? It doesn't seem to be causing any harm but it is annoying and I would like to get rid of it. I assume a registry hack will do it but even support wasn't sure. I'd send a screen shot but I can't paste into this

    Thank you

    James

  • Hi John

    This script was very useful.. Tried for 3 days manually. But this script done within a second..

    Thanks

  • Excellent! There were a couple of virtual network switches and connections installed which was annoying.

    This script helped a lott! Thanks!

Your comment has been posted.   Close
Thank you, your comment requires moderation so it may take a while to appear.   Close
Leave a Comment