Best way to programmatically configure network adapters in .NET - c#

I have an application written in C# that needs to be able to configure the network adapters in Windows. I have this basically working through WMI, but there are a couple of things I don't like about that solution: sometimes the settings don't seem to stick, and when the network cable is not plugged in, errors are returned from the WMI methods, so I can't tell if they really succeeded or not.
I need to be able to configure all of the settings available through the network connections - Properties - TCP/IP screens.
What's the best way to do this?

You could use Process to fire off netsh commands to set all the properties in the network dialogs.
eg:
To set a static ipaddress on an adapter
netsh interface ip set address "Local Area Connection" static 192.168.0.10 255.255.255.0 192.168.0.1 1
To set it to dhcp you'd use
netsh interface ip set address "Local Area Connection" dhcp
To do it from C# would be
Process p = new Process();
ProcessStartInfo psi = new ProcessStartInfo("netsh", "interface ip set address \"Local Area Connection\" static 192.168.0.10 255.255.255.0 192.168.0.1 1");
p.StartInfo = psi;
p.Start();
Setting to static can take a good couple of seconds to complete so if you need to, make sure you wait for the process to exit.

With my code
SetIpAddress and SetDHCP
/// <summary>
/// Sets the ip address.
/// </summary>
/// <param name="nicName">Name of the nic.</param>
/// <param name="ipAddress">The ip address.</param>
/// <param name="subnetMask">The subnet mask.</param>
/// <param name="gateway">The gateway.</param>
/// <param name="dns1">The DNS1.</param>
/// <param name="dns2">The DNS2.</param>
/// <returns></returns>
public static bool SetIpAddress(
string nicName,
string ipAddress,
string subnetMask,
string gateway = null,
string dns1 = null,
string dns2 = null)
{
ManagementClass mc = new ManagementClass("Win32_NetworkAdapterConfiguration");
ManagementObjectCollection moc = mc.GetInstances();
NetworkInterface[] interfaces = NetworkInterface.GetAllNetworkInterfaces();
NetworkInterface networkInterface = interfaces.FirstOrDefault(x => x.Name == nicName);
string nicDesc = nicName;
if (networkInterface != null)
{
nicDesc = networkInterface.Description;
}
foreach (ManagementObject mo in moc)
{
if ((bool)mo["IPEnabled"] == true
&& mo["Description"].Equals(nicDesc) == true)
{
try
{
ManagementBaseObject newIP = mo.GetMethodParameters("EnableStatic");
newIP["IPAddress"] = new string[] { ipAddress };
newIP["SubnetMask"] = new string[] { subnetMask };
ManagementBaseObject setIP = mo.InvokeMethod("EnableStatic", newIP, null);
if (gateway != null)
{
ManagementBaseObject newGateway = mo.GetMethodParameters("SetGateways");
newGateway["DefaultIPGateway"] = new string[] { gateway };
newGateway["GatewayCostMetric"] = new int[] { 1 };
ManagementBaseObject setGateway = mo.InvokeMethod("SetGateways", newGateway, null);
}
if (dns1 != null || dns2 != null)
{
ManagementBaseObject newDns = mo.GetMethodParameters("SetDNSServerSearchOrder");
var dns = new List<string>();
if (dns1 != null)
{
dns.Add(dns1);
}
if (dns2 != null)
{
dns.Add(dns2);
}
newDns["DNSServerSearchOrder"] = dns.ToArray();
ManagementBaseObject setDNS = mo.InvokeMethod("SetDNSServerSearchOrder", newDns, null);
}
}
catch
{
return false;
}
}
}
return true;
}
/// <summary>
/// Sets the DHCP.
/// </summary>
/// <param name="nicName">Name of the nic.</param>
public static bool SetDHCP(string nicName)
{
ManagementClass mc = new ManagementClass("Win32_NetworkAdapterConfiguration");
ManagementObjectCollection moc = mc.GetInstances();
NetworkInterface[] interfaces = NetworkInterface.GetAllNetworkInterfaces();
NetworkInterface networkInterface = interfaces.FirstOrDefault(x => x.Name == nicName);
string nicDesc = nicName;
if (networkInterface != null)
{
nicDesc = networkInterface.Description;
}
foreach (ManagementObject mo in moc)
{
if ((bool)mo["IPEnabled"] == true
&& mo["Description"].Equals(nicDesc) == true)
{
try
{
ManagementBaseObject newDNS = mo.GetMethodParameters("SetDNSServerSearchOrder");
newDNS["DNSServerSearchOrder"] = null;
ManagementBaseObject enableDHCP = mo.InvokeMethod("EnableDHCP", null, null);
ManagementBaseObject setDNS = mo.InvokeMethod("SetDNSServerSearchOrder", newDNS, null);
}
catch
{
return false;
}
}
}
return true;
}

