I am new here and just learning python. I need help to get the right mac-address of my network card in windows using python. I tried to search, and found these :
If I run "ipconfig /all" from command prompt, I get this :
Windows-IP-Konfiguration
Hostname . . . . . . . . . . . . : DESKTOP-CIRBA63
Primäres DNS-Suffix . . . . . . . :
Knotentyp . . . . . . . . . . . . : Hybrid
IP-Routing aktiviert . . . . . . : Nein
WINS-Proxy aktiviert . . . . . . : Nein
Ethernet-Adapter Ethernet:
Verbindungsspezifisches DNS-Suffix:
Beschreibung. . . . . . . . . . . : Realtek PCIe FE Family Controller
Physische Adresse . . . . . . . . : 32-A5-2C-0B-14-D9
DHCP aktiviert. . . . . . . . . . : Nein
Autokonfiguration aktiviert . . . : Ja
IPv4-Adresse . . . . . . . . . . : 192.168.142.35(Bevorzugt)
Subnetzmaske . . . . . . . . . . : 255.255.255.0
Standardgateway . . . . . . . . . : 192.168.142.1
DNS-Server . . . . . . . . . . . : 8.8.8.8
8.8.4.4
NetBIOS über TCP/IP . . . . . . . : Deaktiviert
Ethernet-Adapter Ethernet 2:
Medienstatus. . . . . . . . . . . : Medium getrennt
Verbindungsspezifisches DNS-Suffix:
Beschreibung. . . . . . . . . . . : Norton Security Data Escort Adapter
Physische Adresse . . . . . . . . : 00-CE-35-1B-77-5A
DHCP aktiviert. . . . . . . . . . : Ja
Autokonfiguration aktiviert . . . : Ja
Tunneladapter isatap.{xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx}:
Medienstatus. . . . . . . . . . . : Medium getrennt
Verbindungsspezifisches DNS-Suffix:
Beschreibung. . . . . . . . . . . : Microsoft ISATAP Adapter
Physische Adresse . . . . . . . . : 00-00-00-00-00-00-00-A0
DHCP aktiviert. . . . . . . . . . : Nein
Autokonfiguration aktiviert . . . : Ja
I need to get the mac address of my Realtek network card (32-A5-2C-0B-14-D9), not the one created by Norton or windows tunneling.
Python gave me another result of mac address if i am using :
"uuid.getnode() or "getmac"
I think the best way is to get the output of
"ipconfig /all",
looking at "Realtek" at "Beschreibung" and then get the "Physische Adresse" information to get my real mac address.
How to do this in python on windows ? Any help is appreciated. Thanks in advance.
4 Answers 4
You can retrieve the windows interface information using wmic in XML format, and then convert the xml to a dict. From the resulting dict you can gather any needed information:
def get_interfaces_with_mac_addresses(interface_name_substring=''):
import subprocess
import xml.etree.ElementTree
cmd = 'wmic.exe nic'
if interface_name_substring:
cmd += ' where "name like \'%%%s%%\'" ' % interface_name_substring
cmd += ' get /format:rawxml'
DETACHED_PROCESS = 8
xml_text = subprocess.check_output(cmd, creationflags=DETACHED_PROCESS)
# convert xml text to xml structure
xml_root = xml.etree.ElementTree.fromstring(xml_text)
xml_types = dict(
datetime=str,
boolean=lambda x: x[0].upper() == 'T',
uint16=int,
uint32=int,
uint64=int,
string=str,
)
def xml_to_dict(xml_node):
""" Convert the xml returned from wmic to a dict """
dict_ = {}
for child in xml_node:
name = child.attrib['NAME']
xml_type = xml_types[child.attrib['TYPE']]
if child.tag == 'PROPERTY':
if len(child):
for value in child:
dict_[name] = xml_type(value.text)
elif child.tag == 'PROPERTY.ARRAY':
if len(child):
assert False, "This case is not dealt with"
else:
assert False, "This case is not dealt with"
return dict_
# convert the xml into a list of dict for each interface
interfaces = [xml_to_dict(x)
for x in xml_root.findall("./RESULTS/CIM/INSTANCE")]
# get only the interfaces which have a mac address
interfaces_with_mac = [
intf for intf in interfaces if intf.get('MACAddress')]
return interfaces_with_mac
This function will return a list of dicts, the desired information can be returned from the resulting dicts:
for intf in get_interfaces_with_mac_addresses('Realtek'):
print intf['Name'], intf['MACAddress']
4 Comments
from testpackage.testmac import get_mac_addresses. Also you need __init__.py not init.py. But much easier would be to just put the get_mac_addresses code directly into your script to test. After you are happy, then you can figure out how to get into a package or module.[{'Index': 1, 'PowerManagementSupported': ... etc ... , not only the Mac Address part. If I tried to import the xml_to_dict after importing the get_mac_addresses , i got error (import error). What must i do ?the python3 script below is based on the Stephen Rauch one (thanks for the wmic utility pointer it's really handy)
it retrieves only the IP and active interfaces from the computer, handles fields with multiple values (several ips/masks or gateways on one nic), creates IPv4Iinterface or v6 python objects from ip/mask, and ouputs a list with one dict per nic.
#python3
from subprocess import check_output
from xml.etree.ElementTree import fromstring
from ipaddress import IPv4Interface, IPv6Interface
def getNics() :
cmd = 'wmic.exe nicconfig where "IPEnabled = True" get ipaddress,MACAddress,IPSubnet,DNSHostName,Caption,DefaultIPGateway /format:rawxml'
xml_text = check_output(cmd, creationflags=8)
xml_root = fromstring(xml_text)
nics = []
keyslookup = {
'DNSHostName' : 'hostname',
'IPAddress' : 'ip',
'IPSubnet' : '_mask',
'Caption' : 'hardware',
'MACAddress' : 'mac',
'DefaultIPGateway' : 'gateway',
}
for nic in xml_root.findall("./RESULTS/CIM/INSTANCE") :
# parse and store nic info
n = {
'hostname':'',
'ip':[],
'_mask':[],
'hardware':'',
'mac':'',
'gateway':[],
}
for prop in nic :
name = keyslookup[prop.attrib['NAME']]
if prop.tag == 'PROPERTY':
if len(prop):
for v in prop:
n[name] = v.text
elif prop.tag == 'PROPERTY.ARRAY':
for v in prop.findall("./VALUE.ARRAY/VALUE") :
n[name].append(v.text)
nics.append(n)
# creates python ipaddress objects from ips and masks
for i in range(len(n['ip'])) :
arg = '%s/%s'%(n['ip'][i],n['_mask'][i])
if ':' in n['ip'][i] : n['ip'][i] = IPv6Interface(arg)
else : n['ip'][i] = IPv4Interface(arg)
del n['_mask']
return nics
if __name__ == '__main__':
nics = getNics()
for nic in nics :
for k,v in nic.items() :
print('%s : %s'%(k,v))
print()
import it or use it from a cmd prompt :
python.exe getnics.py
will output something like :
hardware : [00000000] Intel(R) Centrino(R) Wireless-N 2230 Driver
gateway : ['192.168.0.254']
ip : [IPv4Interface('192.168.0.40/24'), IPv6Interface('fe80::7403:9e12:f7db:60c/64')]
mac : xx:xx:xx:xx:xx:xx
hostname : mixer
hardware : [00000002] Killer E2200 Gigabit Ethernet Controller
gateway : ['192.168.0.254']
ip : [IPv4Interface('192.168.0.28/24')]
mac : xx:xx:xx:xx:xx:xx
hostname : mixer
tested with windows10. I have some doubts about the mac adress field, with VM or spoofing cases for example, it seems wmic returns one string only, and not an array.
# Python 3.10.4
from getmac import get_mac_address
mac_address = get_mac_address(ip='192.168.1.20').upper()
1 Comment
getmac? It isn't part of the standard library in Python 3.10.4, or any other version. If you're going to recommend third-party modules, please be explicit about it. See How to Answer.The above answers use wmic, which is deprecated. Here a solution using powershell (also works on at least Windows 10), which is much simpler to boot:
def get_nics() :
import subprocess
import json
from ipaddress import IPv4Interface, IPv6Interface
cmd = 'where powershell'
path = subprocess.check_output(cmd)
cmd = [path.strip(), 'Get-CimInstance -ClassName Win32_NetworkAdapterConfiguration -Filter "IPEnabled = True" | select IPAddress,IPSubnet,MACAddress | ConvertTo-JSON']
ns = json.loads(subprocess.check_output(cmd))
nics = []
for n in ns:
ips = [(ip,f'{ip}/{mask}') for ip,mask in zip(n["IPAddress"],n["IPSubnet"])]
ips = [IPv6Interface(arg[1]) if ':' in arg[0] else IPv4Interface(arg[1]) for arg in ips]
nics.append({'ip': ips, 'mac': n["MACAddress"]})
return nics
Comments
Explore related questions
See similar questions with these tags.
subprocess.Popen. There's no need for the cmd shell; it should be avoided as much as possible, especially if the command is based on user input. Also, wmic.exe can output as reliable XML, which is a suitable alternative for people who don't know PowerShell, or who want to avoid its startup lag (still noticeable in Windows 10, IMO -- it's a beast of a shell).