PowerShell 查找驱动程序版本
PowerShell Find Driver Version
使用 DevCon 实用程序,我 运行 此命令获取计算机中安装的所有驱动程序的列表。
devcon.exe driverfiles * > drivers.txt
输出如下所示:
USB\ROOT_HUB20&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
USB\ROOT_HUB20&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&361B340A&0 USB Root Hub C:\windows\INF\usbport.inf
USB\ROOT_HUB20&361B340A&0 USB Root Hub C:\windows\system32\drivers\usbhub.sys 6.3.9600.17238 (winblue_gdr.140723-2018)
USB\ROOT_HUB20&361B340A&0 USB Root Hub C:\windows\system32\drivers\usbd.sys 6.3.9600.17195 (winblue_gdr.140530-1506)
ACPI\PNP0C09
USB\ROOT_HUB20&361B340A&1 USB Root Hub C:\windows\INF\usbport.inf
USB\ROOT_HUB20&361B340A&1 USB Root Hub C:\windows\system32\drivers\usbhub.sys 6.3.9600.17238 (winblue_gdr.140723-2018)
USB\ROOT_HUB20&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
添加新列相对简单。列出这些列是因为它们是数组中对象的属性。所以现在我们有这样构建的对象(驱动程序行是相似的,然后我们将所有剩余的文件传递给它,添加换行符以便于阅读):
[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'。如果你想添加一列,你可以简单地插入另一个 属性。在这种情况下,您想要在名称旁边添加一个新列,其中包含每个项目的驱动程序版本。我们可以简单地重新调整当前输出每个项目的驱动程序文件路径(缺少版本号)的行:
[PSCustomObject]@{'HardwareID' = $HardwareID;'Name' = $Name; 'Files' = $Driver; 'FileVersion' = If(Test-Path $_.Trim()){[System.Diagnostics.FileVersionInfo]::GetVersionInfo($_.trim()).FileVersion}}
使用该行,我们可以删除其中试图列出 'FileVersion' 列中任何内容的位,并使用您提供的代码在其中为 'DriverVersion' 添加一个新位(有一些小的修改)。我们将把 $Pattern =
行移到脚本的第一行,因为我们不需要为循环的每次迭代重新分配它。然后我们会将您的其余代码分配给新的 'DriverVersion' 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&361B340A&0 USB Root Hub 6.3.9600.17238 C:\windows\INF\usbport.inf
USB\ROOT_HUB20&361B340A&0 USB Root Hub C:\windows\system32\drivers\usbhub.sys 6.3.9600.17238 (winblue_gdr.140723-2018)
USB\ROOT_HUB20&361B340A&0 USB Root Hub C:\windows\system32\drivers\usbd.sys 6.3.9600.17195 (winblue_gdr.140530-1506)
ACPI\PNP0C09
USB\ROOT_HUB20&361B340A&1 USB Root Hub 6.3.9600.17238 C:\windows\INF\usbport.inf
USB\ROOT_HUB20&361B340A&1 USB Root Hub C:\windows\system32\drivers\usbhub.sys 6.3.9600.17238 (winblue_gdr.140723-2018)
USB\ROOT_HUB20&361B340A&1 USB Root Hub C:\windows\system32\drivers\usbd.sys 6.3.9600.17195 (winblue_gdr.140530-1506)
ACPI\PNP0C09
USB\ROOT_HUB20&361B340A&2 6.3.9600.16384 C:\windows\INF\cmbatt.inf
USB\ROOT_HUB20&361B340A&2 C:\windows\system32\DRIVERS\CmBatt.sys 6.3.9600.16384 (winblue_rtm.130821-1623)
USB\ROOT_HUB20&361B340A&2 C:\windows\system32\DRIVERS\battc.sys 6.3.9600.16384 (winblue_rtm.130821-1623)
ACPI\PNP0C0A Microsoft ACPI-Compliant Control Method Battery 6.3.9600.16384 C:\windows\INF\cmbatt.inf
ACPI\PNP0C0A Microsoft ACPI-Compliant Control Method Battery C:\windows\system32\DRIVERS\CmBatt.sys 6.3.9600.16384 (winblue_rtm.130821-1623)
ACPI\PNP0C0A Microsoft ACPI-Compliant Control Method Battery C:\windows\system32\DRIVERS\battc.sys 6.3.9600.16384 (winblue_rtm.130821-1623)
使用 DevCon 实用程序,我 运行 此命令获取计算机中安装的所有驱动程序的列表。
devcon.exe driverfiles * > drivers.txt
输出如下所示:
USB\ROOT_HUB20&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
USB\ROOT_HUB20&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&361B340A&0 USB Root Hub C:\windows\INF\usbport.inf
USB\ROOT_HUB20&361B340A&0 USB Root Hub C:\windows\system32\drivers\usbhub.sys 6.3.9600.17238 (winblue_gdr.140723-2018)
USB\ROOT_HUB20&361B340A&0 USB Root Hub C:\windows\system32\drivers\usbd.sys 6.3.9600.17195 (winblue_gdr.140530-1506)
ACPI\PNP0C09
USB\ROOT_HUB20&361B340A&1 USB Root Hub C:\windows\INF\usbport.inf
USB\ROOT_HUB20&361B340A&1 USB Root Hub C:\windows\system32\drivers\usbhub.sys 6.3.9600.17238 (winblue_gdr.140723-2018)
USB\ROOT_HUB20&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
添加新列相对简单。列出这些列是因为它们是数组中对象的属性。所以现在我们有这样构建的对象(驱动程序行是相似的,然后我们将所有剩余的文件传递给它,添加换行符以便于阅读):
[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'。如果你想添加一列,你可以简单地插入另一个 属性。在这种情况下,您想要在名称旁边添加一个新列,其中包含每个项目的驱动程序版本。我们可以简单地重新调整当前输出每个项目的驱动程序文件路径(缺少版本号)的行:
[PSCustomObject]@{'HardwareID' = $HardwareID;'Name' = $Name; 'Files' = $Driver; 'FileVersion' = If(Test-Path $_.Trim()){[System.Diagnostics.FileVersionInfo]::GetVersionInfo($_.trim()).FileVersion}}
使用该行,我们可以删除其中试图列出 'FileVersion' 列中任何内容的位,并使用您提供的代码在其中为 'DriverVersion' 添加一个新位(有一些小的修改)。我们将把 $Pattern =
行移到脚本的第一行,因为我们不需要为循环的每次迭代重新分配它。然后我们会将您的其余代码分配给新的 'DriverVersion' 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&361B340A&0 USB Root Hub 6.3.9600.17238 C:\windows\INF\usbport.inf
USB\ROOT_HUB20&361B340A&0 USB Root Hub C:\windows\system32\drivers\usbhub.sys 6.3.9600.17238 (winblue_gdr.140723-2018)
USB\ROOT_HUB20&361B340A&0 USB Root Hub C:\windows\system32\drivers\usbd.sys 6.3.9600.17195 (winblue_gdr.140530-1506)
ACPI\PNP0C09
USB\ROOT_HUB20&361B340A&1 USB Root Hub 6.3.9600.17238 C:\windows\INF\usbport.inf
USB\ROOT_HUB20&361B340A&1 USB Root Hub C:\windows\system32\drivers\usbhub.sys 6.3.9600.17238 (winblue_gdr.140723-2018)
USB\ROOT_HUB20&361B340A&1 USB Root Hub C:\windows\system32\drivers\usbd.sys 6.3.9600.17195 (winblue_gdr.140530-1506)
ACPI\PNP0C09
USB\ROOT_HUB20&361B340A&2 6.3.9600.16384 C:\windows\INF\cmbatt.inf
USB\ROOT_HUB20&361B340A&2 C:\windows\system32\DRIVERS\CmBatt.sys 6.3.9600.16384 (winblue_rtm.130821-1623)
USB\ROOT_HUB20&361B340A&2 C:\windows\system32\DRIVERS\battc.sys 6.3.9600.16384 (winblue_rtm.130821-1623)
ACPI\PNP0C0A Microsoft ACPI-Compliant Control Method Battery 6.3.9600.16384 C:\windows\INF\cmbatt.inf
ACPI\PNP0C0A Microsoft ACPI-Compliant Control Method Battery C:\windows\system32\DRIVERS\CmBatt.sys 6.3.9600.16384 (winblue_rtm.130821-1623)
ACPI\PNP0C0A Microsoft ACPI-Compliant Control Method Battery C:\windows\system32\DRIVERS\battc.sys 6.3.9600.16384 (winblue_rtm.130821-1623)