with the help of #PaulB's answers help
NetworkInterface[] nics = NetworkInterface.GetAllNetworkInterfaces();
Process p = new Process();
ProcessStartInfo psi = new ProcessStartInfo("netsh", "interface ip set address " + nics[0].Name + " static 192.168." + provider_ip + "." + index + " 255.255.255.0 192.168." + provider_ip + ".1 1");
p.StartInfo = psi;
p.StartInfo.Verb = "runas";
p.Start();

I can tell you the way the trojans do it, after having had to clean up after a few of them, is to set registry keys under HKEY_LOCAL_MACHINE. The main ones they set are the DNS ones and that approach definitely sticks which can be attested to by anyone who has ever been infected and can no longer get to windowsupdate.com, mcafee.com, etc.

Checkout this app. it is a complete application to set both wifi and ethernet ips
https://github.com/kamran7679/ConfigureIP

Related

some problems about modify IP address with System.Management(WMI)

I want to know the meaning of "ManagementObject" returnValue, such as '2147947410'.
Does C# have any other options to modify IP address, except through WMI?
How to prevent windows change IP address to 169.254.XXX, when it detect IP conflict?
Before run the code, I modify one network's IP address to 192.168.1.66(not my targe network). [Fig.1]
Then run the code , it would not throw any exceptions, outPar["returnValue"] returns value 2147947410, but if I open target network's opions, the IP address is blank! [Fig.2]
And, if type "ipconfig" in CMD, I will see the target network's IP is 169.254.XXX. I know that means "ip conflict". [Fig.2]
Below is the code.
static void Main(string[] args)
{
// Run Code in Admin mode.
ManagementBaseObject inPar = null;
ManagementBaseObject outPar = null;
ManagementClass mc = new ManagementClass("Win32_NetworkAdapterConfiguration");
ManagementObjectCollection moc = mc.GetInstances();
foreach (ManagementObject mo in moc)
{
if (!(bool)mo["IPEnabled"])
continue;
string[] addresses = (string[])mo["IPAddress"];
Console.WriteLine("开始修改");
try
{
//设置ip地址和子网掩码 
inPar = mo.GetMethodParameters("EnableStatic");
inPar["IPAddress"] = new string[] { "192.168.1.66" };
inPar["SubnetMask"] = new string[] { "255.255.255.0" };
outPar = mo.InvokeMethod("EnableStatic", inPar, null);
Console.WriteLine(outPar["returnValue"]);
//设置网关地址 
inPar = mo.GetMethodParameters("SetGateways");
inPar["DefaultIPGateway"] = new string[] { "0.0.0.0" };
outPar = mo.InvokeMethod("SetGateways", inPar, null);
}
catch (Exception e)
{
throw e;
}
//设置DNS 
inPar = mo.GetMethodParameters("SetDNSServerSearchOrder");
inPar["DNSServerSearchOrder"] = new string[] { "0.0.0.0" };
outPar = mo.InvokeMethod("SetDNSServerSearchOrder", inPar, null);
break;
}
Console.ReadLine();
}

C# DHCP will not change for interfaces that are disconnected

