PowerShell Find Driver Version

被刻印的时光 ゝ 提交于 2019-12-14 02:20:02

问题


Using DevCon utility, I ran this command to get the list of all of the drivers installed in the computer.

devcon.exe driverfiles * > drivers.txt

The output looks like this:

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

I then used PowerShell script to parse the file. Thanks to 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'}}}

Now, the output after running the script is:

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)

THE PROBLEM

I would like to add an extra column with driver version.

How can I find the driver version and list it next to the name column? Thank you!

EDIT

The code below parses driver version from the INF file. I am not experienced with PowerShell, so how can I used this bit of information and incorporate it with the above code to add an extra column and list driver version; preferably, next to Name column.

$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:


Adding a new column is relatively simple. The columns are listed because they are properties of the object in the array. So right now we have object that are built like this (the driver line is similar, and then we pipe all remaining files into this, line breaks added for ease of reading):

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

From that we get the four columns 'HardwareID, 'Name', 'Files', and 'FileVersion'. If you want to add a column you can simply insert another property. In this case you want to add a new column next to Name that has the version of the driver for each item. We can simply re-purpose the line that currently outputs the driver file path (with missing version number) for each item:

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

With that line we can just remove the bit in there that tries to list anything in the 'FileVersion' column, and add a new one in there for 'DriverVersion' using the code that you supplied (with some minor modifications). We're going to move the $Pattern = line to be the first line of the script, since we don't need to re-assign that for each iteration of the loop. Then we are going to assign the rest of your code to the new 'DriverVersion' property/column, and wrap it in a If($Driver){} statement, so that it doesn't throw errors for entries that don't have a driver listed. So that now looks like this:

        [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' = '' }

Now, since we added that property to that line, we need to update the next line as well so that it includes that property as well (albeit with a blank value):

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

The updated code as a whole would look something like:

$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

This now outputs something along the lines of:

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)


来源:https://stackoverflow.com/questions/31170845/powershell-find-driver-version

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!