WMI queries in powershell 'Invalid query'
up vote
1
down vote
favorite
Trying to learn more about WMI and powershell(noob) commands.
Running this:
Get-WMIObject -Namespace rootSubscription -Class __FilterToConsumerBinding
Gets me this(fine):
__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 : ROOTSubscription
__PATH : COMPUTERNAMEROOTSubscription:__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
Why does this query give me the same result as above:
Get-WMIObject -Namespace rootSubscription -Class __FilterToConsumerBinding -Filter "__PATH LIKE '%SCM%'"
But this one, looking for the text in 'Filter' :
Get-WMIObject -Namespace rootSubscription -Class __FilterToConsumerBinding -Filter "Filter LIKE '%SCM%'"`
gives me an invalid query error
Get-WMIObject : Invalid query "select * from __FilterToConsumerBinding where Filter LIKE '%SCM%'"
At line:1 char:1
+ Get-WMIObject -Namespace rootSubscription -Class __FilterToConsumerB ...
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : InvalidArgument: (:) [Get-WmiObject], ManagementException
+ FullyQualifiedErrorId : GetWMIManagementException,Microsoft.PowerShell.Commands.GetWmiObjectCommand
I don't get it why doesn't the same query work on both objects?
Thanks!
Doesn't work on EventConsumer either but it does work on EventFilter!
Get-WMIObject -Namespace rootSubscription -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 : ROOTSubscription
__PATH : \COMPUTERNAMEROOTSubscription:__EventFilter.Name="SCM Event Log Filter"
CreatorSID : {1, 2, 0, 0...}
EventAccess :
EventNamespace : rootcimv2
Name : SCM Event Log Filter
Query : select * from MSFT_SCMEventLogEvent
QueryLanguage : WQL
PSComputerName : COMPUTERNAME
powershell wmi get-wmiobject
|
show 1 more comment
up vote
1
down vote
favorite
Trying to learn more about WMI and powershell(noob) commands.
Running this:
Get-WMIObject -Namespace rootSubscription -Class __FilterToConsumerBinding
Gets me this(fine):
__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 : ROOTSubscription
__PATH : COMPUTERNAMEROOTSubscription:__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
Why does this query give me the same result as above:
Get-WMIObject -Namespace rootSubscription -Class __FilterToConsumerBinding -Filter "__PATH LIKE '%SCM%'"
But this one, looking for the text in 'Filter' :
Get-WMIObject -Namespace rootSubscription -Class __FilterToConsumerBinding -Filter "Filter LIKE '%SCM%'"`
gives me an invalid query error
Get-WMIObject : Invalid query "select * from __FilterToConsumerBinding where Filter LIKE '%SCM%'"
At line:1 char:1
+ Get-WMIObject -Namespace rootSubscription -Class __FilterToConsumerB ...
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : InvalidArgument: (:) [Get-WmiObject], ManagementException
+ FullyQualifiedErrorId : GetWMIManagementException,Microsoft.PowerShell.Commands.GetWmiObjectCommand
I don't get it why doesn't the same query work on both objects?
Thanks!
Doesn't work on EventConsumer either but it does work on EventFilter!
Get-WMIObject -Namespace rootSubscription -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 : ROOTSubscription
__PATH : \COMPUTERNAMEROOTSubscription:__EventFilter.Name="SCM Event Log Filter"
CreatorSID : {1, 2, 0, 0...}
EventAccess :
EventNamespace : rootcimv2
Name : SCM Event Log Filter
Query : select * from MSFT_SCMEventLogEvent
QueryLanguage : WQL
PSComputerName : COMPUTERNAME
powershell wmi get-wmiobject
1
I suspect becauseFilter
is generated by powershell on that object and what you actually want is something likeName LIKE '%SCM%'
– TheIncorrigible1
Nov 21 at 21:53
Thanks for the answer @TheIncorrigible1 I tried to edit above, it did let me query the property filter.
– JohnRain
Nov 22 at 0:08
No where in your question are you querying aFilter
property on the\.rootSubscription:__FilterToConsumerBinding
class.
– TheIncorrigible1
Nov 22 at 0:13
Get-WMIObject -Namespace rootSubscription -Class __FilterToConsumerBinding | Select Filter (was that not right?)
– JohnRain
Nov 22 at 0:30
Select-Object -Property Filter
is not a query. It's just selecting a property and turning it into apscustomobject
. Like I said, powershell creates that property for you to be nice.
– TheIncorrigible1
Nov 22 at 0:31
|
show 1 more comment
up vote
1
down vote
favorite
up vote
1
down vote
favorite
Trying to learn more about WMI and powershell(noob) commands.
Running this:
Get-WMIObject -Namespace rootSubscription -Class __FilterToConsumerBinding
Gets me this(fine):
__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 : ROOTSubscription
__PATH : COMPUTERNAMEROOTSubscription:__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
Why does this query give me the same result as above:
Get-WMIObject -Namespace rootSubscription -Class __FilterToConsumerBinding -Filter "__PATH LIKE '%SCM%'"
But this one, looking for the text in 'Filter' :
Get-WMIObject -Namespace rootSubscription -Class __FilterToConsumerBinding -Filter "Filter LIKE '%SCM%'"`
gives me an invalid query error
Get-WMIObject : Invalid query "select * from __FilterToConsumerBinding where Filter LIKE '%SCM%'"
At line:1 char:1
+ Get-WMIObject -Namespace rootSubscription -Class __FilterToConsumerB ...
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : InvalidArgument: (:) [Get-WmiObject], ManagementException
+ FullyQualifiedErrorId : GetWMIManagementException,Microsoft.PowerShell.Commands.GetWmiObjectCommand
I don't get it why doesn't the same query work on both objects?
Thanks!
Doesn't work on EventConsumer either but it does work on EventFilter!
Get-WMIObject -Namespace rootSubscription -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 : ROOTSubscription
__PATH : \COMPUTERNAMEROOTSubscription:__EventFilter.Name="SCM Event Log Filter"
CreatorSID : {1, 2, 0, 0...}
EventAccess :
EventNamespace : rootcimv2
Name : SCM Event Log Filter
Query : select * from MSFT_SCMEventLogEvent
QueryLanguage : WQL
PSComputerName : COMPUTERNAME
powershell wmi get-wmiobject
Trying to learn more about WMI and powershell(noob) commands.
Running this:
Get-WMIObject -Namespace rootSubscription -Class __FilterToConsumerBinding
Gets me this(fine):
__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 : ROOTSubscription
__PATH : COMPUTERNAMEROOTSubscription:__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
Why does this query give me the same result as above:
Get-WMIObject -Namespace rootSubscription -Class __FilterToConsumerBinding -Filter "__PATH LIKE '%SCM%'"
But this one, looking for the text in 'Filter' :
Get-WMIObject -Namespace rootSubscription -Class __FilterToConsumerBinding -Filter "Filter LIKE '%SCM%'"`
gives me an invalid query error
Get-WMIObject : Invalid query "select * from __FilterToConsumerBinding where Filter LIKE '%SCM%'"
At line:1 char:1
+ Get-WMIObject -Namespace rootSubscription -Class __FilterToConsumerB ...
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : InvalidArgument: (:) [Get-WmiObject], ManagementException
+ FullyQualifiedErrorId : GetWMIManagementException,Microsoft.PowerShell.Commands.GetWmiObjectCommand
I don't get it why doesn't the same query work on both objects?
Thanks!
Doesn't work on EventConsumer either but it does work on EventFilter!
Get-WMIObject -Namespace rootSubscription -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 : ROOTSubscription
__PATH : \COMPUTERNAMEROOTSubscription:__EventFilter.Name="SCM Event Log Filter"
CreatorSID : {1, 2, 0, 0...}
EventAccess :
EventNamespace : rootcimv2
Name : SCM Event Log Filter
Query : select * from MSFT_SCMEventLogEvent
QueryLanguage : WQL
PSComputerName : COMPUTERNAME
powershell wmi get-wmiobject
powershell wmi get-wmiobject
edited Nov 22 at 0:43
asked Nov 21 at 21:41
JohnRain
218
218
1
I suspect becauseFilter
is generated by powershell on that object and what you actually want is something likeName LIKE '%SCM%'
– TheIncorrigible1
Nov 21 at 21:53
Thanks for the answer @TheIncorrigible1 I tried to edit above, it did let me query the property filter.
– JohnRain
Nov 22 at 0:08
No where in your question are you querying aFilter
property on the\.rootSubscription:__FilterToConsumerBinding
class.
– TheIncorrigible1
Nov 22 at 0:13
Get-WMIObject -Namespace rootSubscription -Class __FilterToConsumerBinding | Select Filter (was that not right?)
– JohnRain
Nov 22 at 0:30
Select-Object -Property Filter
is not a query. It's just selecting a property and turning it into apscustomobject
. Like I said, powershell creates that property for you to be nice.
– TheIncorrigible1
Nov 22 at 0:31
|
show 1 more comment
1
I suspect becauseFilter
is generated by powershell on that object and what you actually want is something likeName LIKE '%SCM%'
– TheIncorrigible1
Nov 21 at 21:53
Thanks for the answer @TheIncorrigible1 I tried to edit above, it did let me query the property filter.
– JohnRain
Nov 22 at 0:08
No where in your question are you querying aFilter
property on the\.rootSubscription:__FilterToConsumerBinding
class.
– TheIncorrigible1
Nov 22 at 0:13
Get-WMIObject -Namespace rootSubscription -Class __FilterToConsumerBinding | Select Filter (was that not right?)
– JohnRain
Nov 22 at 0:30
Select-Object -Property Filter
is not a query. It's just selecting a property and turning it into apscustomobject
. Like I said, powershell creates that property for you to be nice.
– TheIncorrigible1
Nov 22 at 0:31
1
1
I suspect because
Filter
is generated by powershell on that object and what you actually want is something like Name LIKE '%SCM%'
– TheIncorrigible1
Nov 21 at 21:53
I suspect because
Filter
is generated by powershell on that object and what you actually want is something like Name LIKE '%SCM%'
– TheIncorrigible1
Nov 21 at 21:53
Thanks for the answer @TheIncorrigible1 I tried to edit above, it did let me query the property filter.
– JohnRain
Nov 22 at 0:08
Thanks for the answer @TheIncorrigible1 I tried to edit above, it did let me query the property filter.
– JohnRain
Nov 22 at 0:08
No where in your question are you querying a
Filter
property on the \.rootSubscription:__FilterToConsumerBinding
class.– TheIncorrigible1
Nov 22 at 0:13
No where in your question are you querying a
Filter
property on the \.rootSubscription:__FilterToConsumerBinding
class.– TheIncorrigible1
Nov 22 at 0:13
Get-WMIObject -Namespace rootSubscription -Class __FilterToConsumerBinding | Select Filter (was that not right?)
– JohnRain
Nov 22 at 0:30
Get-WMIObject -Namespace rootSubscription -Class __FilterToConsumerBinding | Select Filter (was that not right?)
– JohnRain
Nov 22 at 0:30
Select-Object -Property Filter
is not a query. It's just selecting a property and turning it into a pscustomobject
. Like I said, powershell creates that property for you to be nice.– TheIncorrigible1
Nov 22 at 0:31
Select-Object -Property Filter
is not a query. It's just selecting a property and turning it into a pscustomobject
. Like I said, powershell creates that property for you to be nice.– TheIncorrigible1
Nov 22 at 0:31
|
show 1 more comment
1 Answer
1
active
oldest
votes
up vote
1
down vote
accepted
Short answer... your ability to filter on a property depends on what kind of WMI Class it is and what the property types are.
Long answer... To get more information about a WMI class in PowerShell, use the Get-CimClass cmdlet. Properties can have different value types based on the data they return (ie String, Integers, Boolean). In your example, you are trying to query the property "Filter" which is a reference type. A reference type doesn't have a literal value, it is just a reference to an instance from another class. You can tell a reference property because it shows a full or partial path to another class (as you saw in your example "__EventFilter" was referenced. You can also get the property type information from this powershell command:
Get-CimClass -Namespace "rootSubscription" -Class __FilterToConsumerBinding | Select-Object -ExpandProperty CimClassProperties | Where-Object {$_.Name -eq 'Filter'}
Reference type properties show up on WMI classes that have a class qualifier called "Association" set to true. Class qualifiers are properties for the class itself that dictate how the class behaves. You can see all the class qualifiers using this command.
Get-CimClass -Namespace "rootSubscription" -Class __FilterToConsumerBinding | Select-Object -ExpandProperty CimClassQualifiers
Unfortunately, Since WQL is a query language you cannot filter instances of a class based on properties with a reference type using a WHERE clause. You can only use simple types such as a string, integer, or property of an embedded object (embedded objects are extremely rare though).
Since the class __EventFilter is whats referenced by the "Filter" property, and that class DOES has simple property types we can start from there. You can query __EventFilter by the Name property, which is a string type, without any problem.
There are some advanced query techniques (ASSOCIATORS OF
and REFERENCES OF
) that can help you get the instance from __FilterToConsumerBinding with queries based on references but its a multi-step process. I'd recommend checking out the Microsoft Doc on it Microsoft Doc WQL but here is a basic two step PowerShell command that will first get the name of the referenced instance then any instances that reference it.
$InstanceName = (Get-WmiObject -Namespace "ROOTsubscription" -Query "SELECT * FROM __EventFilter WHERE Name LIKE '%SCM%'").Name
Get-WmiObject -Namespace "ROOTsubscription" -Query "REFERENCES OF {__EventFilter.Name='$InstanceName'}"
Since REFERENCES OF
will search an entire namespace you can narrow your results down to a specific class by adding a WHERE clause and naming the ResultClass as your target class. The revised second line of your command would now be
Get-WmiObject -Namespace "ROOTsubscription" -Query "REFERENCES OF {__EventFilter.Name='$InstanceName'} WHERE ResultClass = __FilterToConsumerBinding"
This should return the instance you are looking for only from __FilterToConsumerBinding. (*Note that there are no quotes around the class name. Including double or single quotes will give an invalid query error.
To answer your question about the __EventConsumer class, this brings up another WMI concept called abstract classes. I won't go into too much detail about this but an abstract class is essentially a base class (starting point for other classes) that other classes can inherit. Unlike standard base classes, though, abstract classes can not have its own instances. You can find out if a class is abstract by getting the class qualifiers of the __EventConsumer class. You'll notice if you run the command below, you will see it has the "abstract" class qualifier.
Get-CimClass -Namespace "rootSubscription" -Class __EventConsumer | Select-Object -ExpandProperty CimClassQualifiers
Since an abstract class can't contain any instances itself, if you enumerate it, it will return instances for all the classes that use it as a base class. In your example, __EventConsumer is actually yielding an instance from NTEventLogEventConsumer. Since enumerating an abstract class returns a number of different classes there would not always be the promise of the same properties to filter by so filtering is not allowed unless you are filtering on a property that is contained in the base class. To see what the base class of a WMI class is, you can use this command and see that the base class for NTEventLogEventConsumer is __EventConsumer.
Get-CimClass -Namespace "rootSubscription" -Class NTEventLogEventConsumer | Select-Object -ExpandProperty CimSuperClassName
You can usually enumerate all instances from an abstract class using the query SELECT * FROM __EventConsumer
. This will show all instances but once you add a WHERE clause with a property not included in the base class, you either receive invalid query or no instances will be returned. This is the reason why you can directly query NTEventLogEventConsumer but not __EventConsumer.
Hope this helps.
Holy cow I am reading and re-reading this to try and grasp it and understand it! I love explanations with the answers, to me that's the whole purpose of stackoverflow. Thank you, I'll spend the next week or so working on your answer!
– JohnRain
Nov 26 at 1:40
add a comment |
1 Answer
1
active
oldest
votes
1 Answer
1
active
oldest
votes
active
oldest
votes
active
oldest
votes
up vote
1
down vote
accepted
Short answer... your ability to filter on a property depends on what kind of WMI Class it is and what the property types are.
Long answer... To get more information about a WMI class in PowerShell, use the Get-CimClass cmdlet. Properties can have different value types based on the data they return (ie String, Integers, Boolean). In your example, you are trying to query the property "Filter" which is a reference type. A reference type doesn't have a literal value, it is just a reference to an instance from another class. You can tell a reference property because it shows a full or partial path to another class (as you saw in your example "__EventFilter" was referenced. You can also get the property type information from this powershell command:
Get-CimClass -Namespace "rootSubscription" -Class __FilterToConsumerBinding | Select-Object -ExpandProperty CimClassProperties | Where-Object {$_.Name -eq 'Filter'}
Reference type properties show up on WMI classes that have a class qualifier called "Association" set to true. Class qualifiers are properties for the class itself that dictate how the class behaves. You can see all the class qualifiers using this command.
Get-CimClass -Namespace "rootSubscription" -Class __FilterToConsumerBinding | Select-Object -ExpandProperty CimClassQualifiers
Unfortunately, Since WQL is a query language you cannot filter instances of a class based on properties with a reference type using a WHERE clause. You can only use simple types such as a string, integer, or property of an embedded object (embedded objects are extremely rare though).
Since the class __EventFilter is whats referenced by the "Filter" property, and that class DOES has simple property types we can start from there. You can query __EventFilter by the Name property, which is a string type, without any problem.
There are some advanced query techniques (ASSOCIATORS OF
and REFERENCES OF
) that can help you get the instance from __FilterToConsumerBinding with queries based on references but its a multi-step process. I'd recommend checking out the Microsoft Doc on it Microsoft Doc WQL but here is a basic two step PowerShell command that will first get the name of the referenced instance then any instances that reference it.
$InstanceName = (Get-WmiObject -Namespace "ROOTsubscription" -Query "SELECT * FROM __EventFilter WHERE Name LIKE '%SCM%'").Name
Get-WmiObject -Namespace "ROOTsubscription" -Query "REFERENCES OF {__EventFilter.Name='$InstanceName'}"
Since REFERENCES OF
will search an entire namespace you can narrow your results down to a specific class by adding a WHERE clause and naming the ResultClass as your target class. The revised second line of your command would now be
Get-WmiObject -Namespace "ROOTsubscription" -Query "REFERENCES OF {__EventFilter.Name='$InstanceName'} WHERE ResultClass = __FilterToConsumerBinding"
This should return the instance you are looking for only from __FilterToConsumerBinding. (*Note that there are no quotes around the class name. Including double or single quotes will give an invalid query error.
To answer your question about the __EventConsumer class, this brings up another WMI concept called abstract classes. I won't go into too much detail about this but an abstract class is essentially a base class (starting point for other classes) that other classes can inherit. Unlike standard base classes, though, abstract classes can not have its own instances. You can find out if a class is abstract by getting the class qualifiers of the __EventConsumer class. You'll notice if you run the command below, you will see it has the "abstract" class qualifier.
Get-CimClass -Namespace "rootSubscription" -Class __EventConsumer | Select-Object -ExpandProperty CimClassQualifiers
Since an abstract class can't contain any instances itself, if you enumerate it, it will return instances for all the classes that use it as a base class. In your example, __EventConsumer is actually yielding an instance from NTEventLogEventConsumer. Since enumerating an abstract class returns a number of different classes there would not always be the promise of the same properties to filter by so filtering is not allowed unless you are filtering on a property that is contained in the base class. To see what the base class of a WMI class is, you can use this command and see that the base class for NTEventLogEventConsumer is __EventConsumer.
Get-CimClass -Namespace "rootSubscription" -Class NTEventLogEventConsumer | Select-Object -ExpandProperty CimSuperClassName
You can usually enumerate all instances from an abstract class using the query SELECT * FROM __EventConsumer
. This will show all instances but once you add a WHERE clause with a property not included in the base class, you either receive invalid query or no instances will be returned. This is the reason why you can directly query NTEventLogEventConsumer but not __EventConsumer.
Hope this helps.
Holy cow I am reading and re-reading this to try and grasp it and understand it! I love explanations with the answers, to me that's the whole purpose of stackoverflow. Thank you, I'll spend the next week or so working on your answer!
– JohnRain
Nov 26 at 1:40
add a comment |
up vote
1
down vote
accepted
Short answer... your ability to filter on a property depends on what kind of WMI Class it is and what the property types are.
Long answer... To get more information about a WMI class in PowerShell, use the Get-CimClass cmdlet. Properties can have different value types based on the data they return (ie String, Integers, Boolean). In your example, you are trying to query the property "Filter" which is a reference type. A reference type doesn't have a literal value, it is just a reference to an instance from another class. You can tell a reference property because it shows a full or partial path to another class (as you saw in your example "__EventFilter" was referenced. You can also get the property type information from this powershell command:
Get-CimClass -Namespace "rootSubscription" -Class __FilterToConsumerBinding | Select-Object -ExpandProperty CimClassProperties | Where-Object {$_.Name -eq 'Filter'}
Reference type properties show up on WMI classes that have a class qualifier called "Association" set to true. Class qualifiers are properties for the class itself that dictate how the class behaves. You can see all the class qualifiers using this command.
Get-CimClass -Namespace "rootSubscription" -Class __FilterToConsumerBinding | Select-Object -ExpandProperty CimClassQualifiers
Unfortunately, Since WQL is a query language you cannot filter instances of a class based on properties with a reference type using a WHERE clause. You can only use simple types such as a string, integer, or property of an embedded object (embedded objects are extremely rare though).
Since the class __EventFilter is whats referenced by the "Filter" property, and that class DOES has simple property types we can start from there. You can query __EventFilter by the Name property, which is a string type, without any problem.
There are some advanced query techniques (ASSOCIATORS OF
and REFERENCES OF
) that can help you get the instance from __FilterToConsumerBinding with queries based on references but its a multi-step process. I'd recommend checking out the Microsoft Doc on it Microsoft Doc WQL but here is a basic two step PowerShell command that will first get the name of the referenced instance then any instances that reference it.
$InstanceName = (Get-WmiObject -Namespace "ROOTsubscription" -Query "SELECT * FROM __EventFilter WHERE Name LIKE '%SCM%'").Name
Get-WmiObject -Namespace "ROOTsubscription" -Query "REFERENCES OF {__EventFilter.Name='$InstanceName'}"
Since REFERENCES OF
will search an entire namespace you can narrow your results down to a specific class by adding a WHERE clause and naming the ResultClass as your target class. The revised second line of your command would now be
Get-WmiObject -Namespace "ROOTsubscription" -Query "REFERENCES OF {__EventFilter.Name='$InstanceName'} WHERE ResultClass = __FilterToConsumerBinding"
This should return the instance you are looking for only from __FilterToConsumerBinding. (*Note that there are no quotes around the class name. Including double or single quotes will give an invalid query error.
To answer your question about the __EventConsumer class, this brings up another WMI concept called abstract classes. I won't go into too much detail about this but an abstract class is essentially a base class (starting point for other classes) that other classes can inherit. Unlike standard base classes, though, abstract classes can not have its own instances. You can find out if a class is abstract by getting the class qualifiers of the __EventConsumer class. You'll notice if you run the command below, you will see it has the "abstract" class qualifier.
Get-CimClass -Namespace "rootSubscription" -Class __EventConsumer | Select-Object -ExpandProperty CimClassQualifiers
Since an abstract class can't contain any instances itself, if you enumerate it, it will return instances for all the classes that use it as a base class. In your example, __EventConsumer is actually yielding an instance from NTEventLogEventConsumer. Since enumerating an abstract class returns a number of different classes there would not always be the promise of the same properties to filter by so filtering is not allowed unless you are filtering on a property that is contained in the base class. To see what the base class of a WMI class is, you can use this command and see that the base class for NTEventLogEventConsumer is __EventConsumer.
Get-CimClass -Namespace "rootSubscription" -Class NTEventLogEventConsumer | Select-Object -ExpandProperty CimSuperClassName
You can usually enumerate all instances from an abstract class using the query SELECT * FROM __EventConsumer
. This will show all instances but once you add a WHERE clause with a property not included in the base class, you either receive invalid query or no instances will be returned. This is the reason why you can directly query NTEventLogEventConsumer but not __EventConsumer.
Hope this helps.
Holy cow I am reading and re-reading this to try and grasp it and understand it! I love explanations with the answers, to me that's the whole purpose of stackoverflow. Thank you, I'll spend the next week or so working on your answer!
– JohnRain
Nov 26 at 1:40
add a comment |
up vote
1
down vote
accepted
up vote
1
down vote
accepted
Short answer... your ability to filter on a property depends on what kind of WMI Class it is and what the property types are.
Long answer... To get more information about a WMI class in PowerShell, use the Get-CimClass cmdlet. Properties can have different value types based on the data they return (ie String, Integers, Boolean). In your example, you are trying to query the property "Filter" which is a reference type. A reference type doesn't have a literal value, it is just a reference to an instance from another class. You can tell a reference property because it shows a full or partial path to another class (as you saw in your example "__EventFilter" was referenced. You can also get the property type information from this powershell command:
Get-CimClass -Namespace "rootSubscription" -Class __FilterToConsumerBinding | Select-Object -ExpandProperty CimClassProperties | Where-Object {$_.Name -eq 'Filter'}
Reference type properties show up on WMI classes that have a class qualifier called "Association" set to true. Class qualifiers are properties for the class itself that dictate how the class behaves. You can see all the class qualifiers using this command.
Get-CimClass -Namespace "rootSubscription" -Class __FilterToConsumerBinding | Select-Object -ExpandProperty CimClassQualifiers
Unfortunately, Since WQL is a query language you cannot filter instances of a class based on properties with a reference type using a WHERE clause. You can only use simple types such as a string, integer, or property of an embedded object (embedded objects are extremely rare though).
Since the class __EventFilter is whats referenced by the "Filter" property, and that class DOES has simple property types we can start from there. You can query __EventFilter by the Name property, which is a string type, without any problem.
There are some advanced query techniques (ASSOCIATORS OF
and REFERENCES OF
) that can help you get the instance from __FilterToConsumerBinding with queries based on references but its a multi-step process. I'd recommend checking out the Microsoft Doc on it Microsoft Doc WQL but here is a basic two step PowerShell command that will first get the name of the referenced instance then any instances that reference it.
$InstanceName = (Get-WmiObject -Namespace "ROOTsubscription" -Query "SELECT * FROM __EventFilter WHERE Name LIKE '%SCM%'").Name
Get-WmiObject -Namespace "ROOTsubscription" -Query "REFERENCES OF {__EventFilter.Name='$InstanceName'}"
Since REFERENCES OF
will search an entire namespace you can narrow your results down to a specific class by adding a WHERE clause and naming the ResultClass as your target class. The revised second line of your command would now be
Get-WmiObject -Namespace "ROOTsubscription" -Query "REFERENCES OF {__EventFilter.Name='$InstanceName'} WHERE ResultClass = __FilterToConsumerBinding"
This should return the instance you are looking for only from __FilterToConsumerBinding. (*Note that there are no quotes around the class name. Including double or single quotes will give an invalid query error.
To answer your question about the __EventConsumer class, this brings up another WMI concept called abstract classes. I won't go into too much detail about this but an abstract class is essentially a base class (starting point for other classes) that other classes can inherit. Unlike standard base classes, though, abstract classes can not have its own instances. You can find out if a class is abstract by getting the class qualifiers of the __EventConsumer class. You'll notice if you run the command below, you will see it has the "abstract" class qualifier.
Get-CimClass -Namespace "rootSubscription" -Class __EventConsumer | Select-Object -ExpandProperty CimClassQualifiers
Since an abstract class can't contain any instances itself, if you enumerate it, it will return instances for all the classes that use it as a base class. In your example, __EventConsumer is actually yielding an instance from NTEventLogEventConsumer. Since enumerating an abstract class returns a number of different classes there would not always be the promise of the same properties to filter by so filtering is not allowed unless you are filtering on a property that is contained in the base class. To see what the base class of a WMI class is, you can use this command and see that the base class for NTEventLogEventConsumer is __EventConsumer.
Get-CimClass -Namespace "rootSubscription" -Class NTEventLogEventConsumer | Select-Object -ExpandProperty CimSuperClassName
You can usually enumerate all instances from an abstract class using the query SELECT * FROM __EventConsumer
. This will show all instances but once you add a WHERE clause with a property not included in the base class, you either receive invalid query or no instances will be returned. This is the reason why you can directly query NTEventLogEventConsumer but not __EventConsumer.
Hope this helps.
Short answer... your ability to filter on a property depends on what kind of WMI Class it is and what the property types are.
Long answer... To get more information about a WMI class in PowerShell, use the Get-CimClass cmdlet. Properties can have different value types based on the data they return (ie String, Integers, Boolean). In your example, you are trying to query the property "Filter" which is a reference type. A reference type doesn't have a literal value, it is just a reference to an instance from another class. You can tell a reference property because it shows a full or partial path to another class (as you saw in your example "__EventFilter" was referenced. You can also get the property type information from this powershell command:
Get-CimClass -Namespace "rootSubscription" -Class __FilterToConsumerBinding | Select-Object -ExpandProperty CimClassProperties | Where-Object {$_.Name -eq 'Filter'}
Reference type properties show up on WMI classes that have a class qualifier called "Association" set to true. Class qualifiers are properties for the class itself that dictate how the class behaves. You can see all the class qualifiers using this command.
Get-CimClass -Namespace "rootSubscription" -Class __FilterToConsumerBinding | Select-Object -ExpandProperty CimClassQualifiers
Unfortunately, Since WQL is a query language you cannot filter instances of a class based on properties with a reference type using a WHERE clause. You can only use simple types such as a string, integer, or property of an embedded object (embedded objects are extremely rare though).
Since the class __EventFilter is whats referenced by the "Filter" property, and that class DOES has simple property types we can start from there. You can query __EventFilter by the Name property, which is a string type, without any problem.
There are some advanced query techniques (ASSOCIATORS OF
and REFERENCES OF
) that can help you get the instance from __FilterToConsumerBinding with queries based on references but its a multi-step process. I'd recommend checking out the Microsoft Doc on it Microsoft Doc WQL but here is a basic two step PowerShell command that will first get the name of the referenced instance then any instances that reference it.
$InstanceName = (Get-WmiObject -Namespace "ROOTsubscription" -Query "SELECT * FROM __EventFilter WHERE Name LIKE '%SCM%'").Name
Get-WmiObject -Namespace "ROOTsubscription" -Query "REFERENCES OF {__EventFilter.Name='$InstanceName'}"
Since REFERENCES OF
will search an entire namespace you can narrow your results down to a specific class by adding a WHERE clause and naming the ResultClass as your target class. The revised second line of your command would now be
Get-WmiObject -Namespace "ROOTsubscription" -Query "REFERENCES OF {__EventFilter.Name='$InstanceName'} WHERE ResultClass = __FilterToConsumerBinding"
This should return the instance you are looking for only from __FilterToConsumerBinding. (*Note that there are no quotes around the class name. Including double or single quotes will give an invalid query error.
To answer your question about the __EventConsumer class, this brings up another WMI concept called abstract classes. I won't go into too much detail about this but an abstract class is essentially a base class (starting point for other classes) that other classes can inherit. Unlike standard base classes, though, abstract classes can not have its own instances. You can find out if a class is abstract by getting the class qualifiers of the __EventConsumer class. You'll notice if you run the command below, you will see it has the "abstract" class qualifier.
Get-CimClass -Namespace "rootSubscription" -Class __EventConsumer | Select-Object -ExpandProperty CimClassQualifiers
Since an abstract class can't contain any instances itself, if you enumerate it, it will return instances for all the classes that use it as a base class. In your example, __EventConsumer is actually yielding an instance from NTEventLogEventConsumer. Since enumerating an abstract class returns a number of different classes there would not always be the promise of the same properties to filter by so filtering is not allowed unless you are filtering on a property that is contained in the base class. To see what the base class of a WMI class is, you can use this command and see that the base class for NTEventLogEventConsumer is __EventConsumer.
Get-CimClass -Namespace "rootSubscription" -Class NTEventLogEventConsumer | Select-Object -ExpandProperty CimSuperClassName
You can usually enumerate all instances from an abstract class using the query SELECT * FROM __EventConsumer
. This will show all instances but once you add a WHERE clause with a property not included in the base class, you either receive invalid query or no instances will be returned. This is the reason why you can directly query NTEventLogEventConsumer but not __EventConsumer.
Hope this helps.
edited Nov 25 at 1:07
answered Nov 22 at 3:52
Paul G
1894
1894
Holy cow I am reading and re-reading this to try and grasp it and understand it! I love explanations with the answers, to me that's the whole purpose of stackoverflow. Thank you, I'll spend the next week or so working on your answer!
– JohnRain
Nov 26 at 1:40
add a comment |
Holy cow I am reading and re-reading this to try and grasp it and understand it! I love explanations with the answers, to me that's the whole purpose of stackoverflow. Thank you, I'll spend the next week or so working on your answer!
– JohnRain
Nov 26 at 1:40
Holy cow I am reading and re-reading this to try and grasp it and understand it! I love explanations with the answers, to me that's the whole purpose of stackoverflow. Thank you, I'll spend the next week or so working on your answer!
– JohnRain
Nov 26 at 1:40
Holy cow I am reading and re-reading this to try and grasp it and understand it! I love explanations with the answers, to me that's the whole purpose of stackoverflow. Thank you, I'll spend the next week or so working on your answer!
– JohnRain
Nov 26 at 1:40
add a comment |
Thanks for contributing an answer to Stack Overflow!
- Please be sure to answer the question. Provide details and share your research!
But avoid …
- Asking for help, clarification, or responding to other answers.
- Making statements based on opinion; back them up with references or personal experience.
To learn more, see our tips on writing great answers.
Some of your past answers have not been well-received, and you're in danger of being blocked from answering.
Please pay close attention to the following guidance:
- Please be sure to answer the question. Provide details and share your research!
But avoid …
- Asking for help, clarification, or responding to other answers.
- Making statements based on opinion; back them up with references or personal experience.
To learn more, see our tips on writing great answers.
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53420853%2fwmi-queries-in-powershell-invalid-query%23new-answer', 'question_page');
}
);
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
1
I suspect because
Filter
is generated by powershell on that object and what you actually want is something likeName LIKE '%SCM%'
– TheIncorrigible1
Nov 21 at 21:53
Thanks for the answer @TheIncorrigible1 I tried to edit above, it did let me query the property filter.
– JohnRain
Nov 22 at 0:08
No where in your question are you querying a
Filter
property on the\.rootSubscription:__FilterToConsumerBinding
class.– TheIncorrigible1
Nov 22 at 0:13
Get-WMIObject -Namespace rootSubscription -Class __FilterToConsumerBinding | Select Filter (was that not right?)
– JohnRain
Nov 22 at 0:30
Select-Object -Property Filter
is not a query. It's just selecting a property and turning it into apscustomobject
. Like I said, powershell creates that property for you to be nice.– TheIncorrigible1
Nov 22 at 0:31