通过 wmi 类 将 vlan 分配给网络适配器
Assign vlan to network adapter via wmi classes
问题: 无法使用 Msvm_VirtualEthernetSwitchManagementService 和 AddFeatureSettings 方法将 vlan 分配给 hyper-v 虚拟机。
谁能指出我做错了什么?
我还注意到,如果我使用 WMI 类 创建 vNIC,我不会获得 Msvm_EthernetPortAllocationSettingData 的实例,但如果我手动分配 vNIC,它就会被创建..我是也无法通过 WMI 创建 Msvm_EthernetPortAllocationSettingData。
从下面的代码中我得到 4096 的 ReturnValue,这意味着该方法已执行..但没有分配 vlan。
ManagementPath syntheticAdapterSettingDataC = new ManagementPath("Msvm_EthernetSwitchPortVlanSettingData");
String syntheticVlanAdapterId = String.Format("{0}\C\952C5004-4465-451C-8CB8-FA9AB382B773\{1}", adapter.GetPropertyValue("InstanceID"), Guid.NewGuid());
ManagementClass syntheticAdapterClassC =
new ManagementClass(scope, syntheticAdapterSettingDataC, objectOptions)
{
["AccessVlanId"] = 55,
["Caption"] = "Ethernet Switch Port VLAN Settings",
["Description"] = "Represents the vlan setting data.",
["ElementName"] = "Ethernet Switch Port VLAN Settings",
["InstanceID"] = syntheticVlanAdapterId,
["NativeVlanId"] = 0,
["OperationMode"] = 1,
["PrimaryVlanId"] = 0,
["PruneVlanIdArray"] = null,
["PvlanMode"] = 0,
["SecondaryVlanId"] = 0,
["SecondaryVlanIdArray"] = null,
["TrunkVlanIdArray"] = null,
};
var syntheticAdapterC = syntheticAdapterClassC.CreateInstance();
ManagementPath VirtualEthernetSwitchManagementServicePath= new ManagementPath("Msvm_VirtualEthernetSwitchManagementService");
ManagementClass VirtualEthernetSwitchManagementServiceClass = new ManagementClass(scope, VirtualEthernetSwitchManagementServicePath, objectOptions);
ManagementBaseObject inParams = VirtualEthernetSwitchManagementServiceClass.GetMethodParameters("AddFeatureSettings");
string queryFeature = string.Format("select * from Msvm_FeatureSettingData Where InstanceID = 'Microsoft:Definition\\952C5004-4465-451C-8CB8-FA9AB382B773\\Default'");
ManagementObjectSearcher searcherFeature = new ManagementObjectSearcher(scope, new ObjectQuery(queryFeature));
ManagementObjectCollection features = searcherFeature.Get();
ManagementObject feature = null;
foreach (ManagementObject instance in features)
{
feature = instance;
break;
}
string[] syntheticAdapterSettingsC = new string[1];
syntheticAdapterSettingsC[0] = syntheticAdapterC.GetText(TextFormat.CimDtd20);
inParams["AffectedConfiguration"] = feature.GetText(TextFormat.CimDtd20);
inParams["FeatureSettings"] = syntheticAdapterSettingsC;
ManagementObject service = null;
foreach (ManagementObject instance in VirtualEthernetSwitchManagementServiceClass.GetInstances())
{
service = instance;
}
ManagementBaseObject vlanOut = service.InvokeMethod("AddFeatureSettings", inParams, null);
经过试验,我找到了答案。你需要做的是创建(或者指向一个,如果你已经有一个) Msvm_EthernetPortAllocationSettingData 的实例 Msvm_VirtualSystemManagementService class 使用 "AddResourceSettings" 方法。
要使用 "AddResourceSettings" 方法,您需要定义:
- AffectedConfiguration 属性,它是 Msvm_VirtualSystemSettingData class
的一个实例
- ResourceSettings 属性,它是Msvm_EthernetPortAllocationSettingData的一个实例,但是你需要把这个实例放在数组中。
现在您可以分配 vlan 了。您需要使用 Msvm_VirtualSystemManagementService class 和 "AddFeatureSettings" 方法创建 Msvm_EthernetSwitchPortVlanSettingData 实例.
要使用 "AddFeatureSettings" 方法,您需要定义:
- AffectedConfiguration,它是 Msvm_EthernetPortAllocationSettingData
的一个实例
- FeatureSettings,它是Msvm_EthernetSwitchPortVlanSettingData的实例,也是数组
就是这样..
干杯!
ya..知道它有点老了,但是让其他试图实现它的人头疼。以下代码将网络适配器分配给 VM 并设置 VLAN。请记住,我的“_dataFields”是包含虚拟机数据的结构,因此您必须在此处更改一些内容。
添加新的网络适配器并设置 VLAN
/// <summary>
/// For the given virtual machine, this sample adds a new Network Adapter device and
/// connects it to the specified switch. Note that in order to add a new Network Adapter
/// device to the virtual machine, the virtual machine must be in the power off state.
/// Also note that the maximum number of Network Adapter devices that may be configured
/// on a virtual machine is 8.
/// </summary>
public void ConnectVmToSwitch()
{
using (ManagementObject managementService = WmiUtils.GetVirtualMachineManagementService(_dataFields._scope))
//
// Find the Ethernet switch we want to connect to.
//
using (ManagementObject ethernetSwitch = NetworkUtils.FindEthernetSwitch(_dataFields.SwitchName, _dataFields._scope))
//
// Find the virtual machine we want to connect.
//
using (ManagementObject virtualMachine = WmiUtils.GetVirtualMachine(_dataFields.VmName, _dataFields._scope))
//
// Get the virtual machine's settings object which is used to make configuration changes.
//
using (ManagementObject virtualMachineSettings = WmiUtils.GetVirtualMachineSettings(virtualMachine))
//
// Add a new synthetic Network Adapter device to the virtual machine.
//
using (ManagementObject syntheticAdapter = NetworkUtils.AddSyntheticAdapter(virtualMachine, _dataFields._scope))
//
// Now that we have added a network adapter to the virtual machine we can configure its
// connection settings.
//
using (ManagementObject connectionSettingsToAdd = NetworkUtils.GetDefaultEthernetPortAllocationSettingData(_dataFields._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))
{
WmiUtils.ValidateOutput(addConnectionOutParams, _dataFields._scope);
if (_dataFields.VlanID > 0)
{
string[] syntheticAdapterResult = (string[])addConnectionOutParams["ResultingResourceSettings"]; // Msvm_EthernetPortAllocationSettingData return object
string syntheticAdapterPath = syntheticAdapterResult[0]; // Msvm_EthernetPortAllocationSettingData path
using (ManagementClass vlanSettingsData = new ManagementClass("Msvm_EthernetSwitchPortVlanSettingData"))
{
vlanSettingsData.Scope = _dataFields._scope;
using (ManagementObject vlanData = vlanSettingsData.CreateInstance())
{
vlanData["AccessVlanId"] = _dataFields.VlanID;
vlanData["OperationMode"] = (uint)_dataFields.VLANOperationalModes;
// Modify the VM settings.
using (ManagementBaseObject inParams = managementService.GetMethodParameters("AddFeatureSettings"))
{
inParams["AffectedConfiguration"] = syntheticAdapterPath;
inParams["FeatureSettings"] = new string[] { vlanData.GetText(TextFormat.CimDtd20) };
using (ManagementBaseObject outParams = managementService.InvokeMethod("AddFeatureSettings", inParams, null))
{
WmiUtils.ValidateOutput(outParams, _dataFields._scope);
}
}
}
}
}
}
}
}
}
将交换机分配给 VM 的原始代码来自 https://github.com/microsoft/Windows-classic-samples/blob/1d363ff4bd17d8e20415b92e2ee989d615cc0d91/Samples/Hyper-V/Networking/cs/ConnectVmToSwitch.cs 我刚刚对其进行了扩展以支持 VLAN 使用。我在调用中没有任何参数,因为所有数据都在结构中。
在 VM 上的现有网络适配器上添加/修改 VLAN
/// <summary>
/// Gets any virtual machine's management object
/// </summary>
/// <param name="managementObject">Any management object</param>
/// <returns>Any virtual machine's management object.</returns>
public static ManagementObject
GetVirtualMachineManagementObject(ManagementObject managementObject, string className)
{
using (ManagementObjectCollection settingsCollection = managementObject.GetRelated(className))
{
ManagementObject virtualMachineSettings = GetFirstObjectFromCollection(settingsCollection);
return virtualMachineSettings;
}
}
/// <summary>
/// For the given virtual machine, this sample will add / modfiy VLAN on existing network adapter
/// </summary>
public void SetVLANToVMNetworkAdapter()
{
ManagementObject syntheticAdapter = null;
bool vlanAlreadySet = false;
using (ManagementObject managementService = WmiUtils.GetVirtualMachineManagementService(_dataFields._scope))
//
// Find the virtual machine we want to connect.
//
using (ManagementObject virtualMachine = WmiUtils.GetVirtualMachine(_dataFields.VmName, _dataFields._scope))
//
// Now that we have added a network adapter to the virtual machine we can configure its
// connection settings.
//
using (ManagementObjectCollection findConnections = NetworkUtils.FindConnections(virtualMachine, _dataFields._scope))
{
if (findConnections.Count > 0)
{
foreach (ManagementObject connection in findConnections)
{
using (ManagementObjectCollection vmSwitches = connection.GetRelated("Msvm_SyntheticEthernetPortSettingData"))
{
if (vmSwitches.Count > 0)
{
foreach (ManagementObject vmSwitch in vmSwitches)
{
if (vmSwitch["ElementName"].ToString() == _dataFields.NetworkAdapterName)
{
//
// Got adapter on VM, lock it to connection object since we need connection path
// for vlan modifications
//
syntheticAdapter = connection;
//
// Got VLAN defiinition based on connection lock for vlan modifications
//
using (ManagementObjectCollection vmSwitcheVLANs = syntheticAdapter.GetRelated("Msvm_EthernetSwitchPortVlanSettingData"))
{
if (vmSwitcheVLANs.Count > 0)
vlanAlreadySet = true;
}
break;
}
}
}
}
}
}
if (syntheticAdapter != null && _dataFields.VlanID > 0)
{
string syntheticAdapterPath = syntheticAdapter.Path.Path;
if (vlanAlreadySet)
{
// VLAN is already set on adapter, change operation
// Modify the VM settings.
using (ManagementObject vlanData = WmiUtils.GetVirtualMachineManagementObject(syntheticAdapter, "Msvm_EthernetSwitchPortVlanSettingData"))
{
vlanData["AccessVlanId"] = _dataFields.VlanID;
vlanData["OperationMode"] = (uint)_dataFields.VLANOperationalModes;
using (ManagementBaseObject inParams = managementService.GetMethodParameters("ModifyFeatureSettings"))
{
inParams["FeatureSettings"] = new string[] { vlanData.GetText(TextFormat.CimDtd20) };
using (ManagementBaseObject outParams = managementService.InvokeMethod("ModifyFeatureSettings", inParams, null))
{
WmiUtils.ValidateOutput(outParams, _dataFields._scope);
}
}
}
}
else
{
using (ManagementClass vlanSettingsData = new ManagementClass("Msvm_EthernetSwitchPortVlanSettingData"))
{
vlanSettingsData.Scope = _dataFields._scope;
using (ManagementObject vlanData = vlanSettingsData.CreateInstance())
{
vlanData["AccessVlanId"] = _dataFields.VlanID;
vlanData["OperationMode"] = (uint)_dataFields.VLANOperationalModes;
using (ManagementBaseObject inParams = managementService.GetMethodParameters("AddFeatureSettings"))
{
inParams["AffectedConfiguration"] = syntheticAdapterPath;
inParams["FeatureSettings"] = new string[] { vlanData.GetText(TextFormat.CimDtd20) };
using (ManagementBaseObject outParams = managementService.InvokeMethod("AddFeatureSettings", inParams, null))
{
WmiUtils.ValidateOutput(outParams, _dataFields._scope);
}
}
}
}
}
}
}
}
从 VM 上的网络适配器中删除 VLAN
/// <summary>
/// For the given virtual machine, this sample will delete VLAN on existing network adapter
/// </summary>
public void RemoveVLANFromVMNetworkAdapter()
{
using (ManagementObject managementService = WmiUtils.GetVirtualMachineManagementService(_dataFields._scope))
//
// Find the virtual machine we want to connect.
//
using (ManagementObject virtualMachine = WmiUtils.GetVirtualMachine(_dataFields.VmName, _dataFields._scope))
//
// Now that we have added a network adapter to the virtual machine we can configure its
// connection settings.
//
using (ManagementObjectCollection findConnections = NetworkUtils.FindConnections(virtualMachine, _dataFields._scope))
{
if (findConnections.Count > 0)
{
foreach (ManagementObject connection in findConnections)
{
// Get network adapter on virtual machine
using (ManagementObjectCollection vmSwitches = connection.GetRelated("Msvm_SyntheticEthernetPortSettingData"))
{
if (vmSwitches.Count > 0)
{
foreach (ManagementObject vmSwitch in vmSwitches)
{
if (vmSwitch["ElementName"].ToString() == _dataFields.NetworkAdapterName)
{
// Get vlan settings data from network adapter
using (ManagementObjectCollection vmSwitcheVLANs = connection.GetRelated("Msvm_EthernetSwitchPortVlanSettingData"))
{
if (vmSwitcheVLANs.Count > 0)
{
// Get first objecz
using (ManagementObject vlanData = WmiUtils.GetFirstObjectFromCollection(vmSwitcheVLANs))
{
using (ManagementBaseObject inParams = managementService.GetMethodParameters("RemoveFeatureSettings"))
{
// Remove it
inParams["FeatureSettings"] = new string[] { vlanData.Path.Path };
using (ManagementBaseObject outParams = managementService.InvokeMethod("RemoveFeatureSettings", inParams, null))
{
WmiUtils.ValidateOutput(outParams, _dataFields._scope);
}
}
}
}
}
}
}
}
}
}
}
}
}
请记住,我不使用通用网络适配器名称,我在创建 VM 时使用个性化名称。这样我就可以在需要时轻松获取适配器数据。
那些想要为适配器添加个性化名称的人可以编辑 AddSyntheticAdapter(ManagementObject virtualMachine, ManagementScope scope) 函数并在 adapterToAdd["ElementName"] 对象中包含不同的名称。
希望这对通过 WMI 开发的勇敢的灵魂有所帮助! :)
问题: 无法使用 Msvm_VirtualEthernetSwitchManagementService 和 AddFeatureSettings 方法将 vlan 分配给 hyper-v 虚拟机。
谁能指出我做错了什么?
我还注意到,如果我使用 WMI 类 创建 vNIC,我不会获得 Msvm_EthernetPortAllocationSettingData 的实例,但如果我手动分配 vNIC,它就会被创建..我是也无法通过 WMI 创建 Msvm_EthernetPortAllocationSettingData。
从下面的代码中我得到 4096 的 ReturnValue,这意味着该方法已执行..但没有分配 vlan。
ManagementPath syntheticAdapterSettingDataC = new ManagementPath("Msvm_EthernetSwitchPortVlanSettingData");
String syntheticVlanAdapterId = String.Format("{0}\C\952C5004-4465-451C-8CB8-FA9AB382B773\{1}", adapter.GetPropertyValue("InstanceID"), Guid.NewGuid());
ManagementClass syntheticAdapterClassC =
new ManagementClass(scope, syntheticAdapterSettingDataC, objectOptions)
{
["AccessVlanId"] = 55,
["Caption"] = "Ethernet Switch Port VLAN Settings",
["Description"] = "Represents the vlan setting data.",
["ElementName"] = "Ethernet Switch Port VLAN Settings",
["InstanceID"] = syntheticVlanAdapterId,
["NativeVlanId"] = 0,
["OperationMode"] = 1,
["PrimaryVlanId"] = 0,
["PruneVlanIdArray"] = null,
["PvlanMode"] = 0,
["SecondaryVlanId"] = 0,
["SecondaryVlanIdArray"] = null,
["TrunkVlanIdArray"] = null,
};
var syntheticAdapterC = syntheticAdapterClassC.CreateInstance();
ManagementPath VirtualEthernetSwitchManagementServicePath= new ManagementPath("Msvm_VirtualEthernetSwitchManagementService");
ManagementClass VirtualEthernetSwitchManagementServiceClass = new ManagementClass(scope, VirtualEthernetSwitchManagementServicePath, objectOptions);
ManagementBaseObject inParams = VirtualEthernetSwitchManagementServiceClass.GetMethodParameters("AddFeatureSettings");
string queryFeature = string.Format("select * from Msvm_FeatureSettingData Where InstanceID = 'Microsoft:Definition\\952C5004-4465-451C-8CB8-FA9AB382B773\\Default'");
ManagementObjectSearcher searcherFeature = new ManagementObjectSearcher(scope, new ObjectQuery(queryFeature));
ManagementObjectCollection features = searcherFeature.Get();
ManagementObject feature = null;
foreach (ManagementObject instance in features)
{
feature = instance;
break;
}
string[] syntheticAdapterSettingsC = new string[1];
syntheticAdapterSettingsC[0] = syntheticAdapterC.GetText(TextFormat.CimDtd20);
inParams["AffectedConfiguration"] = feature.GetText(TextFormat.CimDtd20);
inParams["FeatureSettings"] = syntheticAdapterSettingsC;
ManagementObject service = null;
foreach (ManagementObject instance in VirtualEthernetSwitchManagementServiceClass.GetInstances())
{
service = instance;
}
ManagementBaseObject vlanOut = service.InvokeMethod("AddFeatureSettings", inParams, null);
经过试验,我找到了答案。你需要做的是创建(或者指向一个,如果你已经有一个) Msvm_EthernetPortAllocationSettingData 的实例 Msvm_VirtualSystemManagementService class 使用 "AddResourceSettings" 方法。
要使用 "AddResourceSettings" 方法,您需要定义:
- AffectedConfiguration 属性,它是 Msvm_VirtualSystemSettingData class 的一个实例
- ResourceSettings 属性,它是Msvm_EthernetPortAllocationSettingData的一个实例,但是你需要把这个实例放在数组中。
现在您可以分配 vlan 了。您需要使用 Msvm_VirtualSystemManagementService class 和 "AddFeatureSettings" 方法创建 Msvm_EthernetSwitchPortVlanSettingData 实例.
要使用 "AddFeatureSettings" 方法,您需要定义:
- AffectedConfiguration,它是 Msvm_EthernetPortAllocationSettingData 的一个实例
- FeatureSettings,它是Msvm_EthernetSwitchPortVlanSettingData的实例,也是数组
就是这样..
干杯!
ya..知道它有点老了,但是让其他试图实现它的人头疼。以下代码将网络适配器分配给 VM 并设置 VLAN。请记住,我的“_dataFields”是包含虚拟机数据的结构,因此您必须在此处更改一些内容。
添加新的网络适配器并设置 VLAN
/// <summary>
/// For the given virtual machine, this sample adds a new Network Adapter device and
/// connects it to the specified switch. Note that in order to add a new Network Adapter
/// device to the virtual machine, the virtual machine must be in the power off state.
/// Also note that the maximum number of Network Adapter devices that may be configured
/// on a virtual machine is 8.
/// </summary>
public void ConnectVmToSwitch()
{
using (ManagementObject managementService = WmiUtils.GetVirtualMachineManagementService(_dataFields._scope))
//
// Find the Ethernet switch we want to connect to.
//
using (ManagementObject ethernetSwitch = NetworkUtils.FindEthernetSwitch(_dataFields.SwitchName, _dataFields._scope))
//
// Find the virtual machine we want to connect.
//
using (ManagementObject virtualMachine = WmiUtils.GetVirtualMachine(_dataFields.VmName, _dataFields._scope))
//
// Get the virtual machine's settings object which is used to make configuration changes.
//
using (ManagementObject virtualMachineSettings = WmiUtils.GetVirtualMachineSettings(virtualMachine))
//
// Add a new synthetic Network Adapter device to the virtual machine.
//
using (ManagementObject syntheticAdapter = NetworkUtils.AddSyntheticAdapter(virtualMachine, _dataFields._scope))
//
// Now that we have added a network adapter to the virtual machine we can configure its
// connection settings.
//
using (ManagementObject connectionSettingsToAdd = NetworkUtils.GetDefaultEthernetPortAllocationSettingData(_dataFields._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))
{
WmiUtils.ValidateOutput(addConnectionOutParams, _dataFields._scope);
if (_dataFields.VlanID > 0)
{
string[] syntheticAdapterResult = (string[])addConnectionOutParams["ResultingResourceSettings"]; // Msvm_EthernetPortAllocationSettingData return object
string syntheticAdapterPath = syntheticAdapterResult[0]; // Msvm_EthernetPortAllocationSettingData path
using (ManagementClass vlanSettingsData = new ManagementClass("Msvm_EthernetSwitchPortVlanSettingData"))
{
vlanSettingsData.Scope = _dataFields._scope;
using (ManagementObject vlanData = vlanSettingsData.CreateInstance())
{
vlanData["AccessVlanId"] = _dataFields.VlanID;
vlanData["OperationMode"] = (uint)_dataFields.VLANOperationalModes;
// Modify the VM settings.
using (ManagementBaseObject inParams = managementService.GetMethodParameters("AddFeatureSettings"))
{
inParams["AffectedConfiguration"] = syntheticAdapterPath;
inParams["FeatureSettings"] = new string[] { vlanData.GetText(TextFormat.CimDtd20) };
using (ManagementBaseObject outParams = managementService.InvokeMethod("AddFeatureSettings", inParams, null))
{
WmiUtils.ValidateOutput(outParams, _dataFields._scope);
}
}
}
}
}
}
}
}
}
将交换机分配给 VM 的原始代码来自 https://github.com/microsoft/Windows-classic-samples/blob/1d363ff4bd17d8e20415b92e2ee989d615cc0d91/Samples/Hyper-V/Networking/cs/ConnectVmToSwitch.cs 我刚刚对其进行了扩展以支持 VLAN 使用。我在调用中没有任何参数,因为所有数据都在结构中。
在 VM 上的现有网络适配器上添加/修改 VLAN
/// <summary>
/// Gets any virtual machine's management object
/// </summary>
/// <param name="managementObject">Any management object</param>
/// <returns>Any virtual machine's management object.</returns>
public static ManagementObject
GetVirtualMachineManagementObject(ManagementObject managementObject, string className)
{
using (ManagementObjectCollection settingsCollection = managementObject.GetRelated(className))
{
ManagementObject virtualMachineSettings = GetFirstObjectFromCollection(settingsCollection);
return virtualMachineSettings;
}
}
/// <summary>
/// For the given virtual machine, this sample will add / modfiy VLAN on existing network adapter
/// </summary>
public void SetVLANToVMNetworkAdapter()
{
ManagementObject syntheticAdapter = null;
bool vlanAlreadySet = false;
using (ManagementObject managementService = WmiUtils.GetVirtualMachineManagementService(_dataFields._scope))
//
// Find the virtual machine we want to connect.
//
using (ManagementObject virtualMachine = WmiUtils.GetVirtualMachine(_dataFields.VmName, _dataFields._scope))
//
// Now that we have added a network adapter to the virtual machine we can configure its
// connection settings.
//
using (ManagementObjectCollection findConnections = NetworkUtils.FindConnections(virtualMachine, _dataFields._scope))
{
if (findConnections.Count > 0)
{
foreach (ManagementObject connection in findConnections)
{
using (ManagementObjectCollection vmSwitches = connection.GetRelated("Msvm_SyntheticEthernetPortSettingData"))
{
if (vmSwitches.Count > 0)
{
foreach (ManagementObject vmSwitch in vmSwitches)
{
if (vmSwitch["ElementName"].ToString() == _dataFields.NetworkAdapterName)
{
//
// Got adapter on VM, lock it to connection object since we need connection path
// for vlan modifications
//
syntheticAdapter = connection;
//
// Got VLAN defiinition based on connection lock for vlan modifications
//
using (ManagementObjectCollection vmSwitcheVLANs = syntheticAdapter.GetRelated("Msvm_EthernetSwitchPortVlanSettingData"))
{
if (vmSwitcheVLANs.Count > 0)
vlanAlreadySet = true;
}
break;
}
}
}
}
}
}
if (syntheticAdapter != null && _dataFields.VlanID > 0)
{
string syntheticAdapterPath = syntheticAdapter.Path.Path;
if (vlanAlreadySet)
{
// VLAN is already set on adapter, change operation
// Modify the VM settings.
using (ManagementObject vlanData = WmiUtils.GetVirtualMachineManagementObject(syntheticAdapter, "Msvm_EthernetSwitchPortVlanSettingData"))
{
vlanData["AccessVlanId"] = _dataFields.VlanID;
vlanData["OperationMode"] = (uint)_dataFields.VLANOperationalModes;
using (ManagementBaseObject inParams = managementService.GetMethodParameters("ModifyFeatureSettings"))
{
inParams["FeatureSettings"] = new string[] { vlanData.GetText(TextFormat.CimDtd20) };
using (ManagementBaseObject outParams = managementService.InvokeMethod("ModifyFeatureSettings", inParams, null))
{
WmiUtils.ValidateOutput(outParams, _dataFields._scope);
}
}
}
}
else
{
using (ManagementClass vlanSettingsData = new ManagementClass("Msvm_EthernetSwitchPortVlanSettingData"))
{
vlanSettingsData.Scope = _dataFields._scope;
using (ManagementObject vlanData = vlanSettingsData.CreateInstance())
{
vlanData["AccessVlanId"] = _dataFields.VlanID;
vlanData["OperationMode"] = (uint)_dataFields.VLANOperationalModes;
using (ManagementBaseObject inParams = managementService.GetMethodParameters("AddFeatureSettings"))
{
inParams["AffectedConfiguration"] = syntheticAdapterPath;
inParams["FeatureSettings"] = new string[] { vlanData.GetText(TextFormat.CimDtd20) };
using (ManagementBaseObject outParams = managementService.InvokeMethod("AddFeatureSettings", inParams, null))
{
WmiUtils.ValidateOutput(outParams, _dataFields._scope);
}
}
}
}
}
}
}
}
从 VM 上的网络适配器中删除 VLAN
/// <summary>
/// For the given virtual machine, this sample will delete VLAN on existing network adapter
/// </summary>
public void RemoveVLANFromVMNetworkAdapter()
{
using (ManagementObject managementService = WmiUtils.GetVirtualMachineManagementService(_dataFields._scope))
//
// Find the virtual machine we want to connect.
//
using (ManagementObject virtualMachine = WmiUtils.GetVirtualMachine(_dataFields.VmName, _dataFields._scope))
//
// Now that we have added a network adapter to the virtual machine we can configure its
// connection settings.
//
using (ManagementObjectCollection findConnections = NetworkUtils.FindConnections(virtualMachine, _dataFields._scope))
{
if (findConnections.Count > 0)
{
foreach (ManagementObject connection in findConnections)
{
// Get network adapter on virtual machine
using (ManagementObjectCollection vmSwitches = connection.GetRelated("Msvm_SyntheticEthernetPortSettingData"))
{
if (vmSwitches.Count > 0)
{
foreach (ManagementObject vmSwitch in vmSwitches)
{
if (vmSwitch["ElementName"].ToString() == _dataFields.NetworkAdapterName)
{
// Get vlan settings data from network adapter
using (ManagementObjectCollection vmSwitcheVLANs = connection.GetRelated("Msvm_EthernetSwitchPortVlanSettingData"))
{
if (vmSwitcheVLANs.Count > 0)
{
// Get first objecz
using (ManagementObject vlanData = WmiUtils.GetFirstObjectFromCollection(vmSwitcheVLANs))
{
using (ManagementBaseObject inParams = managementService.GetMethodParameters("RemoveFeatureSettings"))
{
// Remove it
inParams["FeatureSettings"] = new string[] { vlanData.Path.Path };
using (ManagementBaseObject outParams = managementService.InvokeMethod("RemoveFeatureSettings", inParams, null))
{
WmiUtils.ValidateOutput(outParams, _dataFields._scope);
}
}
}
}
}
}
}
}
}
}
}
}
}
请记住,我不使用通用网络适配器名称,我在创建 VM 时使用个性化名称。这样我就可以在需要时轻松获取适配器数据。
那些想要为适配器添加个性化名称的人可以编辑 AddSyntheticAdapter(ManagementObject virtualMachine, ManagementScope scope) 函数并在 adapterToAdd["ElementName"] 对象中包含不同的名称。
希望这对通过 WMI 开发的勇敢的灵魂有所帮助! :)