Powershell 中的 WMI 查询 'Invalid query'
WMI queries in powershell 'Invalid query'
正在尝试了解有关 WMI 和 powershell(noob) 命令的更多信息。
运行这个:
Get-WMIObject -Namespace root\Subscription -Class __FilterToConsumerBinding
给我这个(很好):
__GENUS : 2
__CLASS : __FilterToConsumerBinding
__SUPERCLASS : __IndicationRelated
__DYNASTY : __SystemClass
__RELPATH : __FilterToConsumerBinding.Consumer="NTEventLogEventConsumer.Name=\"SCM Event Log Consumer\"",Filter="__EventFilter.Name=\"SCM Event Log Filter\""
__PROPERTY_COUNT : 7
__DERIVATION : {__IndicationRelated, __SystemClass}
__SERVER : COMPUTERNAME
__NAMESPACE : ROOT\Subscription
__PATH : \COMPUTERNAME\ROOT\Subscription:__FilterToConsumerBinding.Consumer="NTEventLogEventConsumer.Name=\"SCM Event Log Consumer\"",Filter="__EventFilter.Name=\"SCM Event Log Filter\""
Consumer : NTEventLogEventConsumer.Name="SCM Event Log Consumer"
CreatorSID : {1, 2, 0, 0...}
DeliverSynchronously : False
DeliveryQoS :
Filter : __EventFilter.Name="SCM Event Log Filter"
MaintainSecurityContext : False
SlowDownProviders : False
PSComputerName : COMPUTERNAME
为什么这个查询给我的结果和上面一样:
Get-WMIObject -Namespace root\Subscription -Class __FilterToConsumerBinding -Filter "__PATH LIKE '%SCM%'"
但是这个,在'Filter'中寻找文本:
Get-WMIObject -Namespace root\Subscription -Class __FilterToConsumerBinding -Filter "Filter LIKE '%SCM%'"`
给我一个无效的查询错误
Get-WMIObject : Invalid query "select * from __FilterToConsumerBinding where Filter LIKE '%SCM%'"
At line:1 char:1
+ Get-WMIObject -Namespace root\Subscription -Class __FilterToConsumerB ...
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : InvalidArgument: (:) [Get-WmiObject], ManagementException
+ FullyQualifiedErrorId : GetWMIManagementException,Microsoft.PowerShell.Commands.GetWmiObjectCommand
我不明白为什么同一个查询对两个对象都不起作用?
谢谢!
对 EventConsumer 也不起作用,但对 EventFilter 起作用!
Get-WMIObject -Namespace root\Subscription -Class __EventFilter -Filter "Name LIKE '%SCM%'"
__GENUS : 2
__CLASS : __EventFilter
__SUPERCLASS : __IndicationRelated
__DYNASTY : __SystemClass
__RELPATH : __EventFilter.Name="SCM Event Log Filter"
__PROPERTY_COUNT : 6
__DERIVATION : {__IndicationRelated, __SystemClass}
__SERVER : COMPUTERNAME
__NAMESPACE : ROOT\Subscription
__PATH : \COMPUTERNAME\ROOT\Subscription:__EventFilter.Name="SCM Event Log Filter"
CreatorSID : {1, 2, 0, 0...}
EventAccess :
EventNamespace : root\cimv2
Name : SCM Event Log Filter
Query : select * from MSFT_SCMEventLogEvent
QueryLanguage : WQL
PSComputerName : COMPUTERNAME
简短回答...您过滤 属性 的能力取决于它是哪种 WMI Class 以及 属性 类型是什么。
长答案...要在 PowerShell 中获取有关 WMI class 的更多信息,请使用 Get-CimClass cmdlet。属性可以根据它们 return 的数据具有不同的值类型(即字符串、整数、布尔值)。在您的示例中,您正在尝试查询 属性 "Filter" 这是一个引用类型。引用类型没有文字值,它只是对另一个 class 实例的引用。您可以告诉参考 属性 因为它显示了另一个 class 的完整或部分路径(正如您在示例中看到的那样,“__EventFilter”被引用了。您还可以获得 属性 从这个 powershell 命令输入信息:
Get-CimClass -Namespace "root\Subscription" -Class __FilterToConsumerBinding | Select-Object -ExpandProperty CimClassProperties | Where-Object {$_.Name -eq 'Filter'}
引用类型属性显示在 WMI classes 上,其中一个名为 "Association" 的 class 限定符设置为 true。 Class 限定符是 class 本身的属性,它指示 class 的行为方式。您可以使用此命令查看所有 class 限定符。
Get-CimClass -Namespace "root\Subscription" -Class __FilterToConsumerBinding | Select-Object -ExpandProperty CimClassQualifiers
不幸的是,由于 WQL 是一种查询语言,您无法使用 WHERE 子句根据具有引用类型的属性过滤 class 的实例。您只能使用简单类型,例如字符串、整数或嵌入对象的 属性(尽管嵌入对象极为罕见)。
由于 class __EventFilter 是 "Filter" 属性 引用的内容,并且 class 确实具有简单的 属性 类型,我们可以从那里开始。可以通过Name属性查询__EventFilter,是字符串类型,没有问题。
有一些高级查询技术(ASSOCIATORS OF
和 REFERENCES OF
)可以帮助您通过基于引用的查询从 __FilterToConsumerBinding 获取实例,但这是一个多步骤过程。我建议查看有关它的 Microsoft Doc Microsoft Doc WQL,但这里有一个基本的两步 PowerShell 命令,它将首先获取引用实例的名称,然后获取引用它的任何实例。
$InstanceName = (Get-WmiObject -Namespace "ROOT\subscription" -Query "SELECT * FROM __EventFilter WHERE Name LIKE '%SCM%'").Name
Get-WmiObject -Namespace "ROOT\subscription" -Query "REFERENCES OF {__EventFilter.Name='$InstanceName'}"
由于 REFERENCES OF
将搜索整个命名空间,您可以通过添加 WHERE 子句并将结果 Class 命名为目标 [=60] 将结果缩小到特定的 class =].修改后的第二行命令现在是
Get-WmiObject -Namespace "ROOT\subscription" -Query "REFERENCES OF {__EventFilter.Name='$InstanceName'} WHERE ResultClass = __FilterToConsumerBinding"
这应该 return 您正在寻找的实例仅来自 __FilterToConsumerBinding。 (*请注意,class 名称周围没有引号。包括双引号或单引号将产生无效查询错误。
要回答您关于 __EventConsumer class 的问题,这会引出另一个 WMI 概念,称为抽象 classes。我不会详细介绍这个,但是抽象 class 本质上是其他 classes 可以继承的基础 class(其他 classes 的起点) .但是,与标准基础 classes 不同,抽象 classes 不能有自己的实例。您可以通过获取 __EventConsumer class 的 class 限定符来确定 class 是否是抽象的。您会注意到,如果您 运行 下面的命令,您会看到它具有 "abstract" class 限定符。
Get-CimClass -Namespace "root\Subscription" -Class __EventConsumer | Select-Object -ExpandProperty CimClassQualifiers
由于抽象 class 本身不能包含任何实例,如果您枚举它,它将 return 个实例用于所有使用它作为基础的 class 实例 class。在您的示例中,__EventConsumer 实际上是从 NTEventLogEventConsumer 生成一个实例。由于枚举了一个抽象 class return 多个不同的 classes ,因此不会总是承诺过滤相同的属性,因此不允许过滤,除非您过滤 属性 包含在基数 class 中。要查看 WMI class 的基数 class 是什么,您可以使用此命令并查看 NTEventLogEventConsumer 的基数 class 是 __EventConsumer.
Get-CimClass -Namespace "root\Subscription" -Class NTEventLogEventConsumer | Select-Object -ExpandProperty CimSuperClassName
您通常可以使用查询 SELECT * FROM __EventConsumer
从抽象 class 中枚举所有实例。这将显示所有实例,但是一旦您添加一个带有 属性 的 WHERE 子句未包含在基础 class 中,您要么收到无效查询,要么没有实例将被 returned。这就是为什么可以直接查询NTEventLogEventConsumer而不能直接查询的原因__EventConsumer.
希望这对您有所帮助。
正在尝试了解有关 WMI 和 powershell(noob) 命令的更多信息。
运行这个:
Get-WMIObject -Namespace root\Subscription -Class __FilterToConsumerBinding
给我这个(很好):
__GENUS : 2
__CLASS : __FilterToConsumerBinding
__SUPERCLASS : __IndicationRelated
__DYNASTY : __SystemClass
__RELPATH : __FilterToConsumerBinding.Consumer="NTEventLogEventConsumer.Name=\"SCM Event Log Consumer\"",Filter="__EventFilter.Name=\"SCM Event Log Filter\""
__PROPERTY_COUNT : 7
__DERIVATION : {__IndicationRelated, __SystemClass}
__SERVER : COMPUTERNAME
__NAMESPACE : ROOT\Subscription
__PATH : \COMPUTERNAME\ROOT\Subscription:__FilterToConsumerBinding.Consumer="NTEventLogEventConsumer.Name=\"SCM Event Log Consumer\"",Filter="__EventFilter.Name=\"SCM Event Log Filter\""
Consumer : NTEventLogEventConsumer.Name="SCM Event Log Consumer"
CreatorSID : {1, 2, 0, 0...}
DeliverSynchronously : False
DeliveryQoS :
Filter : __EventFilter.Name="SCM Event Log Filter"
MaintainSecurityContext : False
SlowDownProviders : False
PSComputerName : COMPUTERNAME
为什么这个查询给我的结果和上面一样:
Get-WMIObject -Namespace root\Subscription -Class __FilterToConsumerBinding -Filter "__PATH LIKE '%SCM%'"
但是这个,在'Filter'中寻找文本:
Get-WMIObject -Namespace root\Subscription -Class __FilterToConsumerBinding -Filter "Filter LIKE '%SCM%'"`
给我一个无效的查询错误
Get-WMIObject : Invalid query "select * from __FilterToConsumerBinding where Filter LIKE '%SCM%'"
At line:1 char:1
+ Get-WMIObject -Namespace root\Subscription -Class __FilterToConsumerB ...
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : InvalidArgument: (:) [Get-WmiObject], ManagementException
+ FullyQualifiedErrorId : GetWMIManagementException,Microsoft.PowerShell.Commands.GetWmiObjectCommand
我不明白为什么同一个查询对两个对象都不起作用? 谢谢!
对 EventConsumer 也不起作用,但对 EventFilter 起作用!
Get-WMIObject -Namespace root\Subscription -Class __EventFilter -Filter "Name LIKE '%SCM%'"
__GENUS : 2
__CLASS : __EventFilter
__SUPERCLASS : __IndicationRelated
__DYNASTY : __SystemClass
__RELPATH : __EventFilter.Name="SCM Event Log Filter"
__PROPERTY_COUNT : 6
__DERIVATION : {__IndicationRelated, __SystemClass}
__SERVER : COMPUTERNAME
__NAMESPACE : ROOT\Subscription
__PATH : \COMPUTERNAME\ROOT\Subscription:__EventFilter.Name="SCM Event Log Filter"
CreatorSID : {1, 2, 0, 0...}
EventAccess :
EventNamespace : root\cimv2
Name : SCM Event Log Filter
Query : select * from MSFT_SCMEventLogEvent
QueryLanguage : WQL
PSComputerName : COMPUTERNAME
简短回答...您过滤 属性 的能力取决于它是哪种 WMI Class 以及 属性 类型是什么。
长答案...要在 PowerShell 中获取有关 WMI class 的更多信息,请使用 Get-CimClass cmdlet。属性可以根据它们 return 的数据具有不同的值类型(即字符串、整数、布尔值)。在您的示例中,您正在尝试查询 属性 "Filter" 这是一个引用类型。引用类型没有文字值,它只是对另一个 class 实例的引用。您可以告诉参考 属性 因为它显示了另一个 class 的完整或部分路径(正如您在示例中看到的那样,“__EventFilter”被引用了。您还可以获得 属性 从这个 powershell 命令输入信息:
Get-CimClass -Namespace "root\Subscription" -Class __FilterToConsumerBinding | Select-Object -ExpandProperty CimClassProperties | Where-Object {$_.Name -eq 'Filter'}
引用类型属性显示在 WMI classes 上,其中一个名为 "Association" 的 class 限定符设置为 true。 Class 限定符是 class 本身的属性,它指示 class 的行为方式。您可以使用此命令查看所有 class 限定符。
Get-CimClass -Namespace "root\Subscription" -Class __FilterToConsumerBinding | Select-Object -ExpandProperty CimClassQualifiers
不幸的是,由于 WQL 是一种查询语言,您无法使用 WHERE 子句根据具有引用类型的属性过滤 class 的实例。您只能使用简单类型,例如字符串、整数或嵌入对象的 属性(尽管嵌入对象极为罕见)。
由于 class __EventFilter 是 "Filter" 属性 引用的内容,并且 class 确实具有简单的 属性 类型,我们可以从那里开始。可以通过Name属性查询__EventFilter,是字符串类型,没有问题。
有一些高级查询技术(ASSOCIATORS OF
和 REFERENCES OF
)可以帮助您通过基于引用的查询从 __FilterToConsumerBinding 获取实例,但这是一个多步骤过程。我建议查看有关它的 Microsoft Doc Microsoft Doc WQL,但这里有一个基本的两步 PowerShell 命令,它将首先获取引用实例的名称,然后获取引用它的任何实例。
$InstanceName = (Get-WmiObject -Namespace "ROOT\subscription" -Query "SELECT * FROM __EventFilter WHERE Name LIKE '%SCM%'").Name
Get-WmiObject -Namespace "ROOT\subscription" -Query "REFERENCES OF {__EventFilter.Name='$InstanceName'}"
由于 REFERENCES OF
将搜索整个命名空间,您可以通过添加 WHERE 子句并将结果 Class 命名为目标 [=60] 将结果缩小到特定的 class =].修改后的第二行命令现在是
Get-WmiObject -Namespace "ROOT\subscription" -Query "REFERENCES OF {__EventFilter.Name='$InstanceName'} WHERE ResultClass = __FilterToConsumerBinding"
这应该 return 您正在寻找的实例仅来自 __FilterToConsumerBinding。 (*请注意,class 名称周围没有引号。包括双引号或单引号将产生无效查询错误。
要回答您关于 __EventConsumer class 的问题,这会引出另一个 WMI 概念,称为抽象 classes。我不会详细介绍这个,但是抽象 class 本质上是其他 classes 可以继承的基础 class(其他 classes 的起点) .但是,与标准基础 classes 不同,抽象 classes 不能有自己的实例。您可以通过获取 __EventConsumer class 的 class 限定符来确定 class 是否是抽象的。您会注意到,如果您 运行 下面的命令,您会看到它具有 "abstract" class 限定符。
Get-CimClass -Namespace "root\Subscription" -Class __EventConsumer | Select-Object -ExpandProperty CimClassQualifiers
由于抽象 class 本身不能包含任何实例,如果您枚举它,它将 return 个实例用于所有使用它作为基础的 class 实例 class。在您的示例中,__EventConsumer 实际上是从 NTEventLogEventConsumer 生成一个实例。由于枚举了一个抽象 class return 多个不同的 classes ,因此不会总是承诺过滤相同的属性,因此不允许过滤,除非您过滤 属性 包含在基数 class 中。要查看 WMI class 的基数 class 是什么,您可以使用此命令并查看 NTEventLogEventConsumer 的基数 class 是 __EventConsumer.
Get-CimClass -Namespace "root\Subscription" -Class NTEventLogEventConsumer | Select-Object -ExpandProperty CimSuperClassName
您通常可以使用查询 SELECT * FROM __EventConsumer
从抽象 class 中枚举所有实例。这将显示所有实例,但是一旦您添加一个带有 属性 的 WHERE 子句未包含在基础 class 中,您要么收到无效查询,要么没有实例将被 returned。这就是为什么可以直接查询NTEventLogEventConsumer而不能直接查询的原因__EventConsumer.
希望这对您有所帮助。