PowerShell查找驱动程序版本

时间:2015-07-01 20:17:25

标签: parsing powershell text-files driver

使用DevCon实用程序,我运行此命令以获取计算机中安装的所有驱动程序的列表。

devcon.exe driverfiles * > drivers.txt

输出如下:

USB\ROOT_HUB20\4&361B340A&0
    Name: USB Root Hub
    Driver installed from C:\windows\INF\usbport.inf [ROOTHUB.Dev]. 2 file(s) used by driver:
        C:\windows\system32\drivers\usbhub.sys
        C:\windows\system32\drivers\usbd.sys
ACPI\PNP0C09\1
USB\ROOT_HUB20\4&361B340A&1
    Name: USB Root Hub
    Driver installed from C:\windows\INF\usbport.inf [ROOTHUB.Dev]. 2 file(s) used by driver:
        C:\windows\system32\drivers\usbhub.sys
        C:\windows\system32\drivers\usbd.sys

然后我使用PowerShell脚本来解析文件。感谢TheMadTechnician。

(Get-Content C:\Path\To\File.txt) -join "`r`n" -Split "(?m)^(?=\S)" |
    Where{$_} | 
    ForEach{
        Clear-Variable Files,Driver,Name,HardwareID
        $Files = @()
        $HardwareID = ($_ -split "`r`n")[0].trim()
        Switch -regex ($_ -split "`r`n"){
            "^\s+Name:" {$Name = ($_ -split ':',2)[-1].trim();Continue}
            "^\s+.:\\" {$Files += $_.trim();continue}
            "^\s+Driver" {$Driver = [RegEx]::Matches($_,"(?<=Driver installed from )(.+?)(?= \[)").value;continue}
        }
        [PSCustomObject]@{'HardwareID' = $HardwareID;'Name' = $Name; 'Files' = $Driver; 'FileVersion' = If(Test-Path $_.Trim()){[System.Diagnostics.FileVersionInfo]::GetVersionInfo($_.trim()).FileVersion}}
    $Files | ForEach{ [PSCustomObject]@{'HardwareID' = $HardwareID;'Name' = $Name; 'Files' = $_; 'FileVersion' = If(Test-Path $_.Trim()){[System.Diagnostics.FileVersionInfo]::GetVersionInfo($_.trim()).FileVersion}Else{'File Not Found'}}}

现在,运行脚本后的输出是:

HardwareID                  Name                                            Files                                  FileVersion                             
----------                  ----                                            -----                                  -----------                             
USB\ROOT_HUB20\4&361B340A&0 USB Root Hub                                    C:\windows\INF\usbport.inf                                                     
USB\ROOT_HUB20\4&361B340A&0 USB Root Hub                                    C:\windows\system32\drivers\usbhub.sys 6.3.9600.17238 (winblue_gdr.140723-2018)
USB\ROOT_HUB20\4&361B340A&0 USB Root Hub                                    C:\windows\system32\drivers\usbd.sys   6.3.9600.17195 (winblue_gdr.140530-1506)
ACPI\PNP0C09\1                                                                                                                                             
USB\ROOT_HUB20\4&361B340A&1 USB Root Hub                                    C:\windows\INF\usbport.inf                                                     
USB\ROOT_HUB20\4&361B340A&1 USB Root Hub                                    C:\windows\system32\drivers\usbhub.sys 6.3.9600.17238 (winblue_gdr.140723-2018)
USB\ROOT_HUB20\4&361B340A&1 USB Root Hub                                    C:\windows\system32\drivers\usbd.sys   6.3.9600.17195 (winblue_gdr.140530-1506)

问题

我想添加一个带驱动程序版本的额外列。

如何找到驱动程序版本并将其列在名称列旁边?谢谢!

修改

下面的代码从INF文件中解析驱动程序版本。 我对PowerShell没有经验,所以如何使用这些信息并将其与上面的代码合并以添加额外的列和列表驱动程序版本;最好是在名称栏旁边。

$pattern = 'DriverVer\s*=\s*(?:\d+/\d+/\d+,)?(.*)'
Select-String -Pattern $pattern -Path $path |
  select -Expand Matches -First 1 |
  % { $_.Groups[1].Value }

# $path = the INF file

1 个答案:

答案 0 :(得分:1)

添加新列相对简单。列出的列是因为它们是数组中对象的属性。所以现在我们有像这样构建的对象(驱动程序行类似,然后我们将所有剩余的文件传输到此,添加换行符以便于阅读):

[PSCustomObject]@{
    'HardwareID' = $HardwareID
    'Name' = $Name
    'Files' = $_
    'FileVersion' = If(Test-Path $_.Trim()){[System.Diagnostics.FileVersionInfo]::GetVersionInfo($_.trim()).FileVersion}Else{'File Not Found'}
}

由此我们得到四列&#39; HardwareID,&#39; Name&#39;,&#39; Files&#39;和&#39; FileVersion&#39;。如果要添加列,只需插入另一个属性即可。在这种情况下,您希望在Name旁边添加一个新列,其中包含每个项目的驱动程序版本。我们可以简单地重新设置当前为每个项目输出驱动程序文件路径(缺少版本号)的行:

[PSCustomObject]@{'HardwareID' = $HardwareID;'Name' = $Name; 'Files' = $Driver; 'FileVersion' = If(Test-Path $_.Trim()){[System.Diagnostics.FileVersionInfo]::GetVersionInfo($_.trim()).FileVersion}}

使用该行,我们可以删除那里试图列出&#39; FileVersion&#39;中的任何内容的位。列,并在其中添加一个新的“DriverVersion&#39;使用您提供的代码(稍作修改)。我们将$Pattern =行移动到脚本的第一行,因为我们不需要为循环的每次迭代重新分配该行。然后我们将把剩下的代码分配给新的&#39; DriverVersion&#39; property / column,并将其包装在If($Driver){}语句中,这样它就不会为没有列出驱动程序的条目抛出错误。所以现在看起来像这样:

        [PSCustomObject]@{
            'HardwareID' = $HardwareID
            'Name' = $Name
            'DriverVersion' = If($Driver){Select-String -Pattern $pattern -Path $driver | select -Expand Matches -First 1 |%{ $_.Groups[1].Value }}else{''}
            'Files' = $Driver
            'FileVersion' = '' }

现在,由于我们将该属性添加到该行,我们还需要更新下一行,以便它也包含该属性(尽管值为空白):

        $Files | ForEach{ [PSCustomObject]@{'HardwareID' = $HardwareID;'Name' = $Name; 'DriverVersion'= ''; 'Files' = $_; 'FileVersion' = If(Test-Path $_.Trim()){[System.Diagnostics.FileVersionInfo]::GetVersionInfo($_.trim()).FileVersion}Else{'File Not Found'}}}

整个更新后的代码如下所示:

$pattern = 'DriverVer\s*=\s*(?:\d+/\d+/\d+,)?(.*)'
(Get-Content C:\Path\To\File.txt) -join "`r`n" -Split "(?m)^(?=\S)" |
    Where{$_} | 
    ForEach{
        Clear-Variable Files,Driver,Name,HardwareID,DriverVer -ea SilentlyContinue
        $Files = @()
        $HardwareID = ($_ -split "`r`n")[0].trim()
        Switch -regex ($_ -split "`r`n"){
            "^\s+Name:" {$Name = ($_ -split ':',2)[-1].trim();Continue}
            "^\s+.:\\" {$Files += $_.trim();continue}
            "^\s+Driver" {$Driver = [RegEx]::Matches($_,"(?<=Driver installed from )(.+?)(?= \[)").value;continue}
        }

        [PSCustomObject]@{
            'HardwareID' = $HardwareID
            'Name' = $Name
            'DriverVersion' = If($Driver){Select-String -Pattern $pattern -Path $driver | select -Expand Matches -First 1 |%{ $_.Groups[1].Value }}else{''}
            'Files' = $Driver
            'FileVersion' = '' }
        $Files | ForEach{ [PSCustomObject]@{'HardwareID' = $HardwareID;'Name' = $Name; 'DriverVersion'= ''; 'Files' = $_; 'FileVersion' = If(Test-Path $_.Trim()){[System.Diagnostics.FileVersionInfo]::GetVersionInfo($_.trim()).FileVersion}Else{'File Not Found'}}}
    }|ft

现在输出的内容如下:

HardwareID                  Name                                            DriverVersion  Files                                  FileVersion                             
----------                  ----                                            -------------  -----                                  -----------                             
USB\ROOT_HUB20\4&361B340A&0 USB Root Hub                                    6.3.9600.17238 C:\windows\INF\usbport.inf                                                     
USB\ROOT_HUB20\4&361B340A&0 USB Root Hub                                                   C:\windows\system32\drivers\usbhub.sys 6.3.9600.17238 (winblue_gdr.140723-2018)
USB\ROOT_HUB20\4&361B340A&0 USB Root Hub                                                   C:\windows\system32\drivers\usbd.sys   6.3.9600.17195 (winblue_gdr.140530-1506)
ACPI\PNP0C09\1                                                                                                                                                            
USB\ROOT_HUB20\4&361B340A&1 USB Root Hub                                    6.3.9600.17238 C:\windows\INF\usbport.inf                                                     
USB\ROOT_HUB20\4&361B340A&1 USB Root Hub                                                   C:\windows\system32\drivers\usbhub.sys 6.3.9600.17238 (winblue_gdr.140723-2018)
USB\ROOT_HUB20\4&361B340A&1 USB Root Hub                                                   C:\windows\system32\drivers\usbd.sys   6.3.9600.17195 (winblue_gdr.140530-1506)
ACPI\PNP0C09\2                                                                                                                                                            
USB\ROOT_HUB20\4&361B340A&2                                                 6.3.9600.16384 C:\windows\INF\cmbatt.inf                                                      
USB\ROOT_HUB20\4&361B340A&2                                                                C:\windows\system32\DRIVERS\CmBatt.sys 6.3.9600.16384 (winblue_rtm.130821-1623)
USB\ROOT_HUB20\4&361B340A&2                                                                C:\windows\system32\DRIVERS\battc.sys  6.3.9600.16384 (winblue_rtm.130821-1623)
ACPI\PNP0C0A\2              Microsoft ACPI-Compliant Control Method Battery 6.3.9600.16384 C:\windows\INF\cmbatt.inf                                                      
ACPI\PNP0C0A\2              Microsoft ACPI-Compliant Control Method Battery                C:\windows\system32\DRIVERS\CmBatt.sys 6.3.9600.16384 (winblue_rtm.130821-1623)
ACPI\PNP0C0A\2              Microsoft ACPI-Compliant Control Method Battery                C:\windows\system32\DRIVERS\battc.sys  6.3.9600.16384 (winblue_rtm.130821-1623)