我构建了这个程序,它运行良好,大约需要7-9秒才能运行和显示。 我想知道,是否有更快/最佳的方式来构建此自定义对象?
如您所见,我需要来自Win32_PNPsigneddriver
的所有驱动程序信息,但除此之外,我还根据以下信息从Win32_PNPentity
添加了两个其他属性(configmanagererrorcode
和status
):设备ID。
这样,最终对象将包含所有驱动程序,并显示使用该驱动程序的设备是否存在错误。
$poste = "COMPUTER1234"
$DriversUp = Get-WmiObject -computername $poste Win32_PNPsigneddriver |
Where-Object {$_.DeviceName -ne $null}
$Devices = Get-WmiObject -computername $poste Win32_PNPentity
$DriversDevices = foreach ($driver in $DriversUp) {
$driver |
Select-Object DeviceClass, Manufacturer, DeviceName,
FriendlyName, DriverName, InfName,
@{name='Status';expression={$Devices | Where-Object {$_.DeviceID -eq "$($driver.DeviceID)"} | Select-Object -ExpandProperty status}},
@{name='ConfigManagerErrorCode';expression={$Devices | Where-Object {$_.DeviceID -eq "$($driver.DeviceID)"} | Select-Object -ExpandProperty ConfigManagerErrorCode}},
@{name='DriverDate';expression={[DateTime]::ParseExact(($_.DriverDate).Split('.')[0], "yyyyMMddHHmmss", [System.Globalization.CultureInfo]::InvariantCulture)}},
DriverVersion
}
$DriversDevices |
Sort-Object DeviceClass |
Out-GridView -Title "$poste - Drivers utilisés"
就像我说的那样,一切都已经很好了。但是,我很好奇是否有更快的方法!
答案 0 :(得分:1)
瓶颈每次使用Where-Object
搜索设备。
以下代码使用Group-Object
解决了问题。
$poste = "COMPUTER1234"
$DriversUp = Get-WmiObject -ComputerName $poste Win32_PnPSignedDriver -Filter "DeviceName != NULL"
$Devices = Get-WmiObject -ComputerName $poste Win32_PnPEntity -Property DeviceID,Status,ConfigManagerErrorCode
@($DriversUp; $Devices) | Group-Object DeviceID | Where-Object Count -eq 2 | ForEach-Object {
$driver, $device = $_.Group
[pscustomobject]@{
DeviceClass = $driver.DeviceClass
Manufacturer = $driver.Manufacturer
DeviceName = $driver.DeviceName
FriendlyName = $driver.FriendlyName
DriverName = $driver.DriverName
InfName = $driver.InfName
Status = $device.Status
ConfigManagerErrorCode = $device.ConfigManagerErrorCode
DriverDate = [datetime]::ParseExact($driver.DriverDate.Substring(0, 14), "yyyyMMddHHmmss", $null)
DriverVersion = $driver.DriverVersion
}
} | Sort-Object DeviceClass | Out-GridView -Title "$poste - Drivers utilisés"
答案 1 :(得分:1)
从PowerShell 3.0开始,Get-WmiObject
cmdlet已被Get-CimInstance
取代。
$poste = "COMPUTER1234"
$cimses = New-CimSession -ComputerName $poste
$p = & {$args} DeviceClass Manufacturer DeviceName FriendlyName DriverName `
InfName DriverVersion DeviceID DriverDate
Get-CimInstance -CimSession $cimses -ClassName Win32_PnPSignedDriver `
-Property $p -Filter 'DeviceName != NULL' |
ForEach-Object {
$dev = Get-CimInstance -CimSession $cimses -ClassName Win32_PnPEntity `
-Property Status, ConfigManagerErrorCode `
-Filter "PNPDeviceID='$($_.DeviceID.Replace('\', '\\'))'"
[pscustomobject]@{
DeviceClass = $_.DeviceClass
Manufacturer = $_.Manufacturer
DeviceName = $_.DeviceName
FriendlyName = $_.FriendlyName
DriverName = $_.DriverName
InfName = $_.InfName
Status = $dev.Status
ConfigManagerErrorCode = $dev.ConfigManagerErrorCode
DriverDate = '{0:yyyyMMddHHmmss}' -f $_.DriverDate
DriverVersion = $_.DriverVersion
}
} | Sort-Object DeviceClass | Out-GridView -Title "$poste - Drivers utilisés"
Remove-CimSession -CimSession $cimses
在我的计算机上,Win32_PnPSignedDriver.DriverDate
成员的类型为DateTime
。
Get-CimClass -ClassName Win32_PnPSignedDriver |
Select-Object -ExpandProperty CimClassProperties |
Where-Object Name -eq 'DriverDate' |
Select-Object CimType | Format-Table -AutoSize
CimType
-------
DateTime
答案 2 :(得分:0)
这就是我要这样做的方式,在性能上并没有太大区别,但是更清晰的IMO:
使用ArrayList作为结果,还用Where-Object
替换了Get-WmiObject
上的-Filter
,速度更快了……
$poste = "COMPUTER1234"
$DriversUp = Get-WmiObject -computername $poste Win32_PNPsigneddriver -Filter "DeviceName != NULL"
$Devices = Get-WmiObject -computername $poste Win32_PNPentity
$DriversDevices = New-Object System.Collections.ArrayList
foreach ($driver in $DriversUp) {
$row = "" | Select DeviceClass,Manufacturer,DeviceName,FriendlyName,DriverName,
InfName,Status,ConfigManagerErrorCode,DriverDate,DriverVersion
$row.DeviceClass = $driver.DeviceClass
$row.Manufacturer = $driver.Manufacturer
$row.DeviceName = $driver.DeviceName
$row.DriverName = $driver.DriverName
$row.InfName = $driver.InfName
$row.Status = ($Devices | ? {$_.DeviceID -eq $driver.DeviceID}).Status
$row.ConfigManagerErrorCode = ($Devices | ? {$_.DeviceID -eq $driver.DeviceID}).ConfigManagerErrorCode
$row.DriverDate = [datetime]::ParseExact(($driver.DriverDate.Split('.')[0]),"yyyyMMddHHmmss",$null)
$row.DriverVersion = $driver.DriverVersion
[void]$DriversDevices.Add($row)
}
$DriversDevices | Sort-Object DeviceClass | Out-GridView -Title "$poste - Drivers utilisés"