如何用Python的WMI库获取Windows网卡PCI插槽信息并关联
如何关联Win32_NetworkAdapter与Win32_SystemSlot获取网卡对应的PCI插槽位置
需求说明
在Windows系统中,需要查询各物理网络适配器(NIC)对应的PCI插槽位置。已通过PowerShell的Get-WmiObject -class "Win32_SystemSlot"获取PCI插槽信息,Get-NetAdapterHardwareInfo获取网卡硬件信息,但使用Python的wmi库仅能获取网卡基础信息,无法直接关联到PCI插槽,需要通过WMI类关联实现匹配。
已有的PowerShell输出示例
获取PCI插槽信息
Get-WmiObject -class "Win32_SystemSlot"
输出:
SlotDesignation : PCI1 Tag : System Slot 0 SupportsHotPlug : False Status : OK Shared : False PMESignal : True MaxDataWidth : 8 SlotDesignation : PCI2 Tag : System Slot 1 SupportsHotPlug : False Status : OK Shared : False PMESignal : True MaxDataWidth : 10
获取网卡硬件信息
Get-NetAdapterHardwareInfo
输出:
Name Segment Bus Device Function Slot NumaNode PcieLinkSpeed PcieLinkWidth Version ---- ------- --- ------ -------- ---- -------- ------------- ------------- ------- NIC4 0 2 0 1 0 5.0 GT/s 1 1.1 NIC1 0 1 0 0 0 5.0 GT/s 1 1.1 NIC3 0 2 0 0 0 5.0 GT/s 1 1.1 SLOT 2 Port 1 0 66 0 0 2 1 5.0 GT/s 4 1.1 SLOT 2 Port 2 0 66 0 1 2 1 5.0 GT/s 4 1.1
初始Python代码问题
以下代码仅能获取网卡制造商等基础信息,无法获取插槽关联数据:
import wmi c = wmi.WMI() network = c.Win32_NetworkAdapter() for adapter in network: print(f"Network Adapter: {adapter}")
WMI类实例参考
Win32_NetworkAdapter实例数据
{ AdapterType = "Ethernet 802.3"; AdapterTypeId = 0; Availability = 3; Caption = "[00000008] Broadcom NetXtreme Gigabit Ethernet"; ConfigManagerErrorCode = 0; ConfigManagerUserConfig = FALSE; CreationClassName = "Win32_NetworkAdapter"; Description = "Broadcom NetXtreme Gigabit Ethernet"; DeviceID = "8"; GUID = "{8E574D4E-47A4-408A-B893-D42D569DE9A1}"; Index = 8; Installed = TRUE; InterfaceIndex = 9; MACAddress = "C8:1F:66:F2:A3:B8"; Manufacturer = "Broadcom"; MaxNumberControlled = 0; Name = "Broadcom NetXtreme Gigabit Ethernet #4"; NetConnectionID = "NIC3"; NetConnectionStatus = 7; NetEnabled = FALSE; PhysicalAdapter = TRUE; PNPDeviceID = "PCI\\VEN_14E4&DEV_165F&SUBSYS_1F5B1028&REV_00\\0000C81F66F2A3B800"; PowerManagementSupported = FALSE; ProductName = "Broadcom NetXtreme Gigabit Ethernet"; ServiceName = "b57nd60a"; Speed = "9223372036854775807"; SystemCreationClassName = "Win32_ComputerSystem"; SystemName = "WIN-IB3B2171E8I"; TimeOfLastReset = "20240203222756.500000-480"; };
Win32_SystemSlot实例数据
{ BusNumber = 65535; Caption = "System Slot"; ConnectorType = {0}; CreationClassName = "Win32_SystemSlot"; CurrentUsage = 3; Description = "System Slot"; DeviceNumber = 80; FunctionNumber = 0; MaxDataWidth = 8; Name = "System Slot"; PMESignal = TRUE; SegmentGroupNumber = 65535; Shared = FALSE; SlotDesignation = "PCI1"; Status = "OK"; SupportsHotPlug = FALSE; Tag = "System Slot 0"; VccMixedVoltageSupport = {2}; };
关联方案与Python实现
核心思路
通过SegmentGroupNumber、BusNumber、DeviceNumber、FunctionNumber这组PCI地址编号作为关联键,将Win32_NetworkAdapter(通过关联Win32_PnPEntity和Win32_PCIeDevice)与Win32_SystemSlot进行匹配。
代码实现
import wmi c = wmi.WMI() # 筛选物理网卡,排除虚拟适配器 physical_adapters = [adapter for adapter in c.Win32_NetworkAdapter() if adapter.PhysicalAdapter] # 构建PCI地址到插槽名称的映射字典 slot_map = { (slot.SegmentGroupNumber, slot.BusNumber, slot.DeviceNumber, slot.FunctionNumber): slot.SlotDesignation for slot in c.Win32_SystemSlot() } for adapter in physical_adapters: # 通过PNPDeviceID关联到Win32_PnPEntity pnp_entity = next((pnp for pnp in c.Win32_PnPEntity() if pnp.DeviceID == adapter.PNPDeviceID), None) if not pnp_entity: print(f"网卡 {adapter.NetConnectionID} ({adapter.Name}):未找到对应PnP实体") continue # 从PnP实体关联到Win32_PCIeDevice,获取PCI地址信息 pci_devices = pnp_entity.associators(wmi_result_class="Win32_PCIeDevice") if not pci_devices: print(f"网卡 {adapter.NetConnectionID} ({adapter.Name}):未找到对应PCIe设备信息") continue pci_dev = pci_devices[0] pci_key = (pci_dev.SegmentGroupNumber, pci_dev.BusNumber, pci_dev.DeviceNumber, pci_dev.FunctionNumber) # 查找对应的PCI插槽 slot_name = slot_map.get(pci_key, "未匹配到插槽") print(f"网卡名称:{adapter.NetConnectionID}") print(f"网卡描述:{adapter.Name}") print(f"PCI地址:Segment={pci_dev.SegmentGroupNumber}, Bus={pci_dev.BusNumber}, Device={pci_dev.DeviceNumber}, Function={pci_dev.FunctionNumber}") print(f"对应PCI插槽:{slot_name}\n")
备选方案:直接调用PowerShell命令
如果WMI关联存在兼容性问题,可以直接在Python中执行Get-NetAdapterHardwareInfo命令,解析输出结果获取插槽信息:
import subprocess import json # 执行PowerShell命令并转为JSON格式便于解析 ps_command = "Get-NetAdapterHardwareInfo | ConvertTo-Json" result = subprocess.run( ["powershell", "-Command", ps_command], capture_output=True, text=True, encoding="utf-8" ) if result.returncode != 0: print(f"命令执行失败:{result.stderr}") else: adapter_data = json.loads(result.stdout) for item in adapter_data: slot = item.get("Slot", "N/A") print(f"网卡名称:{item['Name']}") print(f"PCI插槽:{slot}") print(f"PCI地址:Segment={item['Segment']}, Bus={item['Bus']}, Device={item['Device']}, Function={item['Function']}\n")
内容的提问来源于stack exchange,提问作者Deepali Joshi
相关产品推荐
相关产品推荐

