PDA

Показать полную графическую версию : [решено] получить список физически подключенных usb устройств


Griboed0ff
27-10-2022, 15:13
Доброго времени суток!
Появилась нужда получить с компьютеров количество занятых usb портов физическими устройствами, т.е. не интересуют всякие виртуальные устройства и информация об концентраторах. Суть в том, чтобы посчитать сколько у компьютера осталось свободных usb портов, общее количество физических портов компьютера заведомо известно. Проблема в том, что по выводимой мне информации непонятно реальное ли это устройство. Get-PnpDevice -PresentOnly |Select-Object -Property FriendlyName, class, InstanceId, HardwareID | Where-Object {$_.class -like 'USB' }FriendlyName Class InstanceId HardwareID
------------ ----- ---------- ----------
Составное USB устройство USB USB\VID_046D&PID_C068\F3292570BA0018 {USB\VID_046D&PID_C068&REV_5802, USB\VID_046D&PID_C068}
Корневой USB-концентратор (USB*3.0) USB USB\ROOT_HUB30\4&7496E13&0&0 {USB\ROOT_HUB30&VID8086&PID02ED&REV0000, USB\ROOT_HUB30&VID8086&PID02ED, USB\ROOT_HUB30}
Составное USB устройство USB USB\VID_046D&PID_C534\5&698CBB1&0&4 {USB\VID_046D&PID_C534&REV_2900, USB\VID_046D&PID_C534}
Расширяемый хост-контроллер Intel(R) USB 3.1 — 1.10 (Майкрософт) USB PCI\VEN_8086&DEV_02ED&SUBSYS_869D103C&REV_00\3&11583659&0&A0 {PCI\VEN_8086&DEV_02ED&SUBSYS_869D103C&REV_00, PCI\VEN_8086&DEV_02ED&SUBSYS_869D103C, PCI\VEN_8086&DEV_02ED&CC_0C0330, PCI...
Составное USB устройство USB USB\VID_05C8&PID_03CB\5&698CBB1&0&2 {USB\VID_05C8&PID_03CB&REV_0009, USB\VID_05C8&PID_03CB}
А у меня всего два устройства это мышки. Или можно командой: gwmi Win32_USBControllerDevice |%{[wmi]($_.Dependent)} | Sort Manufacturer,Description,DeviceID | Ft -GroupBy Manufacturer Description,Service,DeviceID что тоже ничего не дает, все в кучу.
В общем устройства в информации для меня ничем не различаются.

DJ Mogarych
27-10-2022, 16:44
А так?

Get-PnpDevice -PresentOnly |? { $_.InstanceId -match '^USB' -and $_.class -ne 'USB' }

Griboed0ff
27-10-2022, 17:55
А так? »
Ну это та же самая команда (я с нее и начал, она первая гуглится, но модифицировал ее), которая отображает все usb устройства, которые не все являются вставленными в usb порт.
Status Class FriendlyName InstanceId
------ ----- ------------ ----------
OK HIDClass USB-устройство ввода USB\VID_046D...
OK HIDClass USB-устройство ввода USB\VID_046D...
OK HIDClass USB-устройство ввода USB\VID_046D...
OK HIDClass USB-устройство ввода USB\VID_046D...
OK Camera HP HD Camera USB\VID_05C8...
OK Bluetooth Intel(R) Wireless Bluetooth(R) USB\VID_8087...

У меня два реальных устройства usb, вот и думаю как бы фильтрануть лишнее, дело в том что как всегда будет опрашиваться большое количество пк и что там будет вставлено неизвестно.

Я понимаю, что в моем случае все усложняется тем, что у меня ноут и видимо некоторые устройства почему-то usb, но на самом деле они внутри корпуса. Опрашиваться будут в основном системные блоки где такого должно быть меньше или вообще не должно быть.
Заметил, что многие устройства при подключении генерируют две записи, на примере включена только мышь, пока встроенные устройства я не принимаю во внимание, так как на системниках таких быть не должно
Get-PnpDevice -PresentOnly |Select-Object -Property status, FriendlyName, class, InstanceId | Where-Object { $_.InstanceId -match '^USB' -and $_.class -ne 'USB'}status FriendlyName Class InstanceId
------ ------------ ----- ----------
OK USB-устройство ввода HIDClass USB\VID_046D&PID_C534&MI_00\6&24087896&0&0000
OK USB-устройство ввода HIDClass USB\VID_046D&PID_C534&MI_01\6&24087896&0&0001
OK HP HD Camera Camera USB\VID_05C8&PID_03CB&MI_00\6&242F741B&0&0000
OK Intel(R) Wireless Bluetooth(R) Bluetooth USB\VID_8087&PID_0026\5&698CBB1&0&10
Осталось как-то считать две записи одним устройством, но опять же не все устройства генерируют по две записи..

DJ Mogarych
27-10-2022, 20:53
как бы фильтрануть лишнее »
две записи одним устройством »
Ну отфильтруйте то, что вам нужно, проблема-то в чём?

Get-PnpDevice -PresentOnly |? {
$_.InstanceId -match '^USB' -and
$_.class -ne 'USB' -and
$_.class -ne 'HIDClass'
} |sort friendlyname -unique


Тут тоже вопрос - а если подключено два одинаковых устройства, создающих две записи? Может быть, надо выбрать другой критерий объединения, экспериментируйте.

Griboed0ff
27-10-2022, 23:51
отфильтруйте »
фильтр $_.class -ne 'HIDClass' вообще исключил мои подключенные устройства
Status Class FriendlyName InstanceId
------ ----- ------------ ----------
OK Camera HP HD Camera USB\VID_05C8...
OK Bluetooth Intel(R) Wireless Bluetooth(R) USB\VID_8087... да и такой фильтр не могу применить там где не знаю какие устройства будут.
сейчас вопрос состоит в том как сравнить значения одного устройства: USB\VID_046D&PID_C534&MI_00\6&24087896&0&0000
USB\VID_046D&PID_C534&MI_01\6&24087896&0&0001 и принять это за одно значение. Тут различия только в 0 и 1. Смотрел в сторону Compare-Object, но пока не смог применить его к своей ситуации.

sonny362
28-10-2022, 03:37
Griboed0ff, не знаю, поможет вам или нет - я использую утилиту UsbTreeView. Так-то она экранная, но с ключом -R пишет вывод текстовый файл. Вроде, и в xml может.

Griboed0ff
28-10-2022, 09:28
UsbTreeView »
К сожалению вопрос надо решить встроенными средствами. Такие программы как-то определяют номер порта, вот бы на пошике так же сделать. Вот если бы была возможность достать больше данных об устройстве средствами пошика, возможно бы там нашел нужное.

DJ Mogarych
28-10-2022, 09:58
принять это за одно значение »

sort {$_.instanceid -replace '.*&(PID_.+?)&.*','$1'} -Unique

Griboed0ff
28-10-2022, 16:45
Мне нужно было получить значения именно через gwmi, получилось два варианта:
gwmi Win32_USBControllerDevice |%{[wmi]($_.Dependent)} | select Caption, PNPClass, deviceid | ? { $_.deviceid -match '^USB' -and $_.PNPClass -ne 'USB'}|sort {$_.deviceid -replace '.*&(PID_.+?)&.*','$1'} -UniqueGet-PnpDevice -PresentOnly |Select-Object -Property status, FriendlyName, class, InstanceId|? { $_.InstanceId -match '^USB' -and $_.class -ne 'USB' }|sort {$_.instanceid -replace '.*&(PID_.+?)&.*','$1'} -Unique
опробовано на системных блоках, все отлично!

DJ Mogarych
28-10-2022, 20:57
Кстати, лучше фильтровать результаты как можно раньше, т. е., сначала надо where, а потом select.
Здесь это, может, не очень существенно, но в целом надо применять filter left technique (https://mcpmag.com/articles/2018/01/16/filtering-command-output-in-powershell.aspx), т. е., как можно раньше отбрасывать ненужное, чтобы не тащить лишние данные между процессами обработки.

Также, фильтры бывают уже и в самом командлете, например, можно instanceID отобрать, не перебрасывая через пайп.

Get-PnpDevice -PresentOnly -InstanceId "USB*" |? class -ne 'USB' |select status, FriendlyName, class, InstanceId |sort {$_.instanceid -replace '.*&(PID_.+?)&.*','$1'} -Unique


Ранняя фильтрация ускоряет обработку, иногда кардинально.




© OSzone.net 2001-2012