DeleteSwitch(
            string switchName)
        {
            ManagementScope scope = new ManagementScope(@"root\virtualization\v2");

            //
            // Find the switch that we want to delete.
            //
            using (ManagementObject ethernetSwitch = NetworkingUtilities.FindEthernetSwitch(switchName, scope))

                //
                // Now that we have the switch object we can delete it.
                //
                using (ManagementObject switchService = NetworkingUtilities.GetEthernetSwitchManagementService(scope))
                    using (ManagementBaseObject inParams = switchService.GetMethodParameters("DestroySystem"))
                    {
                        inParams["AffectedSystem"] = ethernetSwitch.Path.Path;

                        using (ManagementBaseObject outParams = switchService.InvokeMethod("DestroySystem", inParams, null))
                        {
                            WmiUtilities.ValidateOutput(outParams, scope);
                        }
                    }

            Console.WriteLine(string.Format(CultureInfo.CurrentCulture,
                                            "The switch '{0}' was deleted successfully.", switchName));
        }
        ConnectVmToSwitch(
            string virtualMachineName,
            string switchName)
        {
            ManagementScope scope = new ManagementScope(@"root\virtualization\v2");

            using (ManagementObject managementService = WmiUtilities.GetVirtualMachineManagementService(scope))

                //
                // Find the Ethernet switch we want to connect to.
                //
                using (ManagementObject ethernetSwitch = NetworkingUtilities.FindEthernetSwitch(switchName, scope))

                    //
                    // Find the virtual machine we want to connect.
                    //
                    using (ManagementObject virtualMachine = WmiUtilities.GetVirtualMachine(virtualMachineName, scope))

                        //
                        // Get the virtual machine's settings object which is used to make configuration changes.
                        //
                        using (ManagementObject virtualMachineSettings = WmiUtilities.GetVirtualMachineSettings(virtualMachine))

                            //
                            // Add a new synthetic Network Adapter device to the virtual machine.
                            //
                            using (ManagementObject syntheticAdapter = NetworkingUtilities.AddSyntheticAdapter(virtualMachine, scope))

                                //
                                // Now that we have added a network adapter to the virtual machine we can configure its
                                // connection settings.
                                //
                                using (ManagementObject connectionSettingsToAdd =
                                           NetworkingUtilities.GetDefaultEthernetPortAllocationSettingData(scope))
                                {
                                    connectionSettingsToAdd["Parent"]       = syntheticAdapter.Path.Path;
                                    connectionSettingsToAdd["HostResource"] = new string[] { ethernetSwitch.Path.Path };

                                    //
                                    // Now add the connection settings.
                                    //
                                    using (ManagementBaseObject addConnectionInParams =
                                               managementService.GetMethodParameters("AddResourceSettings"))
                                    {
                                        addConnectionInParams["AffectedConfiguration"] = virtualMachineSettings.Path.Path;
                                        addConnectionInParams["ResourceSettings"]      =
                                            new string[] { connectionSettingsToAdd.GetText(TextFormat.WmiDtd20) };

                                        using (ManagementBaseObject addConnectionOutParams =
                                                   managementService.InvokeMethod("AddResourceSettings", addConnectionInParams, null))
                                        {
                                            WmiUtilities.ValidateOutput(addConnectionOutParams, scope);
                                        }
                                    }
                                }

            Console.WriteLine(string.Format(CultureInfo.CurrentCulture,
                                            "Successfully connected virtual machine '{0}' to switch '{1}'.",
                                            virtualMachineName, switchName));
        }
        CreateExternalSwitch(
            string externalAdapterName,
            string switchName,
            string switchNotes)
        {
            ManagementScope scope = new ManagementScope(@"root\virtualization\v2");

            string[] ports;

            //
            // Get the external adapter we are connecting to.
            //
            using (ManagementObject externalAdapter =
                       NetworkingUtilities.FindExternalAdapter(externalAdapterName, scope))

                //
                // Get the hosting computer system. The internal port we create needs to be configured
                // to connect to the hosting computer system.
                //
                using (ManagementObject hostComputerSystem = WmiUtilities.GetHostComputerSystem(scope))

                    //
                    // Get the default Msvm_EthernetPortAllocationSettingData instance that we can use to
                    // configure our external port connection for the switch.
                    // Use the same switch name, appended with "_External", for the port name.
                    // You can use any port name that you like.
                    //
                    using (ManagementObject externalPortToCreate =
                               NetworkingUtilities.GetDefaultEthernetPortAllocationSettingData(scope))
                    {
                        externalPortToCreate["ElementName"]  = switchName + "_External";
                        externalPortToCreate["HostResource"] = new string[] { externalAdapter.Path.Path };

                        //
                        // Clone the externalPort connection and configure it for the internal port.
                        // Use the same switch name, appended with "_Internal", for the port name.
                        // You can use any port name that you like.
                        //
                        using (ManagementObject internalPortToCreate =
                                   (ManagementObject)externalPortToCreate.Clone())
                        {
                            internalPortToCreate["ElementName"]  = switchName + "_Internal";
                            internalPortToCreate["HostResource"] = new string[] { hostComputerSystem.Path.Path };

                            //
                            // Now create the switch with the two ports.
                            //
                            ports = new string[] {
                                externalPortToCreate.GetText(TextFormat.WmiDtd20),
                                internalPortToCreate.GetText(TextFormat.WmiDtd20)
                            };
                        }
                    }

            CreateSwitch(switchName, switchNotes, ports, scope);

            Console.WriteLine(string.Format(CultureInfo.CurrentCulture,
                                            "The external switch '{0}' was created successfully.", switchName));
        }
        ModifySwitchName(
            string existingSwitchName,
            string newSwitchName,
            string newNotes)
        {
            ManagementScope scope = new ManagementScope(@"root\virtualization\v2");

            //
            // Get the switch we want to modify.
            //
            using (ManagementObject ethernetSwitch = NetworkingUtilities.FindEthernetSwitch(existingSwitchName, scope))

                //
                // To make modifications to the switch, we need to modify its configuration object.
                //
                using (ManagementObject ethernetSwitchSettings = WmiUtilities.GetFirstObjectFromCollection(
                           ethernetSwitch.GetRelated("Msvm_VirtualEthernetSwitchSettingData",
                                                     "Msvm_SettingsDefineState",
                                                     null, null, null, null, false, null)))
                {
                    //
                    // Modify its properties as desired.
                    //
                    ethernetSwitchSettings["ElementName"] = newSwitchName;
                    ethernetSwitchSettings["Notes"]       = new string[] { newNotes };

                    //
                    // This is how you can modify the IOV Preferred property from its current value.
                    // We leave this commented out because it could potentially fail for a system that doesn't
                    // support IOV.
                    //
                    // ethernetSwitchSettings["IOVPreferred"] = !((bool)ethernetSwitchSettings["IOVPreferred"]);

                    //
                    // Now call the ModifySystemSettings method to apply the changes.
                    //
                    using (ManagementObject switchService = NetworkingUtilities.GetEthernetSwitchManagementService(scope))
                        using (ManagementBaseObject inParams = switchService.GetMethodParameters("ModifySystemSettings"))
                        {
                            inParams["SystemSettings"] = ethernetSwitchSettings.GetText(TextFormat.WmiDtd20);

                            using (ManagementBaseObject outParams =
                                       switchService.InvokeMethod("ModifySystemSettings", inParams, null))
                            {
                                WmiUtilities.ValidateOutput(outParams, scope);
                            }
                        }
                }

            Console.WriteLine(string.Format(CultureInfo.CurrentCulture,
                                            "The switch '{0}' was renamed to '{1}' successfully.",
                                            existingSwitchName, newSwitchName));
        }
        ModifyFeatureSettings(
            string switchName)
        {
            ManagementScope scope = new ManagementScope(@"root\virtualization\v2");

            using (ManagementObject managementService = NetworkingUtilities.GetEthernetSwitchManagementService(scope))

                //
                // Find the specified switch.
                //
                using (ManagementObject ethernetSwitch = NetworkingUtilities.FindEthernetSwitch(switchName, scope))
                    using (ManagementObject ethernetSwitchSetting = WmiUtilities.GetFirstObjectFromCollection(
                               ethernetSwitch.GetRelated("Msvm_VirtualEthernetSwitchSettingData",
                                                         "Msvm_SettingsDefineState",
                                                         null, null, null, null, false, null)))

                        //
                        // Find the existing bandwidth setting and modify it.
                        //
                        using (ManagementObject bandwidthSetting = WmiUtilities.GetFirstObjectFromCollection(
                                   ethernetSwitchSetting.GetRelated("Msvm_VirtualEthernetSwitchBandwidthSettingData",
                                                                    "Msvm_VirtualEthernetSwitchSettingDataComponent",
                                                                    null, null, null, null, false, null)))
                        {
                            //
                            // Increase the current reservation by 1 Mbps.
                            //
                            bandwidthSetting["DefaultFlowReservation"] =
                                (UInt64)bandwidthSetting["DefaultFlowReservation"] + 125000; // in bytes/sec

                            using (ManagementBaseObject inParams =
                                       managementService.GetMethodParameters("ModifyFeatureSettings"))
                            {
                                inParams["FeatureSettings"] = new string[] { bandwidthSetting.GetText(TextFormat.WmiDtd20) };

                                using (ManagementBaseObject outParams =
                                           managementService.InvokeMethod("ModifyFeatureSettings", inParams, null))
                                {
                                    WmiUtilities.ValidateOutput(outParams, scope);
                                }
                            }
                        }

            Console.WriteLine(string.Format(CultureInfo.CurrentCulture,
                                            "Successfully modified bandwidth feature setting on virtual switch '{0}'.",
                                            switchName));
        }
        AddFeatureSettings(
            string switchName)
        {
            ManagementScope scope = new ManagementScope(@"root\virtualization\v2");

            string featureId = NetworkingUtilities.GetSwitchFeatureId(NetworkingUtilities.SwitchFeatureType.Bandwidth);

            using (ManagementObject managementService = NetworkingUtilities.GetEthernetSwitchManagementService(scope))

                //
                // Find the specified switch.
                //
                using (ManagementObject ethernetSwitch = NetworkingUtilities.FindEthernetSwitch(switchName, scope))
                    using (ManagementObject ethernetSwitchSetting = WmiUtilities.GetFirstObjectFromCollection(
                               ethernetSwitch.GetRelated("Msvm_VirtualEthernetSwitchSettingData",
                                                         "Msvm_SettingsDefineState",
                                                         null, null, null, null, false, null)))

                        //
                        // Add a new bandwidth setting instance.
                        //
                        using (ManagementObject bandwidthSetting =
                                   NetworkingUtilities.GetDefaultFeatureSetting(featureId, scope))
                        {
                            //
                            // Set the default bandwidth reservation to 10 Mbps.
                            //
                            bandwidthSetting["DefaultFlowReservation"] = 12500000; // in bytes/sec

                            using (ManagementBaseObject inParams =
                                       managementService.GetMethodParameters("AddFeatureSettings"))
                            {
                                inParams["AffectedConfiguration"] = ethernetSwitchSetting.Path.Path;
                                inParams["FeatureSettings"]       = new string[] { bandwidthSetting.GetText(TextFormat.WmiDtd20) };

                                using (ManagementBaseObject outParams =
                                           managementService.InvokeMethod("AddFeatureSettings", inParams, null))
                                {
                                    WmiUtilities.ValidateOutput(outParams, scope);
                                }
                            }
                        }

            Console.WriteLine(string.Format(CultureInfo.CurrentCulture,
                                            "Successfully added bandwidth feature setting to virtual switch '{0}'.",
                                            switchName));
        }
        CreateSwitch(
            string switchName,
            string switchNotes,
            string[] ports,
            ManagementScope scope)
        {
            string switchSettingText;

            //
            // Create the configuration object we pass into the CreateSwitch method in order to
            // specify details about the switch to create, such as its name and any notes.
            //
            using (ManagementClass switchSettingClass =
                       new ManagementClass("Msvm_VirtualEthernetSwitchSettingData"))
            {
                switchSettingClass.Scope = scope;
                using (ManagementObject switchSetting = switchSettingClass.CreateInstance())
                {
                    switchSetting["ElementName"] = switchName;
                    switchSetting["Notes"]       = new string[] { switchNotes };

                    //
                    // You can also configure other aspects of the switch before you create it,
                    // such as its IOVPreferred property.
                    //
                    // switchSetting["IOVPreferred"] = true;

                    switchSettingText = switchSetting.GetText(TextFormat.WmiDtd20);
                }
            }

            //
            // Now create the switch with the specified ports.
            //
            using (ManagementObject switchService = NetworkingUtilities.GetEthernetSwitchManagementService(scope))
                using (ManagementBaseObject inParams = switchService.GetMethodParameters("DefineSystem"))
                {
                    inParams["SystemSettings"]   = switchSettingText;
                    inParams["ResourceSettings"] = ports;

                    using (ManagementBaseObject outParams =
                               switchService.InvokeMethod("DefineSystem", inParams, null))
                    {
                        WmiUtilities.ValidateOutput(outParams, scope);
                    }
                }
        }
        RemoveFeatureSettings(
            string switchName)
        {
            ManagementScope scope = new ManagementScope(@"root\virtualization\v2");

            using (ManagementObject managementService = NetworkingUtilities.GetEthernetSwitchManagementService(scope))

                //
                // Find the specified switch.
                //
                using (ManagementObject ethernetSwitch = NetworkingUtilities.FindEthernetSwitch(switchName, scope))
                    using (ManagementObject ethernetSwitchSetting = WmiUtilities.GetFirstObjectFromCollection(
                               ethernetSwitch.GetRelated("Msvm_VirtualEthernetSwitchSettingData",
                                                         "Msvm_SettingsDefineState",
                                                         null, null, null, null, false, null)))

                        //
                        // Find the existing bandwidth setting and remove it.
                        //
                        using (ManagementObject bandwidthSetting = WmiUtilities.GetFirstObjectFromCollection(
                                   ethernetSwitchSetting.GetRelated("Msvm_VirtualEthernetSwitchBandwidthSettingData",
                                                                    "Msvm_VirtualEthernetSwitchSettingDataComponent",
                                                                    null, null, null, null, false, null)))
                        {
                            using (ManagementBaseObject inParams =
                                       managementService.GetMethodParameters("RemoveFeatureSettings"))
                            {
                                inParams["FeatureSettings"] = new string[] { bandwidthSetting.Path.Path };

                                using (ManagementBaseObject outParams =
                                           managementService.InvokeMethod("RemoveFeatureSettings", inParams, null))
                                {
                                    WmiUtilities.ValidateOutput(outParams, scope);
                                }
                            }
                        }

            Console.WriteLine(string.Format(CultureInfo.CurrentCulture,
                                            "Successfully removed bandwidth feature setting from virtual switch '{0}'.",
                                            switchName));
        }
        CreateExternalOnlySwitch(
            string externalAdapterName,
            string switchName,
            string switchNotes)
        {
            ManagementScope scope = new ManagementScope(@"root\virtualization\v2");

            string[] ports;

            //
            // Get the external adapter we are connecting to.
            //
            using (ManagementObject externalAdapter =
                       NetworkingUtilities.FindExternalAdapter(externalAdapterName, scope))

                //
                // Get the default Msvm_EthernetPortAllocationSettingData instance that we can use to
                // configure our external port connection for the switch.
                // Use the same switch name, appended with "_External", for the port name.
                // You can use any port name that you like.
                //
                using (ManagementObject portToCreate =
                           NetworkingUtilities.GetDefaultEthernetPortAllocationSettingData(scope))
                {
                    portToCreate["ElementName"]  = switchName + "_External";
                    portToCreate["HostResource"] = new string[] { externalAdapter.Path.Path };

                    //
                    // Now create the switch with the external port.
                    //
                    ports = new string[] { portToCreate.GetText(TextFormat.WmiDtd20) };
                }

            CreateSwitch(switchName, switchNotes, ports, scope);

            Console.WriteLine(string.Format(CultureInfo.CurrentCulture,
                                            "The external-only switch '{0}' was created successfully.", switchName));
        }
        CreateInternalSwitch(
            string switchName,
            string switchNotes)
        {
            ManagementScope scope = new ManagementScope(@"root\virtualization\v2");

            string[] ports;

            //
            // Get the hosting computer system. When connecting an internal port, we specify the
            // path to the hosting computer system as what the port should connect to.
            //
            using (ManagementObject hostComputerSystem = WmiUtilities.GetHostComputerSystem(scope))

                //
                // Get the default Msvm_EthernetPortAllocationSettingData instance that we can use to
                // configure our internal port connection for the switch.
                // Use the same switch name, appended with "_Internal", for the port name.
                // You can use any port name that you like.
                //
                using (ManagementObject portToCreate =
                           NetworkingUtilities.GetDefaultEthernetPortAllocationSettingData(scope))
                {
                    portToCreate["ElementName"]  = switchName + "_Internal";
                    portToCreate["HostResource"] = new string[] { hostComputerSystem.Path.Path };

                    //
                    // Now create the switch with the internal port.
                    //
                    ports = new string[] { portToCreate.GetText(TextFormat.WmiDtd20) };
                }

            CreateSwitch(switchName, switchNotes, ports, scope);

            Console.WriteLine(string.Format(CultureInfo.CurrentCulture,
                                            "The internal switch '{0}' was created successfully.", switchName));
        }
