WMI的WQL简明教程系列的前三篇文章[1,2,3]分别介绍WQL中的关键字,运算符和WMI中的类,由这三个东西,理论上已经能够完成WQL语句的编写了,不过也仅是理论上。就好比盖房子,理论上有水泥,钢筋和砖头是可以盖的,但实际上,并不是一定能盖出好房子的,甚至房子盖不成的也有,要盖好房子,还需要一个设计图纸,相对应的,咱们的WQL也同样,只有了一些基础的配件,有的时候并不一定能够装配出能正常运行的WQL语句。为了能够让我们能够组装出能够运行的WQL语句,就需要WQL的设计图纸——语法。
从WQL关键字篇我们能够看到,WQL并没有UPDATE,INSERT这类SQL中的语句,因此我们能够想象的到,WMI的WQL最主要的功能就是为了查询系统数据,因此我们学习WQL语法的时候,首先只要能够了解到查询数据的语法,基本上就能够应付大部分情况了,怎么样,还是相当的简单吧?那让我们开始吧,先看看下面的WQL:
SELECT * FROM Device
WHERE __CLASS = "Modem" OR __CLASS = "Keyboard"
从上面的语句中我们能够看到WQL的基本语法结构,其和SQL语法类似,但WQL中多处了ASSOCIATORS OF和 REFERENCES OF两个查询结构,具体的WQL查询分为Schema,Data和Event查询,他们的区别:
- 数据查询:用于获取类实例,它返回特定类的所有实例,包括各自的请求属性集
- Schema查询:获取类定义,使用的基本语法的形式与其他类型的查询一样
- 事件查询:用于过滤出一个特定事件通知的属性。事件表征被管理环境的变更。
每个查询允许添加一些附加的操作符,如:
WITHIN:指定轮询
GROUP:分组相同的事件
HAVING:过滤WITHIN和GROUP子句收集事件的通知。一般与NumberofEvents属性(收集事件数量)一起。这样可以侦测何时特定事件的数量超过了时间间隔中设置的极限。
下面是Schema和Data查询的语法结构:
; -----------------------------------
; http://blog.useasp.net/
; MitchellChu's Blog
; WQL tutorial
; WQL schema and data 查询的语法结构
; -----------------------------------
DATA-WQL =
("SELECT" <PROPERTY-LIST> "FROM" <CLASS-NAME>
<OPTIONAL-SEL-WHERE>)/
("SELECT" ASTERISK "FROM" <CLASS-NAME> <OPTIONAL-SEL-WHERE>)/
("SELECT" ASTERISK "FROM META_CLASS" <OPTIONAL-META-WHERE>)/
("ASSOCIATORS OF {" <OBJECT-REL-PATH> "}"
<OPTIONAL-ASSOC-WHERE>)/
("REFERENCES OF {" <OBJECT-REL-PATH> "}" <OPTIONAL-REF-WHERE>)
;========================================
; PROPERTY-LIST:属性列表
; 属性列表有属性名组成,多个属性名使用逗号分隔
; 如果奥全部选择,可以直接使用*(星号)代替
;========================================
PROPERTY-LIST = <PROPERTY-NAME> <PROPERTY-LIST2>
PROPERTY-LIST2 = [COMMA <PROPERTY-LIST>]
;========================================
; OPTIONAL-*-WHERE是WHERE子句
; 这个子句非必须,是用来缩小查询范围
;========================================
OPTIONAL-SEL-WHERE = ["WHERE" <EXPR>]
OPTIONAL-META-WHERE = ["WHERE __THIS ISA" <CLASS-NAME>]
OPTIONAL-ASSOC-WHERE =
["WHERE" [ "AssocClass=" <CLASS-NAME> BLANK ]
[ "RequiredAssocQualifier=" <QUALIFIER-NAME> BLANK ]
[ "RequiredQualifier=" <QUALIFIER-NAME> BLANK ]
[ "ResultClass=" <CLASS-NAME> BLANK ]
[ "ResultRole=" <PROPERTY-NAME> BLANK ]
[ "Role=" <PROPERTY-NAME> BLANK ]
[ "KeysOnly" BLANK ]
[ "ClassDefsOnly" BLANK ]
]
OPTIONAL-REF-WHERE =
["WHERE" [ "RequiredQualifier=" <QUALIFIER-NAME> BLANK ]
[ "ResultClass=" <CLASS-NAME> BLANK ]
[ "Role=" <PROPERTY-NAME> BLANK ]
[ "KeysOnly" BLANK ]
[ "ClassDefsOnly" BLANK ]
]
;========================================
;
;========================================
OBJECT-REL-PATH =
<CLASS-NAME> "=" <TYPED-CONSTANT> <OBJECT-REL-PATH2>
OBJECT-REL-PATH2 =
[COMMA <OBJECT-REL-PATH>]
; -----------------------------------
; Expression 表达式
; -----------------------------------
EXPR =
( [OPEN-PARENTHESIS] <PROPERTY-EVALUATION>
<EXPR2> [CLOSE-PARENTHESIS] ) /
( [OPEN-PARENTHESIS] "__CLASS" <EQUIVALENT-OPERATOR>
<CLASS-NAME> <EXPR2> [CLOSE-PARENTHESIS] )
EXPR2 = ( ["OR" [OPEN-PARENTHESIS] <EXPR> [CLOSE-PARENTHESIS] ])/
( ["AND" [OPEN-PARENTHESIS] <EXPR> [CLOSE-PARENTHESIS] ])
PROPERTY-EVALUATION =
( <PROPERTY-NAME> <OPERATOR> <TYPED-CONSTANT> ) /
( <PROPERTY-NAME> <IS-OPERATOR> "NULL" )
OPERATOR = <EQUIVALENT-OPERATOR> /
<COMPARE-OPERATOR>
EQUIVALENT-OPERATOR = "=" / "!=" / "<>"
COMPARE-OPERATOR = "<=" / ">=" / "<" / ">" / "LIKE"
IS-OPERATOR = "IS" / "IS NOT"
; -----------------------------------
; Characters 字符集
; -----------------------------------
ALPHA = %x41-5A
DIGIT = %x30-39
COMMA = ","
ASTERISK = "*"
OPEN-PARENTHESIS = "("
CLOSE-PARENTHESIS = ")"
BLANK = " " / "\x09"
DOUBLEUNDERSCORE = %x5f %x5f
STRING-IDENTIFIER = ALPHA *(ALPHA / DIGIT / (*("_") ALPHA / DIGIT))
CLASS-NAME = [DOUBLEUNDERSCORE]<STRING-IDENTIFIER>
PROPERTY-NAME = [DOUBLEUNDERSCORE]<STRING-IDENTIFIER>
QUALIFIER-NAME = <STRING-IDENTIFIER>
TYPED-CONSTANT = INT /
REAL /
UNICODE-STRING /
DATETIME /
BOOL
INT = "[-+]?\d+"
REAL = "[-+]?(\d*\.\d+)|(\d+)"
STRING = ["]([a-z][A-Z]\d)*["]
DATETIME is specified in section 2.2.1 of [DMTF-DSP0004]
BOOL = "TRUE" / "FALSE"
关于语法中的一些说明如下:
Schema 对象和关键字 |
描述 |
UNICODE-STRING |
包含Unicode字符的字串。字串必须使用双引号("")或单引号('')括住。 |
CLASS-NAME |
标记要查询的CIM类名。 |
PROPERTY-NAME |
标记CIM类中的属性名称。 |
QUALIFIER-NAME |
在WQL查询的上下文中,QUALIFIER-NAME是PROPERTY-NAME定义对另外一个CIM类关联类型的一个属性。所有的限定符,包含任何自定义的限定符,必须要在WQL查询的上下文中被支持。 RequiredAssocQualifier关键字指示:返回的端点必须与源对象通过一个包含指定限定符的关联类有关联。这个过滤的类型被用于缩小端点(endpoint)的范围,除非端点与目标通过一组特定的标记了的关联类进行关联。举例来说:下面的查询返回的是关联类包含了叫Association限定符的端点实例。
;==============================================
; http://blog.useasp.net/
; Mitchell Chu's Blog
; 关于RequiredAssocQualifier的示例
;==============================================
ASSOCIATORS OF {Win32_LogicalDisk.DeviceID="C:"}
WHERE RequiredAssocQualifier = Association
|
DATA-WQL |
用来表示WQL查询的字符串。WQL字符串使用不同的WQL保留关键字来选择需要的信息类型。 |
SELECT |
用来表示要选择的信息的要求的关键字(类似SQL中的SELECT)。SELECT表达要查询的CIM类或者CIM实例 。在ASSOCIATORS OF或 REFERENCES OF关键字在查询语句中没有使用的情况下,就必须使用SELECT. 但不能在使用了ASSOCIATORS OF或REFERENCES OF关键字的情况下使用。 |
PROPERTY-LIST |
PROPERTY-NAME值列表。 在列表中PROPERTY-NAME 各个值之间必须使用逗号分隔(",")。 |
ASTERISK |
使用星号("*")表示需要CIM类或CIM实例中所有的属性值。 |
FROM |
在SELECT语句中必须指定的一个关键字,用来表示CIM类或者CIM实例必须在查询之前执行。 |
OPTIONAL-SEL-WHERE |
WHERE语句用来缩小SELECT的范围。 |
OPTIONAL-META-WHERE |
WHERE语句用来缩小SELECT的范围。在WHERE后面跟__THIS ISA语句来缩小WQL查询的范围,用来根据下面的规则返回CIM实例:仅返回CLASS-NAME的实例和所有是继承自CLASS-NAME的CIM实例 |
__CLASS |
这个关键字用来表示当前CIM对象引用的CIM对象类,关键字在WHERE子句中出现时,仅会选择派生于CLASS-NAME的CIM实例。 |
ASSOCIATORS OF |
是WQL语句中用来查找相关CIM类或CIM实例的关键字。此关键字不能和SELECT和REFERENCES OF关键字一起使用。 |
OPTIONAL-ASSOC-WHERE |
如果是在ASSOCIATORS OF的WQL查询中使用WHERE语句,将缩小范围至关联或关联的CIM类的一个或几个特征。这个过滤表达式可以用几个特殊的关键字和表达式组成来验证这些特征。 每个表达式像在前前面ABNF符号指定的那样,必须使用BLANK(空白符)分隔,每个表达式不能在单一的WQL查询中多次使用。用来缩小ASSOCIATORS OF查询范围的关键字有:AssocClass, RequiredAssocQualifier, RequiredQualifier, ResultClass, ResultRole, Role, KeysOnly, 和ClassDefsOnly。 |
REFERENCES OF |
是WQL语句中查找CIM类或CIM实例关联的CIM类或CIM实例的关键字。该关键字不能与SELECT和ASSOCIATORS OF关键字一起合用。 |
OPTIONAL-REF-WHERE |
如果在REFERENCES OF查询中指定WHERE语句, 将缩小关联的一个或多个特征和关联的类。这个过滤表达式可由几个特定的关键字和表达式组成来表示这些特征。表达式之间必须使用空白符(BLANK)来分隔,每个表达式不能在单挑个WQL查询中重复使用。支持用来缩小REFERENCES OF查询范围的关键字有:RequiredQualifier, ResultClass, Role, KeysOnly, 和ClassDefsOnly。 |
OBJECT-REL-PATH |
被查询的CIM类或者CIM实例的CIM相对路径。在ASSOCIATORS OF和REFERENCES OF查询中必须指定。 |
KeysOnly |
如果在ASSOCIATORS OF和REFERENCES OF的查询中使用了KeysOnly关键字,那么查询结果中的CIM实例仅要求关键属性必须被填充。 |
ClassDefsOnly |
如果在ASSOCIATORS OF和REFERENCES OF查询中使用ClassDefsOnly关键字,仅要求结果中的CIM实例的CIM类定义必须返回。 |
AssocClass |
如果在ASSOCIATORS OF查询中使用AssocClass关键字,返回的CIM实例结果必须与关联类或者由指定的CLASS-NAME组成CIM实例相关联。 |
RequiredAssocQualifier |
如果在ASSOCIATORS OF查询中使用RequiredAssocQualifier关键字,返回的CIM实例必须通过包含了指定限定符的关联类与源对象相关联。如下示例:
;============================================
; http://blog.useasp.net/
; MitchellChu's Blog
; WQL tutorial
;============================================
ASSOCIATORS OF {Win32_LogicalDisk.DeviceID="C:"}
WHERE RequiredAssocQualifier = Association
返回的CIM实例必须通过包含限定符"association"的关联类与源对象{Win32_LogicalDisk.DeviceID="C:"}相关联 |
RequiredQualifier |
在ASSOCIATORS OF和REFERENCES OF查询中如果使用了RequiredQualifier关键字,返回的CIM实例中必须要有在给定的名称集的CIM限定符。 |
ResultClass |
在ASSOCIATORS OF和REFERENCES OF查询中如果使用了ResultClass关键字,返回的CIM实例必须是属于或者继承与CLASS-NAME指定的类。 |
Role |
在ASSOCIATORS OF和REFERENCES OF查询中如果使用了Role关键字,返回的结果仅是那些角色与关联类的引用CIM属性名称相匹配的CIM实例。 |
ResultRole |
在ASSOCIATORS OF查询中如果使用了ResultRole关键字,返回的结果仅是那些角色与CIM实例的引用CIM属性名称相匹配的CIM实例。可使用的值有:GroupComponent,PartComponent,Antecedent,Dependent |
Event查询语法结构如下:
; -----------------------------------
; http://blog.useasp.net/
; MitchellChu's Blog
; WQL tutorial
; WQL event queries,Event查询
; -----------------------------------
EVENT-WQL = "SELECT" <PROPERTY-LIST> "FROM" /
<EVENT-CLASS-NAME> <OPTIONAL-WITHIN> <EVENT-WHERE>
OPTIONAL-WITHIN = ["WITHIN" <INTERVAL>]
INTERVAL = 1*MODULOREAL
EVENT-WHERE = ["WHERE" <EVENT-EXPR>]
EVENT-EXPR = ( (<INSTANCE-STATE> "ISA" <CLASS-NAME> <EXPR2>) /
<EXPR> )
["GROUP WITHIN" <INTERVAL>
( ["BY" [<INSTANCE-STATE> DOT] <PROPERTY-NAME>]
["HAVING" <EXPR>] )]
INSTANCE-STATE = "TARGETINSTANCE" / "PREVIOUSINSTANCE"
; -----------------------------------
; Expression 表达式
; -----------------------------------
EXPR =
[OPEN-PARENTHESIS] <PROPERTY-EVALUATION> /
<EXPR2> [CLOSE-PARENTHESIS]
EXPR2 = ( ["OR" [OPEN-PARENTHESIS] <EXPR> /
[CLOSE-PARENTHESIS] ] ) /
( ["AND" [OPEN-PARENTHESIS] <EXPR> /
[CLOSE-PARENTHESIS] ] )
PROPERTY-EVALUATION =
( <PROPERTY-NAME> <OPERATOR> <TYPED-CONSTANT> ) /
( <PROPERTY-NAME> <IS-OPERATOR> "NULL" )
OPERATOR = <EQUIVALENT-OPERATOR> /
<COMPARE-OPERATOR>
EQUIVALENT-OPERATOR = "=" / "!=" / "<>"
COMPARE-OPERATOR = "<=" / ">=" / "<" / ">" / "LIKE"
IS-OPERATOR = "IS" / "IS NOT"
; -----------------------------------
; Characters
; -----------------------------------
ALPHA = %x41-5A
DIGIT = %x30-39
DOT = ","
COMMA = "."
ASTERISK = "*"
OPEN-PARENTHESIS = "("
CLOSE-PARENTHESIS = ")"
STRING-IDENTIFIER = ALPHA *(ALPHA / DIGIT / (*("_") ALPHA / DIGIT))
DOUBLEUNDERSCORE = "__"
CLASS-NAME = [DOUBLEUNDERSCORE]<STRING-IDENTIFIER>
EVENT-CLASS-NAME = [DOUBLEUNDERSCORE]<STRING-IDENTIFIER>
PROPERTY-NAME = [DOUBLEUNDERSCORE]<STRING-IDENTIFIER>
TYPED-CONSTANT = INT /
REAL /
STRING /
DATETIME /
BOOL
INT = "[-+]?\d*"
REAL = "[-+]?\d*(\.\d+)?"
MODULOREAL = “[+]?\d*(\.\d+)?”
STRING = ["]([a-z][A-Z]\d)*["]
DATETIME is specified in section 2.2.1 of [DMTF-DSP0004]
BOOL = "TRUE" / "FALSE"
EVENT-WQL语法中的说明:
对象和关键字 |
描述 |
CLASS-NAME |
标记要查询事件中的CIM类名称。 |
PROPERTY-NAME |
标记CIM类中CIM属性的名称。 |
EVENT-WQL |
用来表示WQL事件查询的字符串。WQL字符串使用不同的WQL保留关键字来选择需要的信息类型。 |
SELECT |
用来表示要选择的信息的要求的关键字(类似SQL中的SELECT)。SELECT表达要查询的CIM类或者CIM实例 。在WQL事件查询中必须使用此关键字。 |
PROPERTY-LIST |
PROPERTY-NAME值列表。 在列表中PROPERTY-NAME 各个值之间必须使用逗号分隔(",")。 |
ASTERISK |
使用星号("*")表示需要CIM类或CIM实例中所有的属性值。 |
FROM |
在SELECT语句中必须指定的一个关键字,用来表示CIM类或者CIM实例必须在查询之前执行。 |
EVENT-CLASS-NAME |
必须指定,必须为一个内在的,外在的或是一个定时器事件类。内在的事件类是指类继承于__InstanceOperationEvent, __ClassOperationEvent, 或__NamespaceOperationEvent,代表可能的内部事件。外在的时间类是指该类继承于__ExtrinsicEvent,代表可能的外部事件。 定时器事件类是指该类继承于__TimerEvent事件类,代表可能的定时器事件。 |
WITHIN |
指示服务器轮询事件系统的关键字。在使用内部EVENT-CLASS-NAME时,必须指定WITHIN。对于外部EVENT-CLASS-NAME来说,WITHIN关键字是可选的。如果指定了WITHIN关键字,就必须指定INTERVAL。 |
INTERVAL |
INTERVAL指定轮询间隔,它必须以秒来表示,当使用了WITHIN时,必须使用INTERVAL。 |
EVENT-WHERE |
在EVENT-CLASS-NAME是一个外部或定时器事件的CIM类时,WHERE语句缩小SELECT事件查询的范围。如果EVENT-CLASS-NAME是内部CIM类(intrinsic CIM class),WHERE语句必须使用在SELECT事件查询中缩小范围。 |
INSTANCE-STATE |
表示被计算的实例的类型。INSTANCE-STATE在CLASS-NAME为内部CIM类时必须指定。INSTANCE-STATE在CLASS-NAME是外部CIM类时为可选。如果被使用,INSTANCE-STATE必须是PREVIOUSINSTANCE(用来指明在事件之前的CIM类或者CIM实例的状态必须被计算)或TARGETINSTANCE(用来指明在事件之后的CIM类或者CIM实例的状态必须被计算) |
ISA |
必须和INSTANCE-STATE关键字组合使用的关键字。它在INSTANCE-STATE和CLASS-NAME之间被用作比较运算符,用来减少CLASS-NAME查询返回到CIM实例的事件范围 |
GROUP WITHIN |
如果使用了GROUP WITHIN,就必须使用INTERVAL。该关键字指明,所有在WITHIN INTERVAL期间发生的事件均作为一个事件来分组。 |
HAVING |
如果指定了HAVING关键字,后面必须跟EXPR来过滤事件的选择。该关键字指明所有在GROUP WITHIN期间分组的事件必须在作为一个事件返回之前还要满足EXPR中指定的表达式要求。 |
BY |
关键字在事件实例组中在指定的PROPERTY-NAME中共享同一个值。这种情况下,返回的时间表示该组事件共享同样的PROPERTY-NAME值。系统在事件组中必须返回与PROPERTY-NAME值中一样多的事件。 |
EVENT-EXPR |
过滤WMI事件的表达式。 |
有了这些语法,在应对WQL的操作时,就不再那么不知所措了,根据本文的语法,按照要求选取需要的关键字,找到关键的类,在WHERE子句用上操作符缩小下范围,就能找到自己想要的CIM类或者CIM实例了。enjoy it.
附注:
本文的文章大部分翻译自微软官方网站(才能有限,错愕之处还请指正):WQL Query