I'm having an issue where my code is setting Static IP and DHCP perfectly fine when I'm connected to the WiFi. However, the Ethernet "local networkinterface" is unchangable, when no cable is connected. The issue is vice-versa for when connected with cable, and trying to set the WiFi interface.
The issue seem to only be present when the interface is disconnected and have no live connection. Anyone else able to reproduce? innput nicName is the name of interface I'm sending from my Form, and is basically used for matching it to the interfaceI want to change
Set StaticIP:
public static bool SetStaticIp(
string nicName,
Object objSite )
{
Site site = (Site)objSite;
//string nicName = adapter.Description;
string ipAddress = $"{site.IP}";
string subnetMask = $"{site.SubnetMask}";
string gateway = $"{site.Gateway}";
string dns1 = $"{site.Dns1}";
string dns2 = $"{site.Dns2}";
ManagementClass mc = new ManagementClass("Win32_NetworkAdapterConfiguration");
ManagementObjectCollection moc = mc.GetInstances();
NetworkInterface[] interfaces = NetworkInterface.GetAllNetworkInterfaces();
NetworkInterface networkInterface = interfaces.FirstOrDefault(x => x.Name == nicName);
string nicDesc = nicName;
if (networkInterface != null)
{
nicDesc = networkInterface.Description;
}
foreach (ManagementObject mo in moc)
{
bool moIpEnable = (bool)mo["IPEnabled"];
string moDesc = (string)mo["Description"];
if (moDesc.Equals(nicName) == true)
{
try
{
ManagementBaseObject newIP = mo.GetMethodParameters("EnableStatic");
newIP["IPAddress"] = new string[] { ipAddress };
newIP["SubnetMask"] = new string[] { subnetMask };
ManagementBaseObject setIP = mo.InvokeMethod("EnableStatic", newIP, null);
if (gateway != null)
{
ManagementBaseObject newGateway = mo.GetMethodParameters("SetGateways");
newGateway["DefaultIPGateway"] = new string[] { gateway };
newGateway["GatewayCostMetric"] = new int[] { 1 };
ManagementBaseObject setGateway = mo.InvokeMethod("SetGateways", newGateway, null);
}
if (dns1 != null || dns2 != null)
{
ManagementBaseObject newDns = mo.GetMethodParameters("SetDNSServerSearchOrder");
var dns = new List<string>();
if (dns1 != null)
{
dns.Add(dns1);
}
if (dns2 != null)
{
dns.Add(dns2);
}
newDns["DNSServerSearchOrder"] = dns.ToArray();
ManagementBaseObject setDNS = mo.InvokeMethod("SetDNSServerSearchOrder", newDns, null);
}
}
catch (Exception err)
{
Log(LOG_FN.ERROR, $"SetStaticIp({nicDesc}): Klarte ikke sette statisk IP. {err.Message}");
return false;
}
}
}
return true;
}
Set DHCP
public static int SetDHCP(string nicName)
{
//string nicName = sroGlobal.SelectedAdapters.Description;
//string nicName = Name;
ManagementClass mc = new ManagementClass("Win32_NetworkAdapterConfiguration");
ManagementObjectCollection moc = mc.GetInstances();
NetworkInterface[] interfaces = NetworkInterface.GetAllNetworkInterfaces();
NetworkInterface networkInterface = interfaces.FirstOrDefault(x => x.Name == nicName);
ManagementObjectCollection networkCollection = mc.GetInstances();
string nicDesc = nicName;
if (networkInterface != null)
{
nicDesc = networkInterface.Description;
}
foreach (ManagementObject mo in networkCollection)
{
bool moIpEnable = (bool)mo["IPEnabled"];
string moDesc = (string)mo["Description"];
if (string.Compare(moDesc, nicName,StringComparison.InvariantCultureIgnoreCase) == 0)
{
try
{
ManagementBaseObject newDNS = mo.GetMethodParameters("SetDNSServerSearchOrder");
newDNS["DNSServerSearchOrder"] = null;
ManagementBaseObject enableDHCP = mo.InvokeMethod("EnableDHCP", null, null);
ManagementBaseObject setDNS = mo.InvokeMethod("SetDNSServerSearchOrder", newDNS, null);
return 1;
}
catch (Exception err)
{
Log(LOG_FN.ERROR, $"SetDHCP({nicDesc}): Could'nt set DHCP. {err.Message}");
return -1;
}
}
}
return 0;
}
edit 1: format error

Assign vlan to network adapter via wmi classes