Example #11
0
        AddFeatureSettings(
            string virtualMachineName,
            NetworkingUtilities.PortFeatureType featureType)
        {
            ManagementScope scope            = new ManagementScope(@"root\virtualization\v2");
            int             connectionsCount = 0;
            string          featureId        = NetworkingUtilities.GetPortFeatureId(featureType);

            using (ManagementObject managementService = WmiUtilities.GetVirtualMachineManagementService(scope))

                //
                // Find the virtual machine whose connections we want to modify.
                //
                using (ManagementObject virtualMachine = WmiUtilities.GetVirtualMachine(virtualMachineName, scope))

                    //
                    // Find all connections for the given virtual machine.
                    //
                    using (ManagementObjectCollection connections = NetworkingUtilities.FindConnections(
                               virtualMachine, scope))

                        //
                        // Find the default feature setting for the specified feature type (e.g. Security or ACL).
                        //
                        using (ManagementObject defaultFeatureSetting =
                                   NetworkingUtilities.GetDefaultFeatureSetting(featureId, scope))
                        {
                            //
                            // Set the default feature setting's properties, which will differ depending on which type
                            // of feature setting it is.
                            //
                            switch (featureType)
                            {
                            case NetworkingUtilities.PortFeatureType.Security:
                                //
                                // For example, using a security feature setting, we can disallow MAC spoofing.
                                //
                                defaultFeatureSetting["AllowMacSpoofing"] = false;
                                break;

                            case NetworkingUtilities.PortFeatureType.Acl:
                                //
                                // For example, using an ACL feature setting, we can meter an IP range.
                                //

                                //
                                // Action may be 1 - Allow, 2 - Deny, or 3 - Meter. Here we set up a metering ACL.
                                //
                                defaultFeatureSetting["Action"] = 3;

                                //
                                // Direction may be 1 - Incoming or 2 - Outgoing. Here we set up an ACL on Outgoing traffic.
                                //
                                defaultFeatureSetting["Direction"] = 2;

                                //
                                // Applicability may be 1 - Local or 2 - Remote. Here we set up an ACL on the local endpoint.
                                //
                                defaultFeatureSetting["Applicability"] = 1;

                                //
                                // AclType may be 1 - MAC, 2 - IPv4, or 3 - IPv6. Here we set up an IPv4 ACL.
                                //
                                defaultFeatureSetting["AclType"]                   = 2;
                                defaultFeatureSetting["RemoteAddress"]             = "*.*";
                                defaultFeatureSetting["RemoteAddressPrefixLength"] = 32;
                                break;

                            case NetworkingUtilities.PortFeatureType.Offload:
                                //
                                // For example, using an Offload feature setting, we can enable IOV.
                                //
                                defaultFeatureSetting["IOVOffloadWeight"] = 100;
                                break;

                            default:
                                //
                                // Invalid featureType Argument
                                //
                                throw new ArgumentOutOfRangeException(featureType.ToString());
                            }
                            string defaultFeatureSettingText = defaultFeatureSetting.GetText(TextFormat.WmiDtd20);

                            connectionsCount = connections.Count;

                            //
                            // Now add the feature setting to each connection.
                            //
                            try
                            {
                                foreach (ManagementObject ethernetConnectionSetting in connections)
                                {
                                    using (ManagementBaseObject inParams =
                                               managementService.GetMethodParameters("AddFeatureSettings"))
                                    {
                                        inParams["AffectedConfiguration"] = ethernetConnectionSetting.Path.Path;
                                        inParams["FeatureSettings"]       = new string[] { defaultFeatureSettingText };

                                        using (ManagementBaseObject outParams =
                                                   managementService.InvokeMethod("AddFeatureSettings", inParams, null))
                                        {
                                            WmiUtilities.ValidateOutput(outParams, scope);
                                        }
                                    }
                                }
                            }
                            finally
                            {
                                // Dispose of the connections.
                                foreach (ManagementObject ethernetConnectionSetting in connections)
                                {
                                    ethernetConnectionSetting.Dispose();
                                }
                            }
                        }

            Console.WriteLine(string.Format(CultureInfo.CurrentCulture,
                                            "Successfully modified virtual machine '{0}' so that each of its {1} connection(s) " +
                                            "has an advanced {2} setting added.",
                                            virtualMachineName, connectionsCount, featureType.ToString()));
        }
        SupportsTrunkMode(
            string externalAdapterName)
        {
            ManagementScope scope             = new ManagementScope(@"root\virtualization\v2");
            bool            supportsTrunkMode = false;

            //
            // Get the external adapter.
            //
            using (ManagementObject externalAdapter =
                       NetworkingUtilities.FindExternalAdapter(externalAdapterName, scope))

                //
                // From the external adapter we need to follow the associations to get to the
                // Msvm_VLANEndpoint object that has the property we can query to see if the
                // adapter supports trunk mode. Note however, that these associated objects only
                // exist if the adapter is connected to a switch. Until the adapter is connected to
                // a switch there is not a way through the Hyper-V WMI API to determine whether it
                // supports trunk mode.
                //
                using (ManagementObjectCollection lanEndpointCollection = externalAdapter.GetRelated("Msvm_LanEndpoint"))
                {
                    if (lanEndpointCollection.Count == 0)
                    {
                        throw new ManagementException("This external adapter is not connected to any switch. " +
                                                      "Cannot determine trunk mode support.");
                    }

                    using (ManagementObject lanEndpoint = WmiUtilities.GetFirstObjectFromCollection(
                               lanEndpointCollection))

                        using (ManagementObject otherLanEndpoint = WmiUtilities.GetFirstObjectFromCollection(
                                   lanEndpoint.GetRelated("Msvm_LanEndpoint")))

                            using (ManagementObject vlanEndpoint = WmiUtilities.GetFirstObjectFromCollection(
                                       otherLanEndpoint.GetRelated("Msvm_VLANEndpoint")))
                            {
                                //
                                // Now that we have the VLAN Endpoint, we can check its SupportedEndpointModes
                                // property.
                                //
                                ushort[] supportedEndpointModes = (ushort[])vlanEndpoint["SupportedEndpointModes"];
                                foreach (ushort supportedMode in supportedEndpointModes)
                                {
                                    if (supportedMode == 5) // 5 means "TrunkMode"
                                    {
                                        supportsTrunkMode = true;
                                        break;
                                    }
                                }
                            }
                }

            if (supportsTrunkMode)
            {
                Console.WriteLine("Successfully determined that the external adapter '{0}' does support trunk mode.",
                                  externalAdapterName);
            }
            else
            {
                Console.WriteLine("Successfully determined that the external adapter '{0}' does NOT support trunk mode.",
                                  externalAdapterName);
            }
        }
        AddPorts(
            string switchName,
            string externalAdapterName)
        {
            ManagementScope scope = new ManagementScope(@"root\virtualization\v2");

            string ethernetSwitchSettingPath;
            string portToCreateText;

            ObjectQuery externalAdapterQuery = new ObjectQuery(string.Format(CultureInfo.InvariantCulture,
                                                                             "select * from Msvm_ExternalEthernetPort where Name=\"{0}\"", externalAdapterName));

            //
            // When modifying the switch, we need to pass in its configuration object.
            //
            using (ManagementObject ethernetSwitch = NetworkingUtilities.FindEthernetSwitch(switchName, scope))
                using (ManagementObject ethernetSwitchSetting = WmiUtilities.GetFirstObjectFromCollection(
                           ethernetSwitch.GetRelated("Msvm_VirtualEthernetSwitchSettingData",
                                                     "Msvm_SettingsDefineState",
                                                     null, null, null, null, false, null)))
                {
                    ethernetSwitchSettingPath = ethernetSwitchSetting.Path.Path;
                }

            //
            // Get the external adapter that we want to add a connection to.
            //
            using (ManagementObjectSearcher externalAdapterExecute =
                       new ManagementObjectSearcher(scope, externalAdapterQuery))
                using (ManagementObjectCollection externalAdapterCollection = externalAdapterExecute.Get())
                {
                    if (externalAdapterCollection.Count == 0)
                    {
                        throw new ManagementException(string.Format(CultureInfo.InvariantCulture,
                                                                    "There is no external adapter with the name {0}.",
                                                                    externalAdapterName));
                    }

                    using (ManagementObject externalAdapter =
                               WmiUtilities.GetFirstObjectFromCollection(externalAdapterCollection))

                        //
                        // Get the default Msvm_EthernetPortAllocationSettingData instance, which we can use to
                        // configure our external port connection for the switch.
                        // Use the same switch name, appended with "_External", for the port name.
                        // You can use any port name that you like.
                        //
                        using (ManagementObject portToCreate =
                                   NetworkingUtilities.GetDefaultEthernetPortAllocationSettingData(scope))
                        {
                            portToCreate["ElementName"]  = switchName + "_External";
                            portToCreate["HostResource"] = new string[] { externalAdapter.Path.Path };

                            portToCreateText = portToCreate.GetText(TextFormat.WmiDtd20);
                        }
                }

            //
            // Now add the port connection to the switch.
            //
            using (ManagementObject switchService = NetworkingUtilities.GetEthernetSwitchManagementService(scope))
                using (ManagementBaseObject inParams =
                           switchService.GetMethodParameters("AddResourceSettings"))
                {
                    inParams["AffectedConfiguration"] = ethernetSwitchSettingPath;
                    inParams["ResourceSettings"]      = new string[] { portToCreateText };

                    using (ManagementBaseObject outParams =
                               switchService.InvokeMethod("AddResourceSettings", inParams, null))
                    {
                        WmiUtilities.ValidateOutput(outParams, scope);
                    }
                }

            Console.WriteLine(string.Format(CultureInfo.CurrentCulture,
                                            "We added an external port connection to '{0}' on the switch '{1}'.",
                                            externalAdapterName, switchName));
        }
        RemovePorts(
            string switchName)
        {
            ManagementScope scope         = new ManagementScope(@"root\virtualization\v2");
            List <string>   portsToDelete = new List <string>();

            //
            // Find the switch that we want to modify.
            //
            using (ManagementObject ethernetSwitch = NetworkingUtilities.FindEthernetSwitch(switchName, scope))

                //
                // Find its internal and/or external ports to delete, but don't delete any ports that
                // are connected to virtual machines.
                // Internal ports can be recognized because their HostResource property is set to the
                // host computer.
                // Likewise, external ports can be recognized through their HostResource property,
                // which is always set to the Msvm_ExternalEthernetPort it is connected to.
                //
                using (ManagementObjectCollection ports = ethernetSwitch.GetRelated("Msvm_EthernetSwitchPort",
                                                                                    "Msvm_SystemDevice",
                                                                                    null, null, null, null, false, null))
                {
                    foreach (ManagementObject port in ports)
                    {
                        using (port)
                        {
                            //
                            // The port's connection settings are stored on its related
                            // Msvm_EthernetPortAllocationSettingData object.
                            //
                            using (ManagementObject portSettings = WmiUtilities.GetFirstObjectFromCollection(
                                       port.GetRelated("Msvm_EthernetPortAllocationSettingData",
                                                       "Msvm_ElementSettingData",
                                                       null, null, null, null, false, null)))
                            {
                                string[] hostResource = (string[])portSettings["HostResource"];

                                if (hostResource != null && hostResource.Length > 0)
                                {
                                    ManagementPath hostResourcePath = new ManagementPath(hostResource[0]);

                                    if (string.Equals(hostResourcePath.ClassName, "Msvm_ComputerSystem",
                                                      StringComparison.OrdinalIgnoreCase))
                                    {
                                        // This is the internal port. Add it to the list to delete.
                                        portsToDelete.Add(portSettings.Path.Path);
                                    }
                                    else if (string.Equals(hostResourcePath.ClassName, "Msvm_ExternalEthernetPort",
                                                           StringComparison.OrdinalIgnoreCase))
                                    {
                                        // This is the external port. Add it to the list to delete.
                                        portsToDelete.Add(portSettings.Path.Path);
                                    }
                                }
                            }
                        }
                    }
                }

            if (portsToDelete.Count == 0)
            {
                throw new ManagementException(string.Format(CultureInfo.InvariantCulture,
                                                            "The switch '{0}' does not have any internal or external ports to remove.",
                                                            switchName));
            }

            //
            // Now that we have the ports we want to delete we can call the RemoveResourceSettings
            // method.
            //
            using (ManagementObject switchService = NetworkingUtilities.GetEthernetSwitchManagementService(scope))
                using (ManagementBaseObject inParams = switchService.GetMethodParameters("RemoveResourceSettings"))
                {
                    inParams["ResourceSettings"] = portsToDelete.ToArray();

                    using (ManagementBaseObject outParams = switchService.InvokeMethod("RemoveResourceSettings", inParams, null))
                    {
                        WmiUtilities.ValidateOutput(outParams, scope);
                    }
                }

            Console.WriteLine(string.Format(CultureInfo.CurrentCulture,
                                            "We removed the internal and external ports from switch '{0}' successfully.", switchName));
        }
        RemoveFeatureSettings(
            string virtualMachineName,
            NetworkingUtilities.PortFeatureType featureType)
        {
            ManagementScope scope = new ManagementScope(@"root\virtualization\v2");
            int connectionsCount = 0;

            using (ManagementObject managementService = WmiUtilities.GetVirtualMachineManagementService(scope))

            //
            // Find the virtual machine whose connections we want to modify.
            //
            using (ManagementObject virtualMachine = WmiUtilities.GetVirtualMachine(virtualMachineName, scope))
            
            //
            // Find all connections for the given virtual machine.
            //
            using (ManagementObjectCollection connections = NetworkingUtilities.FindConnections(
                    virtualMachine, scope))
            {
                string featureSettingClass;

                switch (featureType)
                {
                    case NetworkingUtilities.PortFeatureType.Security:
                        featureSettingClass = "Msvm_EthernetSwitchPortSecuritySettingData";
                        break;

                    case NetworkingUtilities.PortFeatureType.Offload:
                        featureSettingClass = "Msvm_EthernetSwitchPortOffloadSettingData";
                        break;

                    case NetworkingUtilities.PortFeatureType.Acl:
                        featureSettingClass = "Msvm_EthernetSwitchPortAclSettingData";
                        break;

                    default:
                        throw new ArgumentOutOfRangeException(featureType.ToString());
                }
                connectionsCount = connections.Count;

                //
                // Now find the feature setting data object associated with each connection, if any.
                //
                try
                {
                    foreach (ManagementObject ethernetConnectionSetting in connections)
                    {
                        List<string> featureSettingPaths = new List<string>();

                        using (ManagementObjectCollection featureSettingCollection =
                            ethernetConnectionSetting.GetRelated(featureSettingClass,
                                "Msvm_EthernetPortSettingDataComponent",
                                null, null, null, null, false, null))
                        {
                            if (featureSettingCollection.Count == 0)
                            {
                                continue;
                            }

                            foreach (ManagementObject featureSetting in featureSettingCollection)
                            using (featureSetting)
                            {
                                featureSettingPaths.Add(featureSetting.Path.Path);
                            }
                        }
    
                        using (ManagementBaseObject inParams = 
                               managementService.GetMethodParameters("RemoveFeatureSettings"))
                        {
        
                            //
                            // We specify which feature setting to remove by giving the WMI path to the feature setting object.
                            //
                            inParams["FeatureSettings"] = featureSettingPaths.ToArray();
        
                            using (ManagementBaseObject outParams = 
                                   managementService.InvokeMethod("RemoveFeatureSettings", inParams, null))
                            {
                                WmiUtilities.ValidateOutput(outParams, scope);
                            }
                        }
                    }
                }
                finally
                {
                    // Dispose of the connections.
                    foreach (ManagementObject ethernetConnectionSetting in connections)
                    {
                        ethernetConnectionSetting.Dispose();
                    }
                }
            }

            Console.WriteLine(string.Format(CultureInfo.CurrentCulture,
                "Successfully modified virtual machine '{0}' to remove advanced {2} settings from " + 
                "each of its {1} connection(s).",
                virtualMachineName, connectionsCount, featureType.ToString()));
        }
        AddFeatureSettings(
            string virtualMachineName,
            NetworkingUtilities.PortFeatureType featureType)
        {
            ManagementScope scope = new ManagementScope(@"root\virtualization\v2");
            int connectionsCount = 0;
            string featureId = NetworkingUtilities.GetPortFeatureId(featureType);

            using (ManagementObject managementService = WmiUtilities.GetVirtualMachineManagementService(scope))

            //
            // Find the virtual machine whose connections we want to modify.
            //
            using (ManagementObject virtualMachine = WmiUtilities.GetVirtualMachine(virtualMachineName, scope))

            //
            // Find all connections for the given virtual machine.
            //
            using (ManagementObjectCollection connections = NetworkingUtilities.FindConnections(
                    virtualMachine, scope))

            //
            // Find the default feature setting for the specified feature type (e.g. Security or ACL).
            //
            using (ManagementObject defaultFeatureSetting =
                  NetworkingUtilities.GetDefaultFeatureSetting(featureId, scope))
            {
                //
                // Set the default feature setting's properties, which will differ depending on which type
                // of feature setting it is.
                //
                switch (featureType)
                {
                    case NetworkingUtilities.PortFeatureType.Security:
                        //  
                        // For example, using a security feature setting, we can disallow MAC spoofing.
                        //
                        defaultFeatureSetting["AllowMacSpoofing"] = false;
                        break;

                    case NetworkingUtilities.PortFeatureType.Acl:
                        //
                        // For example, using an ACL feature setting, we can meter an IP range.
                        //

                        //
                        // Action may be 1 - Allow, 2 - Deny, or 3 - Meter. Here we set up a metering ACL.
                        //
                        defaultFeatureSetting["Action"] = 3;

                        //
                        // Direction may be 1 - Incoming or 2 - Outgoing. Here we set up an ACL on Outgoing traffic.
                        //
                        defaultFeatureSetting["Direction"] = 2;

                        //
                        // Applicability may be 1 - Local or 2 - Remote. Here we set up an ACL on the local endpoint.
                        //
                        defaultFeatureSetting["Applicability"] = 1;

                        //
                        // AclType may be 1 - MAC, 2 - IPv4, or 3 - IPv6. Here we set up an IPv4 ACL.
                        //
                        defaultFeatureSetting["AclType"] = 2;
                        defaultFeatureSetting["RemoteAddress"] = "*.*";
                        defaultFeatureSetting["RemoteAddressPrefixLength"] = 32;
                        break;

                    case NetworkingUtilities.PortFeatureType.Offload:
                        //
                        // For example, using an Offload feature setting, we can enable IOV.
                        //
                        defaultFeatureSetting["IOVOffloadWeight"] = 100;
                        break;

                    default:
                        //
                        // Invalid featureType Argument
                        //
                        throw new ArgumentOutOfRangeException(featureType.ToString());
                }
                string defaultFeatureSettingText = defaultFeatureSetting.GetText(TextFormat.WmiDtd20);

                connectionsCount = connections.Count;

                //
                // Now add the feature setting to each connection.
                //
                try
                {
                    foreach (ManagementObject ethernetConnectionSetting in connections)
                    {
                        using (ManagementBaseObject inParams = 
                               managementService.GetMethodParameters("AddFeatureSettings"))
                        {
                            inParams["AffectedConfiguration"] = ethernetConnectionSetting.Path.Path;
                            inParams["FeatureSettings"] = new string[] { defaultFeatureSettingText };

                            using (ManagementBaseObject outParams = 
                                   managementService.InvokeMethod("AddFeatureSettings", inParams, null))
                            {
                                WmiUtilities.ValidateOutput(outParams, scope);
                            }
                        }
                    }
                }
                finally
                {
                    // Dispose of the connections.
                    foreach (ManagementObject ethernetConnectionSetting in connections)
                    {
                        ethernetConnectionSetting.Dispose();
                    }
                }
            }

            Console.WriteLine(string.Format(CultureInfo.CurrentCulture,
                "Successfully modified virtual machine '{0}' so that each of its {1} connection(s) " + 
                "has an advanced {2} setting added.",
                virtualMachineName, connectionsCount, featureType.ToString()));
        }
        ModifyFeatureSettings(
            string virtualMachineName,
            NetworkingUtilities.PortFeatureType featureType)
        {
            ManagementScope scope = new ManagementScope(@"root\virtualization\v2");
            int connectionsCount = 0;
            
            using (ManagementObject managementService = WmiUtilities.GetVirtualMachineManagementService(scope))

            //
            // Find the virtual machine we want to modify the connections of.
            //
            using (ManagementObject virtualMachine = WmiUtilities.GetVirtualMachine(virtualMachineName, scope))

            //
            // Find all connections for the given virtual machine.
            //
            using (ManagementObjectCollection connections = NetworkingUtilities.FindConnections(
                    virtualMachine, scope))
            {
                connectionsCount = connections.Count;
    
                //
                // Now find the security feature setting data object associated with each connection, if any.
                //
                try
                {
                    string featureClassName;
                    switch (featureType)
                    {
                        case NetworkingUtilities.PortFeatureType.Security:
                            featureClassName = "Msvm_EthernetSwitchPortSecuritySettingData";
                            break;

                        case NetworkingUtilities.PortFeatureType.Offload:
                            featureClassName = "Msvm_EthernetSwitchPortOffloadSettingData";
                            break;

                        default:
                            throw new ArgumentOutOfRangeException(featureType.ToString());
                    }

                    foreach (ManagementObject ethernetConnectionSetting in connections)
                    {
                        using (ManagementObjectCollection featureSettingCollection =
                            ethernetConnectionSetting.GetRelated(featureClassName,
                                "Msvm_EthernetPortSettingDataComponent",
                                null, null, null, null, false, null))
                        {
                            //
                            // For the security/offload feature, each connection can have no more than one instance 
                            // of the feature setting, so we can simply take the first feature setting associated 
                            // with each connection. For other features, it may be necessary to do extra work.
                            //
                            if (featureSettingCollection.Count == 0)
                            {
                                continue;
                            }

                            string featureText;
                            using (ManagementObject featureSetting =
                                   WmiUtilities.GetFirstObjectFromCollection(featureSettingCollection))
                            {
                                switch (featureType)
                                {
                                    case NetworkingUtilities.PortFeatureType.Security:
                                        //
                                        // Modify the feature setting's properties. Here, we enable MAC spoofing.
                                        //
                                        featureSetting["AllowMacSpoofing"] = true;
                                        break;

                                    case NetworkingUtilities.PortFeatureType.Offload:
                                        //
                                        // Modify the feature setting's properties. Here, we modify IOVQueuePairsRequested.
                                        //
                                        featureSetting["IOVQueuePairsRequested"] = 2;
                                        break;
                                }
                                featureText = featureSetting.GetText(TextFormat.WmiDtd20);            
                            }

                            // Now apply the changes to the Hyper-V server.
                            using (ManagementBaseObject inParams =
                                   managementService.GetMethodParameters("ModifyFeatureSettings"))
                            {
                                inParams["FeatureSettings"] = new string[] { featureText };

                                using (ManagementBaseObject outParams =
                                       managementService.InvokeMethod("ModifyFeatureSettings", inParams, null))
                                {
                                    WmiUtilities.ValidateOutput(outParams, scope);
                                }
                            }
                        }
                    }
                }
                finally
                {
                    // Dispose of the connections.
                    foreach (ManagementObject ethernetConnectionSetting in connections)
                    {
                        ethernetConnectionSetting.Dispose();
                    }
                }
            }

            Console.WriteLine(string.Format(CultureInfo.CurrentCulture,
                "Successfully modified virtual machine '{0}' so that each of its {1} connection(s) " +
                "has its advanced {2} settings modified.",
                virtualMachineName, connectionsCount, featureType.ToString()));
        }
        ModifyPorts(
            string switchName,
            string newExternalAdapterName)
        {
            ManagementScope scope = new ManagementScope(@"root\virtualization\v2");

            ObjectQuery externalAdapterQuery = new ObjectQuery(string.Format(CultureInfo.InvariantCulture,
                                                                             "select * from Msvm_ExternalEthernetPort where Name=\"{0}\"", newExternalAdapterName));

            //
            // Find the switch that we want to modify.
            //
            using (ManagementObject ethernetSwitch = NetworkingUtilities.FindEthernetSwitch(switchName, scope))

                //
                // Get the external adapter we are connecting to.
                //
                using (ManagementObjectSearcher externalAdapterExecute = new ManagementObjectSearcher(scope, externalAdapterQuery))
                    using (ManagementObjectCollection externalAdapterCollection = externalAdapterExecute.Get())
                    {
                        if (externalAdapterCollection.Count == 0)
                        {
                            throw new ManagementException("There is no external adapter with the name: " + newExternalAdapterName);
                        }

                        string externalAdapterPath;
                        string externalPortSettingsText = null;

                        using (ManagementObject externalAdapter = WmiUtilities.GetFirstObjectFromCollection(externalAdapterCollection))
                        {
                            externalAdapterPath = externalAdapter.Path.Path;
                        }

                        //
                        // Find the switch's current external port.
                        //

                        using (ManagementObjectCollection ports = ethernetSwitch.GetRelated("Msvm_EthernetSwitchPort",
                                                                                            "Msvm_SystemDevice",
                                                                                            null, null, null, null, false, null))
                            foreach (ManagementObject port in ports)
                            {
                                using (port)
                                {
                                    //
                                    // The port's connection settings are stored on its related
                                    // Msvm_EthernetPortAllocationSettingData object.
                                    // The external port is the one connected to a Msvm_ExternalEthernetPort
                                    // through its HostResource property.
                                    //
                                    using (ManagementObject portSettings = WmiUtilities.GetFirstObjectFromCollection(
                                               port.GetRelated("Msvm_EthernetPortAllocationSettingData",
                                                               "Msvm_ElementSettingData",
                                                               null, null, null, null, false, null)))
                                    {
                                        string[] hostResource = (string[])portSettings["HostResource"];

                                        if (hostResource != null && hostResource.Length > 0)
                                        {
                                            ManagementPath hostResourcePath = new ManagementPath(hostResource[0]);

                                            if (string.Equals(hostResourcePath.ClassName, "Msvm_ExternalEthernetPort",
                                                              StringComparison.OrdinalIgnoreCase))
                                            {
                                                //
                                                // Validate that it isn't already connected to the external adapter we
                                                // are trying to change it to.
                                                //
                                                if (string.Equals(hostResourcePath.Path, externalAdapterPath,
                                                                  StringComparison.OrdinalIgnoreCase))
                                                {
                                                    throw new ManagementException(string.Format(CultureInfo.CurrentCulture,
                                                                                                "The switch '{0}' is already connected to '{1}'.",
                                                                                                switchName, newExternalAdapterName));
                                                }

                                                //
                                                // Now that we have the switch's external port, we can modify it so that it
                                                // is connected to newExternalAdapterName.
                                                //

                                                portSettings["HostResource"] = new string[] { externalAdapterPath };
                                                externalPortSettingsText     = portSettings.GetText(TextFormat.WmiDtd20);
                                                break;
                                            }
                                        }
                                    }
                                }
                            }

                        if (externalPortSettingsText == null)
                        {
                            throw new ManagementException(string.Format(CultureInfo.CurrentCulture,
                                                                        "The switch '{0}' is not connected to an external network.", switchName));
                        }

                        using (ManagementObject switchService = NetworkingUtilities.GetEthernetSwitchManagementService(scope))
                            using (ManagementBaseObject inParams = switchService.GetMethodParameters("ModifyResourceSettings"))
                            {
                                inParams["ResourceSettings"] = new string[] { externalPortSettingsText };

                                using (ManagementBaseObject outParams =
                                           switchService.InvokeMethod("ModifyResourceSettings", inParams, null))
                                {
                                    WmiUtilities.ValidateOutput(outParams, scope);
                                }
                            }
                    }

            Console.WriteLine(string.Format(CultureInfo.CurrentCulture,
                                            "Successfully bound the switch '{0}' to the external network '{1}'.",
                                            switchName, newExternalAdapterName));
        }
        ModifyConnection(
            string virtualMachineName,
            string currentSwitchName,
            string newSwitchName)
        {
            ManagementScope scope = new ManagementScope(@"root\virtualization\v2");

            using (ManagementObject managementService = WmiUtilities.GetVirtualMachineManagementService(scope))

                //
                // Find the Ethernet switch we want to disconnect from and the one we want to connect to.
                //
                using (ManagementObject currentEthernetSwitch = NetworkingUtilities.FindEthernetSwitch(currentSwitchName, scope))
                    using (ManagementObject newEthernetSwitch = NetworkingUtilities.FindEthernetSwitch(newSwitchName, scope))

                        //
                        // Find the virtual machine we want to modify.
                        //
                        using (ManagementObject virtualMachine = WmiUtilities.GetVirtualMachine(virtualMachineName, scope))
                        {
                            //
                            // Find the connections to the current switch.
                            // Note that this method finds all connections to the switch, including those connections
                            // that are configured to dynamically select a switch from a switch resource pool and
                            // reconfigures them to always connect to the new switch. If you only want to modify
                            // connections that are configured with a hard-affinity to the original switch, modify the
                            // NetworkingUtilities.FindConnectionsToSwitch method.
                            //
                            IList <ManagementObject> currentConnections =
                                NetworkingUtilities.FindConnectionsToSwitch(virtualMachine, currentEthernetSwitch, scope);

                            //
                            // Set each connection to connect to the new switch. If the virtual machine is currently
                            // running, then it will immediately connect to the new switch. If it is not running, then
                            // it will connect to the switch when it is turned on.
                            //
                            try
                            {
                                foreach (ManagementObject connection in currentConnections)
                                {
                                    connection["HostResource"] = new string[] { newEthernetSwitch.Path.Path };

                                    using (ManagementBaseObject inParams =
                                               managementService.GetMethodParameters("ModifyResourceSettings"))
                                    {
                                        inParams["ResourceSettings"] = new string[] { connection.GetText(TextFormat.WmiDtd20) };

                                        using (ManagementBaseObject outParams =
                                                   managementService.InvokeMethod("ModifyResourceSettings", inParams, null))
                                        {
                                            WmiUtilities.ValidateOutput(outParams, scope);
                                        }
                                    }
                                }
                            }
                            finally
                            {
                                // Dispose of the connections.
                                foreach (ManagementObject connection in currentConnections)
                                {
                                    connection.Dispose();
                                }
                            }
                        }

            Console.WriteLine(string.Format(CultureInfo.CurrentCulture,
                                            "Successfully modified virtual machine '{0}' so that every connection to '{1}' is now " +
                                            "connected to '{2}'.", virtualMachineName, currentSwitchName, newSwitchName));
        }
        EnumerateSwitch(
            string switchName)
        {
            ManagementScope scope = new ManagementScope(@"root\virtualization\v2");

            //
            // Initialize our SwitchInfo structure to hold information about the switch.
            //
            SwitchInfo ethernetSwitchInfo = new SwitchInfo();

            ethernetSwitchInfo.Name              = switchName;
            ethernetSwitchInfo.Type              = SwitchConnectionType.Private;
            ethernetSwitchInfo.PortList          = new List <PortInfo>();
            ethernetSwitchInfo.SwitchFeatureList = new List <NetworkingUtilities.SwitchFeatureType>();

            using (ManagementObject ethernetSwitch = NetworkingUtilities.FindEthernetSwitch(switchName, scope))
            {
                //
                // Enumerate the switch's ports.
                //
                using (ManagementObjectCollection portCollection = ethernetSwitch.GetRelated("Msvm_EthernetSwitchPort",
                                                                                             "Msvm_SystemDevice",
                                                                                             null, null, null, null, false, null))
                {
                    foreach (ManagementObject port in portCollection)
                    {
                        using (port)
                        {
                            //
                            // Initialize a PortInfo structure to hold information about this port.
                            //
                            PortInfo portInfo = new PortInfo();
                            portInfo.Type        = PortConnectionType.Nothing;
                            portInfo.FeatureList = new List <NetworkingUtilities.PortFeatureType>();

                            //
                            // The port's connection settings are stored on its related
                            // Msvm_EthernetPortAllocationSettingData object.
                            //
                            using (ManagementObject portSettings = WmiUtilities.GetFirstObjectFromCollection(
                                       port.GetRelated("Msvm_EthernetPortAllocationSettingData",
                                                       "Msvm_ElementSettingData",
                                                       null, null, null, null, false, null)))
                            {
                                //
                                // Determine the port's connection type.
                                //
                                portInfo.Type = DeterminePortType(portSettings);

                                if (portInfo.Type == PortConnectionType.VirtualMachine)
                                {
                                    // Get the name of the connected virtual machine.
                                    using (ManagementObject virtualMachineSettings = WmiUtilities.GetFirstObjectFromCollection(
                                               portSettings.GetRelated("Msvm_VirtualSystemSettingData",
                                                                       "Msvm_VirtualSystemSettingDataComponent",
                                                                       null, null, null, null, false, null)))
                                    {
                                        portInfo.ConnectedName = (string)virtualMachineSettings["ElementName"];
                                    }
                                }
                                else if (portInfo.Type == PortConnectionType.External)
                                {
                                    // Get the name of the external connection.
                                    using (ManagementObject externalAdapter = new ManagementObject(
                                               ((string[])portSettings["HostResource"])[0]))
                                    {
                                        portInfo.ConnectedName = (string)externalAdapter["ElementName"];
                                    }
                                }

                                //
                                // Now determine which advanced properties are configured for this port.
                                // Each Feature has its own class definition and is related to the portSettings
                                // through the Msvm_EthernetPortSettingDataComponent association.
                                //
                                using (ManagementObjectCollection portFeatureCollection =
                                           portSettings.GetRelated("Msvm_EthernetSwitchPortFeatureSettingData",
                                                                   "Msvm_EthernetPortSettingDataComponent",
                                                                   null, null, null, null, false, null))
                                {
                                    foreach (ManagementObject portFeature in portFeatureCollection)
                                    {
                                        using (portFeature)
                                        {
                                            portInfo.FeatureList.Add(DeterminePortFeatureType(portFeature));
                                        }
                                    }
                                }
                            }

                            ethernetSwitchInfo.PortList.Add(portInfo);
                        }
                    }
                }

                //
                // Then enumerate the switch's features.
                //
                using (ManagementObject ethernetSwitchSetting = WmiUtilities.GetFirstObjectFromCollection(
                           ethernetSwitch.GetRelated("Msvm_VirtualEthernetSwitchSettingData",
                                                     "Msvm_SettingsDefineState",
                                                     null, null, null, null, false, null)))
                    using (ManagementObjectCollection switchFeatures = ethernetSwitchSetting.GetRelated(
                               "Msvm_EthernetSwitchFeatureSettingData",
                               "Msvm_VirtualEthernetSwitchSettingDataComponent",
                               null, null, null, null, false, null))
                        foreach (ManagementObject switchFeature in switchFeatures)
                        {
                            using (switchFeature)
                            {
                                ethernetSwitchInfo.SwitchFeatureList.Add(DetermineSwitchFeatureType(switchFeature));
                            }
                        }
            }

            //
            // Now that we have enumerated all of the switch's ports, we can determine the
            // switch's connection type.
            //
            ethernetSwitchInfo.Type = DetermineSwitchConnectionType(ethernetSwitchInfo.PortList);

            //
            // We now have all of the information we need - output it to the console.
            //
            OutputSwitchInfo(ethernetSwitchInfo);
        }
        SetRequiredFeature(
            string vmName,
            string featureName,
            bool required)
        {
            ManagementScope scope = new ManagementScope(@"root\virtualization\v2");
            List <string>   connectionsToModify = new List <string>();

            //
            // Find the feature capability object.
            //
            using (ManagementObject feature = NetworkingUtilities.FindFeatureByName(featureName, scope))

                //
                // Find all the Ethernet connections associated with the virtual machine.
                //
                using (ManagementObject virtualMachine = WmiUtilities.GetVirtualMachine(vmName, scope))
                    using (ManagementObjectCollection connectionCollection = NetworkingUtilities.FindConnections(virtualMachine, scope))
                    {
                        foreach (ManagementObject connection in connectionCollection)
                        {
                            using (connection)
                            {
                                //
                                // Look at the current list of required features, and find out whether the
                                // specified feature is already present in the list. Each element of the
                                // list is the WMI path to a feature capability object.
                                //
                                string[] requiredFeatures = (string[])connection["RequiredFeatures"];
                                int      featureIndex     = -1;

                                for (int idx = 0; idx < requiredFeatures.Length; ++idx)
                                {
                                    using (ManagementObject requiredFeature = new ManagementObject(requiredFeatures[idx]))
                                    {
                                        requiredFeature.Get();

                                        if (String.Equals(
                                                (string)requiredFeature["ElementName"],
                                                featureName,
                                                StringComparison.OrdinalIgnoreCase))
                                        {
                                            featureIndex = idx;
                                            break;
                                        }
                                    }
                                }

                                if (((featureIndex == -1) && !required) ||
                                    ((featureIndex != -1) && required))
                                {
                                    //
                                    // The feature is not required and not present in the list,
                                    // or required and already present in the list. In either case
                                    // there's nothing left to do for this connection.
                                    //
                                    continue;
                                }

                                string[] newRequiredFeatures = null;

                                if (required)
                                {
                                    //
                                    // Append the new feature at the end of list.
                                    //
                                    newRequiredFeatures = new string[requiredFeatures.Length + 1];

                                    for (int idx = 0; idx < requiredFeatures.Length; ++idx)
                                    {
                                        newRequiredFeatures[idx] = requiredFeatures[idx];
                                    }

                                    newRequiredFeatures[newRequiredFeatures.Length - 1] = feature.Path.Path;
                                }
                                else
                                {
                                    //
                                    // Remove the feature from the list.
                                    //
                                    newRequiredFeatures = new string[requiredFeatures.Length - 1];

                                    for (int idx = 0; idx < featureIndex; ++idx)
                                    {
                                        newRequiredFeatures[idx] = requiredFeatures[idx];
                                    }

                                    for (int idx = featureIndex; idx < newRequiredFeatures.Length; ++idx)
                                    {
                                        newRequiredFeatures[idx] = requiredFeatures[idx + 1];
                                    }
                                }

                                connection["RequiredFeatures"] = newRequiredFeatures;
                                connectionsToModify.Add(connection.GetText(TextFormat.WmiDtd20));
                            }
                        }
                    }

            if (connectionsToModify.Count > 0)
            {
                using (ManagementObject managementService = WmiUtilities.GetVirtualMachineManagementService(scope))
                    using (ManagementBaseObject inParams = managementService.GetMethodParameters("ModifyResourceSettings"))
                    {
                        inParams["ResourceSettings"] = connectionsToModify.ToArray();

                        using (ManagementBaseObject outParams =
                                   managementService.InvokeMethod("ModifyResourceSettings", inParams, null))
                        {
                            WmiUtilities.ValidateOutput(outParams, scope);
                        }
                    }
            }

            Console.WriteLine(string.Format(CultureInfo.CurrentCulture,
                                            "Feature '{0}' is {1} the list of required features for virtual machine '{2}'.",
                                            featureName,
                                            required ? "added to" : "removed from",
                                            vmName));
        }
        SetExtensionEnabledState(
            string switchName,
            string extensionName,
            bool enabled)
        {
            bool found = false;

            ManagementScope scope = new ManagementScope(@"root\virtualization\v2");

            //
            // Get the switch we want to modify.
            //
            using (ManagementObject ethernetSwitch = NetworkingUtilities.FindEthernetSwitch(switchName, scope))

                //
                // To make modifications to the switch, we need to modify its configuration object.
                //
                using (ManagementObjectCollection extensions = ethernetSwitch.GetRelated(
                           "Msvm_EthernetSwitchExtension",
                           "Msvm_HostedEthernetSwitchExtension",
                           null,
                           null,
                           null,
                           null,
                           false,
                           null))
                {
                    foreach (ManagementObject extension in extensions)
                    {
                        using (extension)
                        {
                            if (!String.Equals(
                                    (string)extension["ElementName"],
                                    extensionName,
                                    StringComparison.OrdinalIgnoreCase))
                            {
                                continue;
                            }

                            found = true;

                            if ((UInt16)extension["EnabledState"] == CimEnabledStateNotApplicable)
                            {
                                Console.WriteLine("The enabled state of the specified extension cannot be changed.");
                                continue;
                            }

                            if (((UInt16)extension["EnabledState"] == CimEnabledStateEnabled) && enabled)
                            {
                                Console.WriteLine("The specified extension is already enabled.");
                                continue;
                            }

                            if (((UInt16)extension["EnabledState"] == CimEnabledStateDisabled) && !enabled)
                            {
                                Console.WriteLine("The specified extension is already disabled.");
                                continue;
                            }

                            using (ManagementBaseObject inParams = extension.GetMethodParameters("RequestStateChange"))
                            {
                                inParams["RequestedState"] = enabled ? CimEnabledStateEnabled : CimEnabledStateDisabled;

                                using (ManagementBaseObject outParams =
                                           extension.InvokeMethod("RequestStateChange", inParams, null))
                                {
                                    WmiUtilities.ValidateOutput(outParams, scope);

                                    Console.WriteLine(string.Format(
                                                          CultureInfo.CurrentCulture,
                                                          "Extension '{0}' was successfully {1} on switch '{2}'.",
                                                          extensionName,
                                                          enabled ? "enabled" : "disabled",
                                                          switchName));
                                }
                            }
                        }
                    }
                }

            if (!found)
            {
                throw new ApplicationException(String.Format(
                                                   CultureInfo.CurrentCulture,
                                                   "Could not find extension '{0}' on switch '{1}'.",
                                                   extensionName,
                                                   switchName));
            }
        }
