Разобрать вывод pnputil в опубликованное имя для определенного класса

В PowerShell после ввода «pnputil.exe -e» я получаю список информации о драйвере, как показано ниже. Мне нужно получить опубликованное имя монитора класса из списка и сохранить "oem8.inf" в $monitor_name. Какую команду я могу использовать для поиска class = monitor и извлечения его опубликованного имени в переменную. Поскольку в атрибуте «опубликованное имя» есть место, я понятия не имею, как это сделать.

Published name :            oem8.inf    
Driver package provider :   HP
Class :                     Monitors
Driver date and version :   07/25/2013 2.2.0.0    
Signer name :               Microsoft Windows Hardware Compatibility Publisher

Published name :            oem6.inf
Driver package provider :   Canon
Class :                     Printers
Driver date and version :   06/21/2006 6.1.7600.16385
Signer name :               Microsoft Windows

Published name :            oem1.inf
Driver package provider :   Microsoft
Class :                     Printers
Driver date and version :   06/21/2006 10.0.14393.0
Signer name :               Microsoft Windows

person John    schedule 07.06.2017    source источник
comment
См. страницу справки Как задать хороший вопрос. Что вы уже пробовали и с какими ошибками/проблемами столкнулись? StackOverflow не является сервисом для написания кода. В идеале предоставьте минимальный, полный и поддающийся проверке пример.   -  person G42    schedule 07.06.2017


Ответы (3)


Вы можете сделать это с помощью WMI через Get-WMIObject командлет (псевдоним gwmi):

gwmi Win32_PnPSignedDriver | ? DeviceClass -eq "MONITOR"

вернет некоторые детали, вы можете сузить их до InfName, используя это:

gwmi win32_PnPSignedDriver | ? DeviceClass -eq "MONITOR" | Select InfName

InfName
-------
oem30.inf
oem30.inf
person colsw    schedule 07.06.2017

Полезный ответ ConnorLSW — это правильный путь, и его подход иллюстрирует важный момент:

Если вы используете командлеты PowerShell, нет необходимости в манипулировании строками для извлечения информации — объектно-ориентированный характер PowerShell позволяет использовать решения, которые более надежный и удобный по сравнению с традиционными методами анализа вывода текста.

Тем не менее, при необходимости PowerShell также имеет мощные функции синтаксического анализа строк:

$monitor_name = pnputil.exe -e | Select-String -Context 2 'Class :\s+ Monitors' | 
  ForEach-Object { ($_.Context.PreContext[0] -split ' : +')[1] }

С вашим образцом ввода это дает:

oem8.inf
person mklement0    schedule 07.06.2017

Также отметить mklement0 полезный ответ. Если вам когда-нибудь понадобятся все данные объекта только для мониторов, вы можете сделать это.

Clear-Host
(PNPUtil /Enum-Drivers /class Display | 
Select-Object -Skip 2) | 
Select-String -Pattern 'Monitors' -Context 3,4
# Results
<#
  Published Name:     oe...
  Original Name:      tpl...
  Provider Name:      L...
> Class Name:         Monitors
  Class GUID:         {4d36e...
  Driver Version:     11/...
  Signer Name:        Microsof...

  Published Name:     oem...
  Original Name:      tp...
  Provider Name:      L....
> Class Name:         Monitors
  Class GUID:         {4d36...
  Driver Version:     06/...
  Signer Name:        Microsof...
#>

Выбирайте по мере необходимости или создайте и используйте пользовательский объект, чтобы получить свои свойства таким же образом, а затем просто выберите. Например:

Clear-Host
((PNPUtil /Enum-Drivers /class Display | 
Select-Object -Skip 2) | 
Select-String -Pattern 'Class Name:' -Context 3,4) | 
ForEach {
    [PSCustomObject]@{
        PublishedName = $PSItem.Context.PreContext[0] -replace '.*:\s+'
        OriginalName  = $PSItem.Context.PreContext[1] -replace '.*:\s+'
        ProviderName  = $PSItem.Context.PreContext[2] -replace '.*:\s+'
        ClassName     = ($PSitem | Select-String -Pattern 'Class Name:') -replace '.*:\s+'
        ClassGUID     = $PSItem.Context.PostContext[0] -replace '.*:\s+'
        DriverVersion = $PSItem.Context.PostContext[1] -replace '.*:\s+'
        SignerName    = $PSItem.Context.PostContext[2] -replace '.*:\s+'   
    }
}
# Results
<#
PublishedName : oe...
OriginalName  : amd...
ProviderName  : AMD
ClassName     : Sys...s
ClassGUID     : {4d...
DriverVersion : 02/...
SignerName    : Microsof...
...
PublishedName : oem4...
OriginalName  : w...
ProviderName  : West...
ClassName     : WD D...
ClassGUID     : {8496e8....
DriverVersion : 11...
SignerName    : Microsoft W...
#>

Или формат таблицы, или сохранить в csv.

Clear-Host
((PNPUtil /Enum-Drivers /class Display | 
Select-Object -Skip 2) | 
Select-String -Pattern 'Class Name:' -Context 3,4) | 
ForEach {
    [PSCustomObject]@{
        PublishedName = $PSItem.Context.PreContext[0] -replace '.*:\s+'
        OriginalName  = $PSItem.Context.PreContext[1] -replace '.*:\s+'
        ProviderName  = $PSItem.Context.PreContext[2] -replace '.*:\s+'
        ClassName     = ($PSitem | Select-String -Pattern 'Class Name:') -replace '.*:\s+'
        ClassGUID     = $PSItem.Context.PostContext[0] -replace '.*:\s+'
        DriverVersion = $PSItem.Context.PostContext[1] -replace '.*:\s+'
        SignerName    = $PSItem.Context.PostContext[2] -replace '.*:\s+'   
    }
} | 
Format-Table -AutoSize
# Results
<#
PublishedName OriginalName   ProviderName                   ClassName                         ClassGUID                              DriverVersion         SignerName                        
------------- ------------   ------------                   ---------                         ---------                              -------------         ----------                        
...

Clear-Host
((PNPUtil /Enum-Drivers /class Display | 
Select-Object -Skip 2) | 
Select-String -Pattern 'Class Name:' -Context 3,4) | 
ForEach {
    [PSCustomObject]@{
        PublishedName = $PSItem.Context.PreContext[0] -replace '.*:\s+'
        OriginalName  = $PSItem.Context.PreContext[1] -replace '.*:\s+'
        ProviderName  = $PSItem.Context.PreContext[2] -replace '.*:\s+'
        ClassName     = ($PSitem | Select-String -Pattern 'Class Name:') -replace '.*:\s+'
        ClassGUID     = $PSItem.Context.PostContext[0] -replace '.*:\s+'
        DriverVersion = $PSItem.Context.PostContext[1] -replace '.*:\s+'
        SignerName    = $PSItem.Context.PostContext[2] -replace '.*:\s+'   
    }
} | 
Where-Object -Property ClassName -EQ 'Monitors' |
Select-Object -Property PublishedName
# Results
<#
PublishedName
-------------
oem11.inf    
oem67.inf 
#>
person postanote    schedule 12.03.2021