Problem : Can't assign vlan to hyper-v virtual machine using Msvm_VirtualEthernetSwitchManagementService, and AddFeatureSettings method.
Can someone point me what am I doing wrong?
Also I've noticed that if I use WMI classes to create vNIC I'm not getting instance of Msvm_EthernetPortAllocationSettingData, but if I assign vNIC manually it get's created.. I'm having trouble with creating Msvm_EthernetPortAllocationSettingData via WMI also.
From code bellow I'm getting ReturnValue of 4096, which means that method was executed.. but no vlan was assigned.
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);
After experimenting I've found an answer. What you need to do is create (or point to one if you have one already) instance of Msvm_EthernetPortAllocationSettingData with Msvm_VirtualSystemManagementService class using "AddResourceSettings" method.
To use "AddResourceSettings" method you will need to define :
AffectedConfiguration property, which is an instance of Msvm_VirtualSystemSettingData class
ResourceSettings property, which is an instance of Msvm_EthernetPortAllocationSettingData, but you need to put this instance in array.
Now you are ready to assign vlan. You will need to create instance of Msvm_EthernetSwitchPortVlanSettingData with Msvm_VirtualSystemManagementService class and "AddFeatureSettings" method.
To use "AddFeatureSettings" method you will need to define :
AffectedConfiguration, which is an instance of Msvm_EthernetPortAllocationSettingData
FeatureSettings, which is an instance of Msvm_EthernetSwitchPortVlanSettingData, which is also array
And that is that..
Cheers!
ya..know its kinda old, but lets save headache of other people trying to implement this. Following code will assign Network Adapter to a VM and set VLAN. Keep in mind, my '_dataFields' is struct with virtual machine data, so you will have to change few things here.
Add new Network Adapter and set 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);
}
}
}
}
}
}
}
}
}
Original code for assigning switch to the VM is from https://github.com/microsoft/Windows-classic-samples/blob/1d363ff4bd17d8e20415b92e2ee989d615cc0d91/Samples/Hyper-V/Networking/cs/ConnectVmToSwitch.cs i've just extended it to support VLAN usage. I dont have any parameters in call, since all data is in struct.
Add / Modify VLAN on existing network adapter on VM
/// <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);
}
}
}
}
}
}
}
}
Delete VLAN from network adapter on VM
/// <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);
}
}
}
}
}
}
}
}
}
}
}
}
}
Keep in mind, i don't use general network adapter name, i'm using personalized ones when VM is being created. This way i can easily get adapter data when required.
Those who want to add personalized names for adapters can edit AddSyntheticAdapter(ManagementObject virtualMachine, ManagementScope scope) function and include different name in adapterToAdd["ElementName"] object.
Hope this helps to brave souls who are developing via WMI! :)

How to Change DNS with C# on Windows 10