Example #23
0
        ModifyFeatureSettings(
            string virtualMachineName,
            NetworkingUtilities.PortFeatureType featureType)
        {
            ManagementScope scope            = new ManagementScope(@"root\virtualization\v2");
            int             connectionsCount = 0;

            using (ManagementObject managementService = WmiUtilities.GetVirtualMachineManagementService(scope))

                //
                // Find the virtual machine we want to modify the connections of.
                //
                using (ManagementObject virtualMachine = WmiUtilities.GetVirtualMachine(virtualMachineName, scope))

                    //
                    // Find all connections for the given virtual machine.
                    //
                    using (ManagementObjectCollection connections = NetworkingUtilities.FindConnections(
                               virtualMachine, scope))
                    {
                        connectionsCount = connections.Count;

                        //
                        // Now find the security feature setting data object associated with each connection, if any.
                        //
                        try
                        {
                            string featureClassName;
                            switch (featureType)
                            {
                            case NetworkingUtilities.PortFeatureType.Security:
                                featureClassName = "Msvm_EthernetSwitchPortSecuritySettingData";
                                break;

                            case NetworkingUtilities.PortFeatureType.Offload:
                                featureClassName = "Msvm_EthernetSwitchPortOffloadSettingData";
                                break;

                            default:
                                throw new ArgumentOutOfRangeException(featureType.ToString());
                            }

                            foreach (ManagementObject ethernetConnectionSetting in connections)
                            {
                                using (ManagementObjectCollection featureSettingCollection =
                                           ethernetConnectionSetting.GetRelated(featureClassName,
                                                                                "Msvm_EthernetPortSettingDataComponent",
                                                                                null, null, null, null, false, null))
                                {
                                    //
                                    // For the security/offload feature, each connection can have no more than one instance
                                    // of the feature setting, so we can simply take the first feature setting associated
                                    // with each connection. For other features, it may be necessary to do extra work.
                                    //
                                    if (featureSettingCollection.Count == 0)
                                    {
                                        continue;
                                    }

                                    string featureText;
                                    using (ManagementObject featureSetting =
                                               WmiUtilities.GetFirstObjectFromCollection(featureSettingCollection))
                                    {
                                        switch (featureType)
                                        {
                                        case NetworkingUtilities.PortFeatureType.Security:
                                            //
                                            // Modify the feature setting's properties. Here, we enable MAC spoofing.
                                            //
                                            featureSetting["AllowMacSpoofing"] = true;
                                            break;

                                        case NetworkingUtilities.PortFeatureType.Offload:
                                            //
                                            // Modify the feature setting's properties. Here, we modify IOVQueuePairsRequested.
                                            //
                                            featureSetting["IOVQueuePairsRequested"] = 2;
                                            break;
                                        }
                                        featureText = featureSetting.GetText(TextFormat.WmiDtd20);
                                    }

                                    // Now apply the changes to the Hyper-V server.
                                    using (ManagementBaseObject inParams =
                                               managementService.GetMethodParameters("ModifyFeatureSettings"))
                                    {
                                        inParams["FeatureSettings"] = new string[] { featureText };

                                        using (ManagementBaseObject outParams =
                                                   managementService.InvokeMethod("ModifyFeatureSettings", inParams, null))
                                        {
                                            WmiUtilities.ValidateOutput(outParams, scope);
                                        }
                                    }
                                }
                            }
                        }
                        finally
                        {
                            // Dispose of the connections.
                            foreach (ManagementObject ethernetConnectionSetting in connections)
                            {
                                ethernetConnectionSetting.Dispose();
                            }
                        }
                    }

            Console.WriteLine(string.Format(CultureInfo.CurrentCulture,
                                            "Successfully modified virtual machine '{0}' so that each of its {1} connection(s) " +
                                            "has its advanced {2} settings modified.",
                                            virtualMachineName, connectionsCount, featureType.ToString()));
        }
        ConnectVmUsingResourcePool(
            string virtualMachineName,
            string resourcePoolName)
        {
            ManagementScope scope = new ManagementScope(@"root\virtualization\v2");

            using (ManagementObject managementService = WmiUtilities.GetVirtualMachineManagementService(scope))

                //
                // Find the virtual machine we want to connect.
                //
                using (ManagementObject virtualMachine = WmiUtilities.GetVirtualMachine(virtualMachineName, scope))

                    //
                    // As a sanity check, verify that the specified resource pool exists by querying for it.
                    //
                    using (ManagementObject resourcePool = WmiUtilities.GetResourcePool(
                               "33",
                               "Microsoft:Hyper-V:Ethernet Connection",
                               resourcePoolName,
                               scope))

                        //
                        // Get the virtual machine's settings object which is used to make configuration changes.
                        //
                        using (ManagementObject virtualMachineSettings = WmiUtilities.GetVirtualMachineSettings(virtualMachine))

                            //
                            // Add a new synthetic Network Adapter device to the virtual machine.
                            //
                            using (ManagementObject syntheticAdapter = NetworkingUtilities.AddSyntheticAdapter(virtualMachine, scope))

                                //
                                // Now that we have added a network adapter to the virtual machine, we can configure its
                                // connection settings.
                                //
                                using (ManagementObject connectionSettingsToAdd =
                                           NetworkingUtilities.GetDefaultEthernetPortAllocationSettingData(scope))
                                {
                                    connectionSettingsToAdd["Parent"] = syntheticAdapter.Path.Path;

                                    //
                                    // Rather than specifying which switch to connect to, we specify which pool to look in.
                                    //
                                    connectionSettingsToAdd["PoolId"] = resourcePoolName;

                                    //
                                    // Now add the connection settings.
                                    //
                                    using (ManagementBaseObject addConnectionInParams =
                                               managementService.GetMethodParameters("AddResourceSettings"))
                                    {
                                        addConnectionInParams["AffectedConfiguration"] = virtualMachineSettings.Path.Path;
                                        addConnectionInParams["ResourceSettings"]      =
                                            new string[] { connectionSettingsToAdd.GetText(TextFormat.WmiDtd20) };

                                        using (ManagementBaseObject addConnectionOutParams =
                                                   managementService.InvokeMethod("AddResourceSettings", addConnectionInParams, null))
                                        {
                                            WmiUtilities.ValidateOutput(addConnectionOutParams, scope);
                                        }
                                    }
                                }

            Console.WriteLine(string.Format(CultureInfo.CurrentCulture,
                                            "Successfully created dynamic connection from virtual machine '{0}' to resource pool '{1}'.",
                                            virtualMachineName, resourcePoolName));
        }
        DisconnectVmFromSwitch(
            string virtualMachineName,
            string switchName)
        {
            ManagementScope scope = new ManagementScope(@"root\virtualization\v2");

            using (ManagementObject managementService = WmiUtilities.GetVirtualMachineManagementService(scope))

                //
                // Find the Ethernet switch we want to disconnect from.
                //
                using (ManagementObject ethernetSwitch = NetworkingUtilities.FindEthernetSwitch(switchName, scope))

                    //
                    // Find the virtual machine we want to disconnect.
                    //
                    using (ManagementObject virtualMachine = WmiUtilities.GetVirtualMachine(virtualMachineName, scope))
                    {
                        //
                        // Find all of the connections to this switch.
                        //
                        IList <ManagementObject> connectionsToSwitch =
                            NetworkingUtilities.FindConnectionsToSwitch(virtualMachine, ethernetSwitch, scope);

                        //
                        // Now that we have found all of the connections to the switch we can go through and
                        // disable each connection so that it is not connected to anything. Note that you can also
                        // delete the connection object, but disabling the connection is sometimes preferable because
                        // it preserves all of the connection's configuration options along with any metrics
                        // associated with the connection.
                        //
                        try
                        {
                            foreach (ManagementObject connection in connectionsToSwitch)
                            {
                                connection["EnabledState"] = 3; // 3 means "Disabled"

                                using (ManagementBaseObject inParams =
                                           managementService.GetMethodParameters("ModifyResourceSettings"))
                                {
                                    inParams["ResourceSettings"] = new string[] { connection.GetText(TextFormat.WmiDtd20) };

                                    using (ManagementBaseObject outParams =
                                               managementService.InvokeMethod("ModifyResourceSettings", inParams, null))
                                    {
                                        WmiUtilities.ValidateOutput(outParams, scope);
                                    }
                                }
                            }
                        }
                        finally
                        {
                            // Dispose of the connectionsToSwitch.
                            foreach (ManagementObject connection in connectionsToSwitch)
                            {
                                connection.Dispose();
                            }
                        }
                    }

            Console.WriteLine(string.Format(CultureInfo.CurrentCulture,
                                            "Successfully disconnected virtual machine '{0}' from switch '{1}'.",
                                            virtualMachineName, switchName));
        }
