Reputation: 4197
I am trying to retrieve the MAC address for the onboard ethernet adapter from a computer, in order to generate a unique identifier for the device. Below is the approach I am using.
NetworkInterface[] ifConfig = NetworkInterface.GetAllNetworkInterfaces();
int maxHash = int.MinValue;
Guid D = Guid.Empty;
foreach (NetworkInterface net in ifConfig)
{
if (net.NetworkInterfaceType == NetworkInterfaceType.Ethernet)
{
if (maxHash < net.GetPhysicalAddress().ToString().GetHashCode())
{
maxHash = net.GetPhysicalAddress().ToString().GetHashCode();
ID = new Guid(String.Concat("00000000-0000-0000-0000-", net.GetPhysicalAddress().ToString()));
}
}
}
However, the Bluetooth adapter, VM adapter and several other network adapters are also of the NetworkInterfaceType.Ethernet
type. How can I specifically get the onboard ethernet connection's MAC address?
Doing a contains to omit those wouldn't be possible. Any help would be much appreciated.
Upvotes: 0
Views: 1335
Reputation: 11
I recently wrote a Powershell Script to generate a permanent system-format-immutable unique ID for a Windows PC for inventory purposes (QR encode the ID, print it on a sticker...).
It concatenates the PC manufacturer UUID field with the permanent MAC address of every PCI-connected network adapter (sorted alphabetically by MAC). The PCI requirement automatically dismisses removable or virtual NICs. The real script MD5-hashes the resulting string in order to obtain a more homogeneous identifier (constant length and 0-9A-F set of symbols), but I will omit this here for the sake of simplicity
I could’ve settled for the PC manufacturer UUID and call it a day, but I didn’t feel comfortable with an ID that relies on:
Basically, I tried to adhere to the intuitive idea of putting in the mixer as many non-removable components with permanent and “unique” (dream on) identifier as possible.
This ID generation technique is not fail proof: if a new PCI network adapter is added to the system, the ID will change. But with the popularization of integrated NICs I believe this is no longer something to worry about, if it ever was.
This solution is not directly applicable for C#, but I believe it can be easily adapted since Powershell shares almost the same .net object-class ecosystem.
#Variable names in spanish, but if I try to translate them in a hurry
#I will most certainly end up with a non-working script
$elpc=(Get-WmiObject -Class Win32_ComputerSystemProduct)
$id=$elpc.UUID #This is the UUID the manufacturer wrote somewhere in the BIOS
#Get network devices
#"Net" for network devices, "PCI*" because PCI connected devices begin that way
$dispositivosdered=@(Get-PnpDevice | Where-Object {($_.Class -eq "Net") -and ($_.InstanceId -like "PCI*")})
#Get network adapters
#Use "PermanentAddress" property. "MacAddress" property can be spoofed easily
$tarjetasdered=@(Get-Netadapter | Sort-Object PermanentAddress)
#Double loop to rule out any network adapters which are not PCI
#Comparison is made using long name, ie "Realtek PCIe GBE Family Controller #2"
#Is the only valid field I found to (inner) join the device and adapter worlds
for($j=0; $j -lt $tarjetasdered.length; $j++) {
for ($i=0; $i -lt $dispositivosdered.length; $i++) {
if($dispositivosdered[$i].FriendlyName -eq $tarjetasdered[$j].InterfaceDescription) {
if(-not [string]::IsNullOrEmpty($tarjetasdered[$j].PermanentAddress)) {
$id= $id + $tarjetasdered[$j].PermanentAddress.Replace("-", "");
}
}
}
}
Upvotes: 1
Reputation: 83
using system.Management;
private string GetMACAddress()
{
ManagementClass mc = new ManagementClass("Win32_NetworkAdapterConfiguration");
ManagementObjectCollection moc = mc.GetInstances();
string MACAddress = String.Empty;
foreach (ManagementObject mo in moc)
{
if (MACAddress == String.Empty) // only return MAC Address from first card
{
if ((bool)mo["IPEnabled"] == true) MACAddress = mo["MacAddress"].ToString();
}
mo.Dispose();
}
MACAddress = MACAddress.Replace(":", "");
return MACAddress;
}
Upvotes: 0
Reputation: 75
As an option (not the best, but still =) ) - You can try to use metric. In most cases the metric of the network to a physical network card priority
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Management;
using System.Net.NetworkInformation;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
private void button1_Click(object sender, EventArgs e)
{
listBox1.Items.Clear();
ManagementObjectSearcher query = new
ManagementObjectSearcher("SELECT * FROM Win32_NetworkAdapterConfiguration WHERE IPEnabled = 'TRUE'");
ManagementObjectCollection queryCollection = query.Get();
foreach (ManagementObject mo in queryCollection)
{
if (!(mo["Description"].ToString().Contains("VM")))
{
if (!(mo["Description"].ToString().Contains("Virtual")))
{
if (!(mo["Description"].ToString().Contains("Hyper")))
{
string[] addresses = (string[])mo["IPAddress"];
string IPConnectionMetric = Convert.ToString(mo["IPConnectionMetric"]).Trim();
foreach (string ipaddress in addresses)
{
listBox1.Items.Add(ipaddress + ";" + IPConnectionMetric);
}
}
private void button2_Click(object sender, EventArgs e)
{
if (listBox1.Items.Count > 1)
{
int maximum = int.MinValue;
int minimum = int.MaxValue;
for (int i = 0; i < listBox1.Items.Count; i++)
{
int output = Convert.ToInt32(listBox1.Items[i].ToString().Split(';')[1]);
if ((int)output > maximum)
maximum = (int)output;
}
for (int i = 0; i < listBox1.Items.Count; i++)
{
int output = Convert.ToInt32(listBox1.Items[i].ToString().Split(';')[1]);
if ((int)output < maximum)
minimum = (int)output;
if (listBox1.Items[i].ToString().Contains(minimum.ToString()))
{
var minmetric = listBox1.Items[i].ToString();
NetworkInterface[] ifConfig = NetworkInterface.GetAllNetworkInterfaces();
int maxHash = int.MinValue;
Guid D = Guid.Empty;
foreach (NetworkInterface net in ifConfig)
{
if (net.NetworkInterfaceType == NetworkInterfaceType.Ethernet)
{
if (maxHash < net.GetPhysicalAddress().ToString().GetHashCode())
{
maxHash = net.GetPhysicalAddress().ToString().GetHashCode();
foreach (UnicastIPAddressInformation ip in net.GetIPProperties().UnicastAddresses)
{
if (ip.Address.AddressFamily == System.Net.Sockets.AddressFamily.InterNetwork)
{
if (ip.Address.AddressFamily == System.Net.Sockets.AddressFamily.InterNetwork)
{
if (ip.Address.ToString().Contains(minmetric.ToString().Split(';')[0]))
{
var ID = new Guid(String.Concat("00000000-0000-0000-0000-", net.GetPhysicalAddress().ToString()));
}
}
else
{
NetworkInterface[] ifConfig = NetworkInterface.GetAllNetworkInterfaces();
int maxHash = int.MinValue;
Guid D = Guid.Empty;
foreach (NetworkInterface net in ifConfig)
{
if (net.NetworkInterfaceType == NetworkInterfaceType.Ethernet)
{
if (maxHash < net.GetPhysicalAddress().ToString().GetHashCode())
{
maxHash = net.GetPhysicalAddress().ToString().GetHashCode();
var ID = new Guid(String.Concat("00000000-0000-0000-0000-", net.GetPhysicalAddress().ToString()));
}
}
}
Upvotes: 0