I'm trying to change the DNS on Windows 10 through VB.NET.
I have code that works on Windows 7, however it does not work on Windows 10.
Here is my code for Windows 7 that changes the DNS:
ManagementClass mc = new ManagementClass("Win32_NetworkAdapterConfiguration");
ManagementObjectCollection moc = mc.GetInstances();
foreach (ManagementObject mo in moc)
{
if ((bool)mo["IPEnabled"])
{
ManagementBaseObject objdns = mo.GetMethodParameters("SetDNSServerSearchOrder");
if (objdns != null)
{
string[] s = { "192.168.XX.X", "XXX.XX.X.XX" };
objdns["DNSServerSearchOrder"] = s;
mo.InvokeMethod("SetDNSServerSearchOrder", objdns, null);
My question is, how do I get this to work on Windows 10 OS?
First you need to get the NetworkInterface you want to set/unset DNS
I've tested this code on the latest version of Windows 10 and it works like a charm!
Here is the code to find the active Ethernet or Wifi network (Not 100% accurate but useful in most cases)
public static NetworkInterface GetActiveEthernetOrWifiNetworkInterface()
{
var Nic = NetworkInterface.GetAllNetworkInterfaces().FirstOrDefault(
a => a.OperationalStatus == OperationalStatus.Up &&
(a.NetworkInterfaceType == NetworkInterfaceType.Wireless80211 || a.NetworkInterfaceType == NetworkInterfaceType.Ethernet) &&
a.GetIPProperties().GatewayAddresses.Any(g => g.Address.AddressFamily.ToString() == "InterNetwork"));
return Nic;
}
SetDNS
public static void SetDNS(string DnsString)
{
string[] Dns = { DnsString };
var CurrentInterface = GetActiveEthernetOrWifiNetworkInterface();
if (CurrentInterface == null) return;
ManagementClass objMC = new ManagementClass("Win32_NetworkAdapterConfiguration");
ManagementObjectCollection objMOC = objMC.GetInstances();
foreach (ManagementObject objMO in objMOC)
{
if ((bool)objMO["IPEnabled"])
{
if (objMO["Description"].ToString().Equals(CurrentInterface.Description))
{
ManagementBaseObject objdns = objMO.GetMethodParameters("SetDNSServerSearchOrder");
if (objdns != null)
{
objdns["DNSServerSearchOrder"] = Dns;
objMO.InvokeMethod("SetDNSServerSearchOrder", objdns, null);
}
}
}
}
}
UnsetDNS
public static void UnsetDNS()
{
var CurrentInterface = GetActiveEthernetOrWifiNetworkInterface();
if (CurrentInterface == null) return;
ManagementClass objMC = new ManagementClass("Win32_NetworkAdapterConfiguration");
ManagementObjectCollection objMOC = objMC.GetInstances();
foreach (ManagementObject objMO in objMOC)
{
if ((bool)objMO["IPEnabled"])
{
if (objMO["Description"].ToString().Equals(CurrentInterface.Description))
{
ManagementBaseObject objdns = objMO.GetMethodParameters("SetDNSServerSearchOrder");
if (objdns != null)
{
objdns["DNSServerSearchOrder"] = null;
objMO.InvokeMethod("SetDNSServerSearchOrder", objdns, null);
}
}
}
}
}
Usage
SetDNS("127.0.0.1");
Combining multiple solutions I found that the following code is working great for Windows 10 and 8.1 (others not tested, but should work as well):
public static void setDNS(string NIC, string DNS)
{
ConnectionOptions options = PrepareOptions();
ManagementScope scope = PrepareScope(Environment.MachineName, options, #"\root\CIMV2");
ManagementPath managementPath = new ManagementPath("Win32_NetworkAdapterConfiguration");
ObjectGetOptions objectGetOptions = new ObjectGetOptions();
ManagementClass mc = new ManagementClass(scope, managementPath, objectGetOptions);
ManagementObjectCollection moc = mc.GetInstances();
foreach (ManagementObject mo in moc)
{
if ((bool)mo["IPEnabled"])
{
if (mo["Caption"].ToString().Contains(NIC))
{
try
{
ManagementBaseObject newDNS = mo.GetMethodParameters("SetDNSServerSearchOrder");
newDNS["DNSServerSearchOrder"] = DNS.Split(',');
ManagementBaseObject setDNS = mo.InvokeMethod("SetDNSServerSearchOrder", newDNS, null);
}
catch (Exception e)
{
Console.WriteLine(e.ToString());
Console.ReadKey();
throw;
}
}
}
}
}
The application needs to run with elevated permissions (in my case I'm starting an elevated process running an .exe):
private void callSwapDNS(string NIC, string DNS)
{
const int ERROR_CANCELLED = 1223; //The operation was canceled by the user.
ProcessStartInfo info = new ProcessStartInfo(#"swap.exe");
string wrapped = string.Format(#"""{0}"" ""{1}""", NIC, DNS);
info.Arguments = wrapped;
info.UseShellExecute = true;
info.Verb = "runas";
info.WindowStyle = ProcessWindowStyle.Hidden;
try
{
Process.Start(info);
Thread.Sleep(500);
}
catch (Win32Exception ex)
{
if (ex.NativeErrorCode == ERROR_CANCELLED)
MessageBox.Show("Why you no select Yes?");
else
throw;
}
}
Using mo["Caption"].ToString().Contains(NIC) doesn't work for Windows 10 as the WMI query returns the NIC-Name leading with [000000]
[000000] Intel(R) 82574L Gigabit Network Connection
on my Windows 10 machine.
Credit to the following answers: [WMI not working after upgrading to Windows 10
WMI not working after upgrading to Windows 10
How can you change Network settings (IP Address, DNS, WINS, Host Name) with code in C#
and the answers to this question.
With Windows 10 you may need authentication first. Pass a ConnectionOptions instance to a ManagementScope constructor, defining your Authentication and Impersonation properties.
Try this:
// Method to prepare the WMI query connection options.
public static ConnectionOptions PrepareOptions ( )
{
ConnectionOptions options = new ConnectionOptions ( );
options . Impersonation = ImpersonationLevel . Impersonate;
options . Authentication = AuthenticationLevel . Default;
options . EnablePrivileges = true;
return options;
}
// Method to prepare WMI query management scope.
public static ManagementScope PrepareScope ( string machineName , ConnectionOptions options , string path )
{
ManagementScope scope = new ManagementScope ( );
scope . Path = new ManagementPath ( #"\\" + machineName + path );
scope . Options = options;
scope . Connect ( );
return scope;
}
// Set DNS.
ConnectionOptions options = PrepareOptions ( );
ManagementScope scope = PrepareScope ( Environment . MachineName , options , #"\root\CIMV2" );
ManagementClass mc = new ManagementClass(scope, "Win32_NetworkAdapterConfiguration");
ManagementObjectCollection moc = mc.GetInstances();
foreach (ManagementObject mo in moc)
{
if ((bool)mo["IPEnabled"])
{
ManagementBaseObject objdns = mo.GetMethodParameters("SetDNSServerSearchOrder");
if (objdns != null)
{
string[] s = { "192.168.XX.X", "XXX.XX.X.XX" };
objdns["DNSServerSearchOrder"] = s;
mo.InvokeMethod("SetDNSServerSearchOrder", objdns, null);
Based on this answer:
WMI not working after upgrading to Windows 10
This is the code I use to do this and it works:
/// <summary>
/// Set's the DNS Server of the local machine
/// </summary>
/// <param name="NIC">NIC address</param>
/// <param name="DNS">DNS server address</param>
/// <remarks>Requires a reference to the System.Management namespace</remarks>
public void setDNS(string NIC, string DNS)
{
ManagementClass objMC = new ManagementClass("Win32_NetworkAdapterConfiguration");
ManagementObjectCollection objMOC = objMC.GetInstances();
foreach (ManagementObject objMO in objMOC)
{
if ((bool)objMO["IPEnabled"])
{
// if you are using the System.Net.NetworkInformation.NetworkInterface you'll need to change this line to if (objMO["Caption"].ToString().Contains(NIC)) and pass in the Description property instead of the name
if (objMO["Caption"].Equals(NIC))
{
try
{
ManagementBaseObject newDNS =
objMO.GetMethodParameters("SetDNSServerSearchOrder");
newDNS["DNSServerSearchOrder"] = DNS.Split(',');
ManagementBaseObject setDNS =
objMO.InvokeMethod("SetDNSServerSearchOrder", newDNS, null);
}
catch (Exception)
{
throw;
}
}
}
}
}
Hope it helps...

Configure Win 7 Network Adapter Programatically in C#

I want to configure all active network adapters in windows 7 programatically through c#.
I have tried following code:
string newIPAddress = "100.200.100.11";
string newSubnetMask = "255.255.255.1";
string[] newGateway = { "100.200.100.1" };
ManagementObjectSearcher m = new ManagementObjectSearcher();
m.Query = new ObjectQuery("Select * from Win32_NetworkAdapterConfiguration Where IPEnabled = True");
foreach (ManagementObject mo in m.Get())
{
try
{
ManagementBaseObject setIP;
ManagementBaseObject newIP = mo.GetMethodParameters("EnableStatic");
newIP["IPAddress"] = new string[] { newIPAddress };
newIP["SubnetMask"] = new string[] { newSubnetMask };
setIP = mo.InvokeMethod("EnableStatic", newIP, null);
mo.InvokeMethod("SetGateways", new object[] { newGateway, new string[] { "1" } });
mo.InvokeMethod("SetDNSServerSearchOrder", new object[] { new string[] { "100.100.100.100" } });
}
catch (Exception)
{
throw;
}
}
But it just updates the default gateways and changes nothing else.
I have used netsh command as well:
NetworkInterface[] adapters = NetworkInterface.GetAllNetworkInterfaces();
foreach (NetworkInterface adapter in adapters)
{
Console.WriteLine(adapter.Name);
Process p = new Process();
ProcessStartInfo psi = new ProcessStartInfo("netsh", "interface ip set address \"" + adapter.Name + "\" static 192.168.0.10 255.255.255.0 192.168.0.1 ");
psi.UseShellExecute = false;
p.StartInfo = psi;
p.Start();
}
But it works for first adapter and after that it thows an error:
"Failed to configure the DHCP service. The interface may be disconnected."
How can i configure all adapters in c#?
I know this post is old but I believe you are having this issue because you are trying to set the IP of multiple adaptors to the Exact same IP.

Categories