Example #26
0
        RemoveFeatureSettings(
            string virtualMachineName,
            NetworkingUtilities.PortFeatureType featureType)
        {
            ManagementScope scope            = new ManagementScope(@"root\virtualization\v2");
            int             connectionsCount = 0;

            using (ManagementObject managementService = WmiUtilities.GetVirtualMachineManagementService(scope))

                //
                // Find the virtual machine whose connections we want to modify.
                //
                using (ManagementObject virtualMachine = WmiUtilities.GetVirtualMachine(virtualMachineName, scope))

                    //
                    // Find all connections for the given virtual machine.
                    //
                    using (ManagementObjectCollection connections = NetworkingUtilities.FindConnections(
                               virtualMachine, scope))
                    {
                        string featureSettingClass;

                        switch (featureType)
                        {
                        case NetworkingUtilities.PortFeatureType.Security:
                            featureSettingClass = "Msvm_EthernetSwitchPortSecuritySettingData";
                            break;

                        case NetworkingUtilities.PortFeatureType.Offload:
                            featureSettingClass = "Msvm_EthernetSwitchPortOffloadSettingData";
                            break;

                        case NetworkingUtilities.PortFeatureType.Acl:
                            featureSettingClass = "Msvm_EthernetSwitchPortAclSettingData";
                            break;

                        default:
                            throw new ArgumentOutOfRangeException(featureType.ToString());
                        }
                        connectionsCount = connections.Count;

                        //
                        // Now find the feature setting data object associated with each connection, if any.
                        //
                        try
                        {
                            foreach (ManagementObject ethernetConnectionSetting in connections)
                            {
                                List <string> featureSettingPaths = new List <string>();

                                using (ManagementObjectCollection featureSettingCollection =
                                           ethernetConnectionSetting.GetRelated(featureSettingClass,
                                                                                "Msvm_EthernetPortSettingDataComponent",
                                                                                null, null, null, null, false, null))
                                {
                                    if (featureSettingCollection.Count == 0)
                                    {
                                        continue;
                                    }

                                    foreach (ManagementObject featureSetting in featureSettingCollection)
                                    {
                                        using (featureSetting)
                                        {
                                            featureSettingPaths.Add(featureSetting.Path.Path);
                                        }
                                    }
                                }

                                using (ManagementBaseObject inParams =
                                           managementService.GetMethodParameters("RemoveFeatureSettings"))
                                {
                                    //
                                    // We specify which feature setting to remove by giving the WMI path to the feature setting object.
                                    //
                                    inParams["FeatureSettings"] = featureSettingPaths.ToArray();

                                    using (ManagementBaseObject outParams =
                                               managementService.InvokeMethod("RemoveFeatureSettings", inParams, null))
                                    {
                                        WmiUtilities.ValidateOutput(outParams, scope);
                                    }
                                }
                            }
                        }
                        finally
                        {
                            // Dispose of the connections.
                            foreach (ManagementObject ethernetConnectionSetting in connections)
                            {
                                ethernetConnectionSetting.Dispose();
                            }
                        }
                    }

            Console.WriteLine(string.Format(CultureInfo.CurrentCulture,
                                            "Successfully modified virtual machine '{0}' to remove advanced {2} settings from " +
                                            "each of its {1} connection(s).",
                                            virtualMachineName, connectionsCount, featureType.ToString()));
        }
        MoveExtension(
            string switchName,
            string extensionName,
            int offset)
        {
            ManagementScope scope = new ManagementScope(@"root\virtualization\v2");

            //
            // Get the switch we want to modify.
            //
            using (ManagementObject ethernetSwitch = NetworkingUtilities.FindEthernetSwitch(switchName, scope))

                //
                // To make modifications to the switch, we need to modify its configuration object.
                //
                using (ManagementObject ethernetSwitchSettings = WmiUtilities.GetFirstObjectFromCollection(
                           ethernetSwitch.GetRelated("Msvm_VirtualEthernetSwitchSettingData",
                                                     "Msvm_SettingsDefineState",
                                                     null, null, null, null, false, null)))
                {
                    string[] extensionOrder = (string[])ethernetSwitchSettings["ExtensionOrder"];
                    byte[]   extensionTypes = new byte[extensionOrder.Length];
                    int      extensionIndex = -1;

                    for (int idx = 0; idx < extensionOrder.Length; ++idx)
                    {
                        using (ManagementObject extension = new ManagementObject(extensionOrder[idx]))
                        {
                            extension.Get();

                            extensionTypes[idx] = (byte)extension["ExtensionType"];

                            if (String.Equals(
                                    (string)extension["ElementName"],
                                    extensionName,
                                    StringComparison.OrdinalIgnoreCase))
                            {
                                extensionIndex = idx;
                            }
                        }
                    }

                    if (extensionIndex == -1)
                    {
                        throw new ApplicationException(String.Format(
                                                           CultureInfo.CurrentCulture,
                                                           "Could not find extension '{0}' on switch '{1}'.",
                                                           extensionName,
                                                           switchName));
                    }

                    //
                    // Ensure that this is a valid move operation. The new extension index must
                    // be in range, and the extension cannot be interleaved with other extensions of
                    // a different type.
                    //
                    int newExtensionIndex = extensionIndex + offset;

                    if ((newExtensionIndex < 0) || (newExtensionIndex >= extensionOrder.Length))
                    {
                        throw new ApplicationException("Invalid move operation.");
                    }

                    if (extensionTypes[newExtensionIndex] != extensionTypes[extensionIndex])
                    {
                        throw new ApplicationException("Invalid move operation.");
                    }

                    //
                    // Reorder the extensions and apply the switch settings changes.
                    //
                    string temp = extensionOrder[newExtensionIndex];
                    extensionOrder[newExtensionIndex] = extensionOrder[extensionIndex];
                    extensionOrder[extensionIndex]    = temp;

                    ethernetSwitchSettings["ExtensionOrder"] = extensionOrder;

                    using (ManagementObject switchService = NetworkingUtilities.GetEthernetSwitchManagementService(scope))
                        using (ManagementBaseObject inParams = switchService.GetMethodParameters("ModifySystemSettings"))
                        {
                            inParams["SystemSettings"] = ethernetSwitchSettings.GetText(TextFormat.WmiDtd20);

                            using (ManagementBaseObject outParams =
                                       switchService.InvokeMethod("ModifySystemSettings", inParams, null))
                            {
                                WmiUtilities.ValidateOutput(outParams, scope);
                            }
                        }
                }

            Console.WriteLine(string.Format(
                                  CultureInfo.CurrentCulture,
                                  "Extension '{0}' was successfully reordered on switch '{1}'.",
                                  extensionName,
                                  switchName));
        }