首页 > 解决方案 > WMI 是否有损坏的关联类?(Win32_PnPSignedDriverCIMDataFile)

问题描述

我有一个Win32_PnPSignedDriverWMI 对象,我想找到它的所有文件。值得庆幸的是,Win32_PnPSignedDriverCIMDataFile这是一个关联类Win32_PnPSignedDriverCIM_DataFile。这应该可以很容易地从另一个中获取一个。

TL;博士

但是,在实践中,它不起作用,因为Win32_PnPSignedDriver和/或Win32_PnPSignedDriverCIMDataFile具有错误的密钥属性。

这真的是真的还是我做错了?

协会类

让我们通过以下方式获得一个示例性关联类实例

Get-WmiObject -Query "SELECT * FROM Win32_PnPSignedDriverCIMDataFile" |
  Where-Object Antecedent -Like "*Fax*" |
  Select-Object -Property Antecedent, Dependent | Format-List

经过相当长的延迟后,这会产生

Antecedent : \\PCNAME\ROOT\cimv2:Win32_PnPSignedDriver.DeviceID="Fax"
Dependent  : \\PCNAME\ROOT\cimv2:CIM_DataFile.Name="C:\\Windows\\system32\\spool\\DRIVERS\\x64\\3\\FXSDRV.DLL"

请注意,我使用 PowerShell 过滤传真设备(用于演示目的的最简单名称)。不幸的是,仅通过 WQL 获取对象是不可能的:

Get-WmiObject -Query "SELECT * FROM Win32_PnPSignedDriverCIMDataFile WHERE Antecedent LIKE '%Fax%'"
Get-WmiObject -Query "SELECT * FROM Win32_PnPSignedDriverCIMDataFile WHERE Antecedent='foobar'"
Get-WmiObject -Query "SELECT * FROM Win32_PnPSignedDriverCIMDataFile WHERE Dependent LIKE '%FXSDRV.DLL%'"
Get-WmiObject -Query "SELECT * FROM Win32_PnPSignedDriverCIMDataFile WHERE Dependent='foobar'"

所有这些都会产生无效的查询异常(对于任何“foobar”)。但是,这对于关联类来说似乎是正常的。

一个方向的关联者

但是我们无论如何都不应该查询关联对象。我们宁愿使用适当的ASSOCIATORS OF查询直接从Win32_PnPSignedDriverto CIM_DataFile

Get-WmiObject -Query "ASSOCIATORS OF {Win32_PnPSignedDriver.DeviceID='Fax'}"

哎呀。无效的对象路径异常。

在另一个方向

让我们反过来使用关联类:

$name = 'C:\Windows\system32\spool\DRIVERS\x64\3\FXSDRV.DLL'
Get-WmiObject -Query "ASSOCIATORS OF {CIM_DataFile.Name='$($name)'}" |
  foreach { $_.__CLASS }

此查询找到Win32_DirectoryWin32_LogicalFileSecuritySettingWin32_Printer对象,但没有找到任何Win32_PnPSignedDriver

甚至可以通过指定关联类来获取,例如,作为驱动程序的Win32_Printer对象CIM_DataFile

$name = 'C:\Windows\system32\spool\DRIVERS\x64\3\FXSDRV.DLL'
Get-WmiObject -Query `
  "ASSOCIATORS OF {CIM_DataFile.Name='$($name)'} WHERE AssocClass=Win32_PrinterDriverDll"

...或通过指定结果类:

$name = 'C:\Windows\system32\spool\DRIVERS\x64\3\FXSDRV.DLL'
Get-WmiObject -Query `
  "ASSOCIATORS OF {CIM_DataFile.Name='$($name)'} WHERE ResultClass=Win32_Printer"

指定Win32_PnPSignedDriverCIMDataFileWin32_PnPSignedDriver相同的方式需要很长时间,但不会产生任何结果:

$name = 'C:\Windows\system32\spool\DRIVERS\x64\3\FXSDRV.DLL'
Get-WmiObject -Query `
  "ASSOCIATORS OF {CIM_DataFile.Name='$($name)'} WHERE ResultClass=Win32_PnPSignedDriver"
Get-WmiObject -Query `
  "ASSOCIATORS OF {CIM_DataFile.Name='$($name)'} WHERE AssocClass=Win32_PnPSignedDriverCIMDataFile"

丢失的钥匙

那么为什么链接Win32_PnPSignedDriver失效了呢?事实证明,ASSOCIATORS OF仅适用于“关键”属性,而关键Win32_PnPSignedDrivernot DeviceIDbut Name

([wmiclass]"\\.\ROOT\CIMV2:Win32_PnPSignedDriver").Properties |
  Select-Object @{Name="PropertyName";Expression={$_.name}} -ExpandProperty Qualifiers |
  Where-Object { $_.Name -eq "key" } | ForEach-Object { $_.PropertyName }

不幸的是,Name我所有的Win32_PnPSignedDrivers 都是空的:

Get-WmiObject -Query "SELECT * FROM Win32_PnPSignedDriver" |
   Select-Object -Property Name | Where-Object { $null -ne $_.Name }

因此,即使Win32_PnPSignedDriverCIMDataFile引用Name而不是DeviceID,它也是无用的。

结论

似乎我必须自己查询所有Win32_PnPSignedDriverCIMDataFile对象并过滤匹配的对象,而 WQL 由于错误的键定义而无济于事,将关联类Win32_PnPSignedDriverCIMDataFile变成了无用的。

这真的是真的还是我错过了什么?

标签: powershellwmiwql

解决方案


推荐阅读