about_WQL
简短说明
介绍可用于获取 Windows PowerShell 中的 WMI 对象的 WMI 查询语言 (WQL)。
长说明
WQL 是 Windows Management Instrumentation (WMI) 查询语言,它是用于从 WMI 获取信息的语言。
无需使用 WQL 在 Windows PowerShell 中执行 WMI 查询。
相反,可以使用 Get-WmiObject
的参数或 Get-CimInstance
cmdlet。 WQL 查询比标准 Get-WmiObject
命令要快一些,并且当命令在数百个系统上运行时,性能的提高是显而易见的。 但是,请确保编写成功的 WQL 查询所花费的时间不会超过性能的改进。
使用 WQL 所需的基本 WQL 语句是 SELECT
、WHERE
和 FROM
。
何时使用 WQL
使用 WMI(尤其是 WQL)时,不要忘记你也在使用 Windows PowerShell。 通常,如果 WQL 查询未按预期工作,则使用标准 Windows PowerShell 命令比调试 WQL 查询更容易。
除非要从带宽受限的远程系统返回大量数据,否则在可以使用 PowerShell cmdlet 完成相同操作的情况下,花费数小时尝试完善复杂的 WQL 查询是非常低效的选择。
使用 SELECT 语句
典型的 WMI 查询以 SELECT
语句开始,该语句可获取 WMI 类的所有属性或特定属性。 若要选择 WMI 类的所有属性,请使用星号 (*
)。
FROM
关键字可指定 WMI 类。
SELECT
语句具有以下格式:
SELECT <property> FROM <WMI-class>
例如,以下 SELECT
语句从 *
WMI 类的实例中选择所有属性 ()。
SELECT * FROM Win32_Bios
注意
默认情况下,PowerShell 仅显示默认对象。 这些属性是在 Types.ps1xml
文件中定义的。 使用 Select-Object
cmdlet 或 Format-*
cmdlet 显示其他属性。
要选择 WMI 类的特定属性,请将属性名称放在关键字 SELECT
和 FROM
之间。
以下查询仅从 Win32_Bios WMI 类中选择 BIOS 名称。 该命令将查询保存在 $queryName
变量中。
SELECT Name FROM Win32_Bios
若要选择多个属性,请使用逗号分隔属性名称。
以下 WMI 查询选择 Win32_Bios WMI 类的名称和版本。 该命令将查询保存在 $queryNameVersion
变量中。
SELECT name, version FROM Win32_Bios
使用 WQL 查询
在Windows PowerShell 命令中使用WQL 查询的方法有3 种。
- 使用
Get-WmiObject
cmdlet - 使用
Get-CimInstance
cmdlet - 使用
[wmisearcher]
类型加速器。
使用 Get-WmiObject cmdlet
使用 WQL 查询的最基本方法是将其括在引号中(作为字符串),然后使用查询字符串作为 cmdlet 的 Get-WmiObject
参数的值,如以下示例所示。
Get-WmiObject -Query "SELECT * FROM Win32_Bios"
SMBIOSBIOSVersion : 8BET56WW (1.36 )
Manufacturer : LENOVO
Name : Default System BIOS
SerialNumber : R9FPY3P
Version : LENOVO - 1360
还可以将 WQL 语句保存在变量中,然后使用该变量作为查询参数的值,如以下命令所示。
$query = "SELECT * FROM Win32_Bios"
Get-WmiObject -Query $query
可以将任一格式与任何 WQL 语句一起使用。 以下命令使用 $queryName
变量中的查询来仅获取系统 BIOS 的 Name 和 Version 属性。
$queryNameVersion = "SELECT Name, Version FROM Win32_Bios"
Get-WmiObject -Query $queryNameVersion
__GENUS : 2
__CLASS : Win32_BIOS
__SUPERCLASS :
__DYNASTY :
__RELPATH :
__PROPERTY_COUNT : 2
__DERIVATION : {}
__SERVER :
__NAMESPACE :
__PATH :
Name : S03KT39A
Version : LENOVO - 1270
PSComputerName :
请记住,可以使用 Get-WmiObject
cmdlet 的参数来获得相同的结果。 例如,以下命令还将获取 Win32_Bios WMI 类实例的 Name 和 Version 属性的值。
Get-WmiObject -Class Win32_Bios -Property Name, Version
__GENUS : 2
__CLASS : Win32_BIOS
__SUPERCLASS :
__DYNASTY :
__RELPATH :
__PROPERTY_COUNT : 2
__DERIVATION : {}
__SERVER :
__NAMESPACE :
__PATH :
Name : S03KT39A
Version : LENOVO - 1270
PSComputerName :
使用 Get-CimInstance cmdlet
从 Windows PowerShell 3.0 开始,可以使用 Get-CimInstance
cmdlet 运行 WQL 查询。
Get-CimInstance
可获取符合 CIM 的类的实例,包括 WMI 类。 Windows PowerShell 3.0 中引入的 CIM cmdlet 执行与 WMI cmdlet 相同的任务。 CIM cmdlet 符合 WS 管理 (WSMan) 标准和通用信息模型 (CIM) 标准,这使得 cmdlet 能够使用相同的技术来管理 Windows 计算机和运行其他操作系统的计算机。
以下命令使用 Get-CimInstance
cmdlet 运行 WQL 查询。
任何可与 Get-WmiObject
一起使用的 WQL 查询也可与 Get-CimInstance
一起使用。
Get-CimInstance -Query "SELECT * FROM Win32_Bios"
SMBIOSBIOSVersion : S03KT39A
Manufacturer : LENOVO
Name : S03KT39A
SerialNumber : MJ0AETTX
Version : LENOVO - 1270
Get-CimInstance
将返回 CimInstance 对象,而不是 返回的 Get-WmiObject
,但这些对象都非常相似。
PS> (Get-CimInstance -Query "SELECT * FROM Win32_Bios").GetType().FullName
Microsoft.Management.Infrastructure.CimInstance
PS> (Get-WmiObject -Query "SELECT * FROM Win32_Bios").GetType().FullName
System.Management.ManagementObject
使用 wmisearcher 类型加速器
[wmisearcher]
类型加速器将从 WQL 语句字符串创建 ManagementObjectSearcher 对象。
ManagementObjectSearcher 对象具有许多属性和方法,但最基本的方法是 Get 方法,它调用指定的 WMI 查询并返回结果对象。
通过使用 [wmisearcher]
,可以轻松访问 ManagementObjectSearcher .NET 类。 这样,便可以查询 WMI 并配置查询的执行方式。
要使用 [wmisearcher]
类型加速器:
- 将 WQL 字符串强制转换为 ManagementObjectSearcher 对象。
- 调用 ManagementObjectSearcher 对象的 Get 方法。
例如,以下命令将强制转换“全选”查询,将结果保存在 $bios
变量中,然后调用 Get()
变量中 ManagementObjectSearcher 对象的 $bios
方法。
$bios = [wmisearcher]"SELECT * FROM Win32_Bios"
$bios.Get()
SMBIOSBIOSVersion : 8BET56WW (1.36 )
Manufacturer : LENOVO
Name : Default System BIOS
SerialNumber : R9FPY3P
Version : LENOVO - 1360
可以使用 [wmisearcher]
类型加速器来强制转换查询或变量。 在以下示例中,使用 [wmisearcher]
类型加速器来强制转换变量。 结果是一样的。
[wmisearcher]$bios = "SELECT * FROM Win32_Bios"
$bios.Get()
SMBIOSBIOSVersion : S03KT39A
Manufacturer : LENOVO
Name : S03KT39A
SerialNumber : MJ0AETTX
Version : LENOVO - 1270
使用 [wmisearcher]
类型加速器时,它会将查询字符串更改为 ManagementObjectSearcher 对象,如以下命令所示。
$a = "SELECT * FROM Win32_Bios"
$a.GetType().FullName
System.String
$a = [wmisearcher]"SELECT * FROM Win32_Bios"
$a.GetType().FullName
System.Management.ManagementObjectSearcher
此命令格式适用于任何查询。 以下命令将获取 Win32_Bios WMI 类的 Name 属性的值。
$biosname = [wmisearcher]"Select Name from Win32_Bios"
$biosname.Get()
__GENUS : 2
__CLASS : Win32_BIOS
__SUPERCLASS :
__DYNASTY :
__RELPATH :
__PROPERTY_COUNT : 1
__DERIVATION : {}
__SERVER :
__NAMESPACE :
__PATH :
Name : S03KT39A
PSComputerName :
使用基本 WQL WHERE 语句
WHERE
语句为 SELECT
语句返回的数据建立条件。
WHERE
语句具有以下格式:
WHERE <property> <operator> <value>
例如:
WHERE Name = 'Notepad.exe'
WHERE
语句与 SELECT
语句一起使用,如以下示例所示。
SELECT * FROM Win32_Process WHERE Name = 'Notepad.exe'
使用 WHERE
语句时,属性名称和值必须准确。
例如,以下命令将获取本地计算机上的记事本进程。
Get-WmiObject -Query "SELECT * FROM Win32_Process WHERE name='Notepad.exe'"
但是,以下命令失败,因为进程名称包含 .exe
文件扩展名。
Get-WmiObject -Query "SELECT * FROM Win32_Process WHERE name='Notepad'"
WHERE 语句比较运算符
以下运算符在 WQL WHERE
语句中有效。
Operator Description
-----------------------
= Equal
!= Not equal
<> Not equal
< Less than
> Greater than
<= Less than or equal
>= Greater than or equal
LIKE Wildcard match
IS Evaluates null
ISNOT Evaluates not null
ISA Evaluates a member of a WMI class
还有其他运算符,但这些运算符用于进行比较。
例如,以下查询从 Win32_Process 类中进程优先级大于或等于 11 的进程中选择 Name 和 Priority 属性。
Get-WmiObject
cmdlet 运行该查询。
$highPriority = "Select Name, Priority from Win32_Process " +
"WHERE Priority >= 11"
Get-WmiObject -Query $highPriority
在 FILTER 参数中使用 WQL 运算符
WQL 运算符还可以用在 或 Get-WmiObject
cmdlet 的 Get-CimInstance
参数的值中,以及这些 cmdlet 的 Query 参数的值中。
例如,以下命令可获取 ProcessID 值大于 1004 的最后五个进程的 Name 和 ProcessID 属性。 该命令使用 Filter 参数指定 ProcessID 条件。
$getWmiObjectSplat = @{
Class = 'Win32_Process'
Property = 'Name', 'ProcessID'
Filter = "ProcessID >= 1004"
}
Get-WmiObject @getWmiObjectSplat |
Sort-Object ProcessID |
Select-Object Name, ProcessID -Last 5
Name ProcessID
---- ---------
SROSVC.exe 4220
WINWORD.EXE 4664
TscHelp.exe 4744
SnagIt32.exe 4748
WmiPrvSE.exe 5056
使用 LIKE 运算符
LIKE
运算符允许使用通配符来筛选 WQL 查询的结果。
Like Operator Description
--------------------------------------------------
[] Character in a range [a-f] or a set
of characters [abcdef]. The items in
a set don't need to be consecutive or
listed in alphabetical order.
^ Character not in a range [^a-f] or
not in a set [^abcdef]. The items in
a set don't need to be consecutive or
listed in alphabetical order.
% A string of zero or more characters
_ One character.
(underscore) NOTE: To use a literal underscore
in a query string, enclose it in
square brackets [_].
当使用不带任何通配符或范围运算符的 LIKE
运算符时,它的行为类似于等于运算符 (=
),并且仅当对象与模式完全匹配时才返回对象。
可以将范围操作与百分比 (%
) 通配符结合起来,以创建简单但功能强大的筛选器。
LIKE 运算符示例
示例 1:[<range>]
以下命令将启动记事本,然后搜索名称以“H”和“N”之间的字母(不区分大小写)开头的 Win32_Process 类的实例。
该查询应返回从 Hotepad.exe
到 Notepad.exe
的任何进程。
Notepad # Starts Notepad
$query = "SELECT * FROM Win32_Process WHERE Name LIKE '[H-N]otepad.exe'"
Get-WmiObject -Query $query | Select Name, ProcessID
Name ProcessID
---- ---------
notepad.exe 1740
示例 2:[<range>] 和 %
以下命令选择名称以 A 和 P 之间的字母开头(不区分大小写)的所有进程,后跟零个或多个字母的任意组合。
Get-WmiObject
cmdlet 运行该查询,Select-Object
cmdlet 将获取 Name 和 ProcessID 属性,Sort-Object
按名称的字母顺序对结果进行排序。
$query = "SELECT * FROM Win32_Process WHERE name LIKE '[A-P]%'"
Get-WmiObject -Query $query |
Select-Object -Property Name, ProcessID |
Sort-Object -Property Name
示例 3:不在范围中 (^)
以下命令将获取名称不以以下任何字母开头的进程:A、S、W、P、R、C、U、N
后跟零个或多个字母。
$query = "SELECT * FROM Win32_Process WHERE name LIKE '[^ASWPRCUN]%'"
Get-WmiObject -Query $query |
Select-Object -Property Name, ProcessID |
Sort-Object -Property Name
示例 4:任何字符 -- 或 none (%)
以下命令将获取名称以“calc
”开头的进程。
百分比 (%
) 符号是 WQL 通配符。 它等效于 PowerShell 中的星号 (*
) 通配符。
$query = "SELECT * FROM Win32_Process WHERE Name LIKE 'calc%'"
Get-WmiObject -Query $query | Select-Object -Property Name, ProcessID
Name ProcessID
---- ---------
calc.exe 4424
示例 5:一个字符 (_)
以下命令将获取名称具有以下模式的进程:“c_lc.exe
”,其中下划线字符代表任意一个字符。 此模式匹配 calc.exe
到 czlc.exe
或 c9lc.exe
中的任何名称,但不匹配其中“c”和“l”由多个字符分隔的名称。
$query = "SELECT * FROM Win32_Process WHERE Name LIKE 'c_lc.exe'"
Get-WmiObject -Query $query | Select-Object -Property Name, ProcessID
Name ProcessID
---- ---------
calc.exe 4424
示例 6:完全匹配
以下命令将获取名为 WLIDSVC.exe
的进程。 即使查询使用关键字 LIKE
,它也需要完全匹配,因为该值不包含任何通配符。
$query = "SELECT * FROM Win32_Process WHERE name LIKE 'WLIDSVC.exe'"
Get-WmiObject -Query $query | Select-Object -Property Name, ProcessID
```powershell
```output
Name ProcessID
---- ---------
WLIDSVC.exe 84
使用 OR 运算符
若要指定多个独立条件,请使用关键字 OR
。 关键字 OR
出现在 WHERE
子句中。 它对两个(或多个)条件执行非独占 OR
运算,并返回满足任何条件的项目。
OR
运算符具有以下格式:
WHERE <property> <operator> <value> OR <property> <operator> <value> ...
例如,以下命令将获取 Win32_Process WMI 类的所有实例,但仅当进程名称为 winword.exe
或 excel.exe
时才返回它们。
$q = "SELECT * FROM Win32_Process WHERE Name='winword.exe'" +
" OR Name='excel.exe'"
Get-WmiObject -Query $q
OR
语句可以用于两个以上的条件。 在以下查询中,OR
语句将获取 Winword.exe
、Excel.exe
或 Powershell.exe
。
$q = "SELECT * FROM Win32_Process WHERE Name='winword.exe'" +
" OR Name='excel.exe' OR Name='powershell.exe'"
使用 AND 运算符
若要指定多个相关条件,请使用关键字 AND
。 关键字 AND
出现在 WHERE
子句中。 它将返回满足所有条件的项目。
AND
运算符具有以下格式:
WHERE <property> <operator> <value> `AND` <property> <operator> <value> ...
例如,以下命令将获取名称为“Winword.exe
”且进程 ID 为 6512 的进程。
请注意,这些命令使用 Get-CimInstance
cmdlet。
$q = "SELECT * FROM Win32_Process WHERE Name = 'winword.exe' " +
"AND ProcessID =6512"
Get-CimInstance -Query $q
ProcessId Name HandleCount WorkingSetSize VirtualSize
--------- ---- ----------- -------------- -----------
# 6512 WINWORD.EXE 768 117170176 633028608
所有运算符(包括 LIKE
运算符)都对 OR
和 AND
运算符有效。 而且,可以将 OR
和 AND
运算符组合在一个带有括号的查询中,告知 Windows PowerShell 先处理哪些子句。
此命令使用 Windows PowerShell 延续字符 (`
) 将命令划分为两行。
搜索 NULL 值
在 WMI 中搜索空值具有挑战性,因为它可能会导致不可预测的结果。
Null
不是零,它不等效于空字符串。 有些 WMI 类属性已初始化,而其他属性则未初始化,因此搜索 null 可能不适用于所有属性。
要搜索 null 值,请使用包含“null”的 Is 运算符。
例如,以下命令将获取 IntallDate 属性为 null 值的进程。 这些命令会返回许多进程。
$q = "SELECT * FROM Win32_Process WHERE InstallDate is null"
Get-WmiObject -Query $q
相反,以下命令将获取 Description 属性具有 null 值的用户帐户。 此命令不会返回任何用户帐户,即使大多数用户帐户的 Description 属性没有任何值。
$q = "SELECT * FROM Win32_UserAccount WHERE Description is null"
Get-WmiObject -Query $q
若要查找没有 Description 属性值的用户帐户,请使用等于运算符获取空字符串。 若要表示空字符串,请使用两个连续的单引号。
$q = "SELECT * FROM Win32_UserAccount WHERE Description = '' "
使用 true 或 false
若要获取 WMI 对象属性中的布尔值,请使用 True
和 False
。
它们不区分大小写。
以下 WQL 查询仅返回来自加入域的计算机的本地用户帐户。
$q = "SELECT * FROM Win32_UserAccount WHERE LocalAccount = True"
Get-CimInstance -Query $q
若要查找域帐户,请使用值为 False,如以下示例所示。
$q = "SELECT * FROM Win32_UserAccount WHERE LocalAccount = False"
Get-CimInstance -Query $q
使用转义字符
WQL 使用反斜杠 (\
) 作为其转义字符。 这与 Windows PowerShell 不同,后者使用反杆字符 (`
)。
引号以及用于引号的字符通常需要转义,以免被误解。
若要查找名称包含单引号的用户,请使用反斜杠对单引号进行转义,如以下命令所示。
$q = "SELECT * FROM Win32_UserAccount WHERE Name = 'Tim O\'Brian'"
Get-CimInstance -Query $q
Name Caption AccountType SID Domain
---- ------- ----------- --- ------
Tim O'Brian FABRIKAM\TimO 512 S-1-5-21-1457... FABRIKAM
在某些情况下,反斜杠也需要转义。 例如,以下命令由于 Caption 值中的反斜杠而生成无效查询错误。
$q = "SELECT * FROM Win32_UserAccount WHERE Caption = 'Fabrikam\TimO'"
Get-CimInstance -Query $q
Get-CimInstance : Invalid query
At line:1 char:1
+ Get-CimInstance -Query $q
+ ~~~~~~~~~~~
+ CategoryInfo : InvalidArgument: (:) [Get-CimInstance], CimExcep
+ FullyQualifiedErrorId : HRESULT 0x80041017,Microsoft.Management.Infrastr
若要转义反斜杠,请使用第二个反斜杠字符,如以下命令所示。
$q = "SELECT * FROM Win32_UserAccount WHERE Caption = 'Fabrikam\\TimO'"
Get-CimInstance -Query $q