AnOldSoul
AnOldSoul

Reputation: 4197

How to retrieve the onboard ethernet MAC address of a computer?

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

Answers (3)

rebaneitor
rebaneitor

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:

  • Each PC manufacturer in the world making the effort of filling in the UUID BIOS field.
  • Every PC manufacturer making the effort of keeping track of already used UUIDs

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

ha a
ha a

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

Vitaly
Vitaly

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

Related Questions