// THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF // ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO // THE IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A // PARTICULAR PURPOSE. // // Copyright (c) Microsoft. All rights reserved. namespace Microsoft.Samples.HyperV.Networking { using System; using System.Management; using System.Globalization; using System.Collections.Generic; using Microsoft.Samples.HyperV.Common; static class AdvancedConnectionPropertiesSample { /// /// Adds a feature setting to all of the specified virtual machine's connections. /// /// The name of the virtual machine. /// The type of feature to add. static void 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())); } /// /// Modifies any security feature settings on the specified virtual machine's connections. /// /// The name of the virtual machine. static void 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())); } /// /// Finds and removes any feature settings of the specified type on the specified virtual machine's connections. /// /// The name of the virtual machine. /// The type of the feature to be removed. static void 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 featureSettingPaths = new List(); 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())); } /// /// Entry point for the advanced connection properties sample. /// /// The command line arguments. internal static void ExecuteSample( string[] args) { if (args.Length == 0 || args[0] == "/?") { Console.WriteLine("Usage: AdvancedConnectionProperties (Add|Modify|Remove) VmName FeatureType \n"); Console.WriteLine("If \"Add\" is specified we add a feature setting of the specified type for each"); Console.WriteLine("connection from the specified virtual machine"); Console.WriteLine("If \"Modify\" is specified we change a feature setting of the specified type for"); Console.WriteLine("each connection from the specified virtual machine"); Console.WriteLine("If \"Remove\" is specified we remove any feature settings of the specified type"); Console.WriteLine("from all connections from the specified virtual machine"); Console.WriteLine("Example: AdvancedConnectionProperties Add MyVirtualMachine Security"); return; } string type = args[0]; if (string.Equals(type, "add", StringComparison.CurrentCultureIgnoreCase)) { if (args.Length != 3) { Console.WriteLine("Must specify the virtual machine and the property type to add"); Console.WriteLine("(Acl, Security or Offload)\n"); Console.WriteLine("Example: AdvancedConnectionProperties Add MyVirtualMachine Security"); return; } else { NetworkingUtilities.PortFeatureType featureType; if (!Enum.TryParse(args[2].ToString(), true, out featureType) || (featureType != NetworkingUtilities.PortFeatureType.Acl && featureType != NetworkingUtilities.PortFeatureType.Offload && featureType != NetworkingUtilities.PortFeatureType.Security)) { Console.WriteLine("Valid property types to add are Acl, Security or Offload\n"); Console.WriteLine("Example: AdvancedConnectionProperties Add MyVirtualMachine Security"); return; } try { AddFeatureSettings(args[1], featureType); } catch (Exception ex) { Console.WriteLine("Failed to add feature settings. Error message details:\n"); Console.WriteLine(ex.Message); } } } else if (string.Equals(type, "modify", StringComparison.CurrentCultureIgnoreCase)) { if (args.Length != 3) { Console.WriteLine("Must specify the virtual machine and the property type to modify"); Console.WriteLine("(Security or Offload)\n"); Console.WriteLine("Example: AdvancedConnectionProperties Modify MyVirtualMachine Security"); return; } else { NetworkingUtilities.PortFeatureType featureType; if (!Enum.TryParse(args[2], true, out featureType) || (featureType != NetworkingUtilities.PortFeatureType.Offload && featureType != NetworkingUtilities.PortFeatureType.Security)) { Console.WriteLine("Valid property types to modify are Security or Offload.\n"); Console.WriteLine("Example: AdvancedConnectionProperties Remove MyVirtualMachine Security"); return; } try { ModifyFeatureSettings(args[1], featureType); } catch (Exception ex) { Console.WriteLine("Failed to modify security feature settings. Error message details:\n"); Console.WriteLine(ex.Message); } } } else if (string.Equals(type, "remove", StringComparison.CurrentCultureIgnoreCase)) { if (args.Length != 3) { Console.WriteLine("Must specify the virtual machine and the property type to remove"); Console.WriteLine("(Acl, Security or Offload)\n"); Console.WriteLine("Example: AdvancedConnectionProperties Remove MyVirtualMachine Security"); return; } else { NetworkingUtilities.PortFeatureType featureType; if (!Enum.TryParse(args[2], true, out featureType) || (featureType != NetworkingUtilities.PortFeatureType.Acl && featureType != NetworkingUtilities.PortFeatureType.Offload && featureType != NetworkingUtilities.PortFeatureType.Security)) { Console.WriteLine("Valid property types to remove are Acl, Security or Offload.\n"); Console.WriteLine("Example: AdvancedConnectionProperties Remove MyVirtualMachine Security"); return; } try { RemoveFeatureSettings(args[1], featureType); } catch (Exception ex) { Console.WriteLine("Failed to remove feature settings. Error message details:\n"); Console.WriteLine(ex.Message); } } } else { Console.WriteLine("First parameter must be \"add\", \"modify\", or \"remove\""); return; } } } }