about_Operators

简短说明

介绍 PowerShell 支持的运算符。

长说明

运算符是可在命令或表达式中使用的语言元素。 PowerShell 支持多种类型的运算符来帮助你操作值。

算术运算符

使用算术运算符(+-*/%)计算命令或表达式中的值。 使用这些运算符可以对值进行加减乘除,还可计算除法运算的余数(模数)。

加法运算符可连接元素。 乘法运算符返回每个元素的指定副本数。 可在任何实现它们的 .NET 类型上使用算术运算符,例如:IntStringDateTimeHashtable 和数组。

按位运算符(-band-bor-bxor-bnot-shl-shr)操作值中的位模式。

有关详细信息,请参阅 about_Arithmetic_Operators

赋值运算符

使用赋值运算符(=+=-=*=/=%=)向变量赋值、更改值或追加值。 可以将算术运算符与赋值结合起来,将算术运算的结果赋值给变量。

有关详细信息,请参阅 about_Assignment_Operators

比较运算符

使用比较运算符(-eq-ne-gt-lt-le-ge)来比较值和测试条件。 例如,可以比较两个字符串值,确定它们是否相等。

比较运算符还包括用于在文本中查找或替换模式的运算符。 -match-notmatch-replace 运算符使用正则表达式,-like-notlike 使用通配符 *

包含比较运算符确定测试值是否出现在引用集中(-in-notin-contains-notcontains)。

类型比较运算符(-is-isnot)确定对象是否为给定类型。

有关详细信息,请参阅 about_Comparison_Operators

逻辑运算符

使用逻辑运算符(-and-or-xor-not!)将条件语句连接到单个复杂条件中。 例如,可以使用逻辑 -and 运算符创建具有两个不同条件的对象筛选器。

有关详细信息,请参阅 about_Logical_Operators

重定向运算符

使用重定向运算符(>>>2>2>>2>&1)将命令或表达式的输出发送到文本文件。 重定向运算符的工作方式类似于 Out-File cmdlet(不含参数),但它们还允许将错误输出重定向到指定的文件。 也可使用 Tee-Object cmdlet 重定向输出。

有关详细信息,请参阅 about_Redirection

拆分运算符和联接运算符

-split-join 运算符对子字符串进行划分和组合。 -split 运算符将字符串拆分为子字符串。 -join 运算符将多个字符串连接成一个字符串。

有关详细信息,请参阅 about_Splitabout_Join

类型运算符

使用类型运算符(-is-isnot-as)查找或更改对象的 .NET 类型。

有关详细信息,请参阅 about_Type_Operators

一元运算符

使用一元 ++-- 运算符递增或递减值,使用 - 进行求反。 例如,若要将变量 $a9 递增到 10,请键入 $a++

有关详细信息,请参阅 about_Arithmetic_Operators

特殊运算符

特殊运算符具有不适合任何其他运算符组的特定用例。 例如,通过特殊运算符,你可以运行命令、更改值的数据类型或从数组中检索元素。

分组运算符 ( )

与其他语言一样,(...) 用于重写表达式中的运算符优先级。 例如:(1 + 2) / 3

但是在 PowerShell 中,还有其他行为。

对结果表达式进行分组

借助 (...),来自命令的输出可以参与表达式。 例如:

PS> (Get-Item *.txt).Count -gt 10
True

注意

将命令括在括号中会导致将自动变量 $? 设置为 $true,即使被括住的命令本身将 $? 设置为 $false。 例如,(Get-Item /Nosuch); $? 意外地生成 True。 有关 $? 的详细信息,请参阅 about_Automatic_Variables

将分组表达式放入管道

用作管道的第一段时,将命令或表达式包装在括号中总是会导致枚举表达式结果。 如果命令包装在括号中,则在通过管道发送结果之前,该命令会完成运行且所有输出收集在内存中。

例如,这些语句的输出是不同的:

PS> ConvertFrom-Json '["a", "b"]'   | ForEach-Object { "The value is '$_'" }

The value is 'a b'

PS> (ConvertFrom-Json '["a", "b"]') | ForEach-Object { "The value is '$_'" }

The value is 'a'
The value is 'b'

如果在放入管道之前对表达式分组,还可确保后续的逐个对象处理不会干扰命令用于生成其输出的枚举。

例如,通过管道将输出从 Get-ChildItem 传递给 Rename-Item 可能会产生意外的效果,其中的项被重命名,然后再次被发现并重命名。

对赋值语句进行分组

未分组的赋值语句不会输出值。 对赋值语句进行分组时,赋值变量的值是传递的值,可在较大的表达式中使用。 例如:

PS> ($var = 1 + 2)
3
PS> ($var = 1 + 2) -eq 3
True

将语句包装在括号中会将其转换为输出 $var 的值的表达式。

此行为适用于所有赋值运算符,包括复合运算符(如 +=)、递增运算符 (++) 和递减运算符 (--)。 但是,递增和递减运算的顺序取决于其位置。

PS> $i = 0
PS> (++$i) # prefix
1
PS> $i = 0
PS> ($i++) # postfix
0
PS> $i
1

在前缀情况下,$i 的值在输出之前递增。 在后缀情况下,$i 的值在输出之后递增。

还可以在条件语句(例如 if 语句)的上下文中使用此方法。

if ($textFiles = Get-ChildItem *.txt) {
    $textFiles.Count
}

在此示例中,如果没有文件匹配,Get-ChildItem 命令不会返回任何内容,并且不会向 $textFiles 进行任何赋值,这在布尔上下文中被视为 $false。 如果将一个或多个 FileInfo 对象赋值给 $textFiles,则条件计算结果为 $true。 可以使用 if 语句正文中的 $textFiles 值。

注意

虽然此方法方便简洁,但它可能会导致赋值运算符 (=) 和相等比较运算符 (-eq) 之间出现混淆。

子表达式运算符 $( )

返回一个或多个语句的结果。 对于单个结果,返回 量。 对于多个结果,返回一个数组。 如果要在另一个表达式中使用某个表达式,请使用此方法。 例如,在字符串表达式中嵌入命令的结果。

PS> "Today is $(Get-Date)"
Today is 12/02/2019 13:15:20

PS> "Folder list: $((dir c:\ -dir).Name -join ', ')"
Folder list: Program Files, Program Files (x86), Users, Windows

数组表达式运算符 @( )

以数组形式返回一个或多个语句的结果。 结果始终为 0 个或多个对象的数组。

PS> $list = @(Get-Process | Select-Object -First 10; Get-Service | Select-Object -First 10 )
PS> $list.GetType()

IsPublic IsSerial Name                                     BaseType
-------- -------- ----                                     --------
True     True     Object[]                                 System.Array

PS> $list.Count
20
PS> $list = @(Get-Service | Where-Object Status -eq Starting )
PS> $list.GetType()

IsPublic IsSerial Name                                     BaseType
-------- -------- ----                                     --------
True     True     Object[]                                 System.Array

PS> $list.Count
0

哈希表文本语法 @{}

与数组子表达式类似,此语法用于声明哈希表。 有关详细信息,请参阅 about_Hash_Tables

调用运算符 &

运行命令、脚本或脚本块。 调用运算符(也称为 调用运算符)允许运行存储在变量中并由字符串或脚本块表示的命令。 调用运算符在子作用域中执行。 有关作用域的详细信息,请参阅 about_Scopes。 可以使用它生成包含所需命令、参数和参数的字符串,然后像调用命令一样调用字符串。 创建的字符串必须与在命令行中键入的命令遵循相同的分析规则。 有关详细信息,请参阅 about_Parsing

此示例将命令存储在字符串中,并使用调用运算符执行该命令。

PS> $c = "get-executionpolicy"
PS> $c
get-executionpolicy
PS> & $c
AllSigned

调用运算符不会分析字符串。 这意味着在使用调用运算符时,不能在字符串中使用命令参数。

PS> $c = "Get-Service -Name Spooler"
PS> $c
Get-Service -Name Spooler
PS> & $c
& : The term 'Get-Service -Name Spooler' is not recognized as the name of a
cmdlet, function, script file, or operable program. Check the spelling of
the name, or if a path was included, verify that the path is correct and
try again.
At line:1 char:2
+ & $c
+  ~~
    + CategoryInfo          : ObjectNotFound: (Get-Service -Name Spooler:String) [], CommandNotFoundException
    + FullyQualifiedErrorId : CommandNotFoundException

Invoke-Expression cmdlet 可执行在使用调用运算符时导致分析错误的代码。

PS> & "1+1"
&: The term '1+1' is not recognized as a name of a cmdlet, function, script
file, or executable program. Check the spelling of the name, or if a path was
included, verify that the path is correct and try again.
At line:1 char:2
+ & "1+1"
+  ~~~~~
    + CategoryInfo          : ObjectNotFound: (1+1:String) [], CommandNotFoundException
    + FullyQualifiedErrorId : CommandNotFoundException
PS> Invoke-Expression "1+1"
2

可以使用脚本的文件名执行脚本。 脚本文件的文件扩展名必须是 .ps1 才能执行。 路径包含空格的文件必须用引号括起来。 如果尝试执行带引号的路径,PowerShell 将显示带引号的字符串的内容,而不是运行脚本。 使用调用运算符可以执行包含文件名字符串的内容。

PS C:\Scripts> Get-ChildItem

    Directory: C:\Scripts


Mode                LastWriteTime         Length Name
----                -------------         ------ ----
-a----        8/28/2018   1:36 PM             58 script name with spaces.ps1

PS C:\Scripts> ".\script name with spaces.ps1"
.\script name with spaces.ps1
PS C:\Scripts> & ".\script name with spaces.ps1"
Hello World!

有关脚本块的详细信息,请参阅 about_Script_Blocks

强制转换运算符 [ ]

将对象转换或限制为指定类型。 如果无法转换对象,PowerShell 会生成错误。

[DateTime] '2/20/88' - [DateTime] '1/20/88' -eq [TimeSpan] '31'

当使用强制转换表示法对变量赋值时,也可以执行强制转换。

逗号运算符 ,

作为二元运算符,逗号会创建数组或追加到要创建的数组。 在表达式模式下,作为一元运算符,逗号创建只有一个成员的数组。 将逗号放置在成员前面。

$myArray = 1,2,3
$SingleArray = ,1
Write-Output (,1)

Write-Output 需要参数,因此必须将表达式放在括号中。

点溯源运算符 .

在当前作用域内运行脚本,以便脚本创建的任何函数、别名和变量都添加到当前作用域,从而重写现有内容。 脚本声明的参数将成为变量。 没有给定值的参数将成为没有值的变量。 但是,将保留自动变量 $args

. c:\scripts\sample.ps1 1 2 -Also:3

注意

点溯源运算符后跟空格。 使用空格将点与表示当前目录的点 (.) 符号区分开来。

在以下示例中,当前目录中的 Sample.ps1 脚本在当前作用域内运行。

. .\sample.ps1

格式运算符 -f

提供对 .NET 复合格式设置功能的访问权限。 复合格式字符串由与索引占位符混合的固定文本组成,称为 格式项。 这些格式项对应于列表中的对象。

每个格式项都采用下面的形式并包含以下组件:

{index[,alignment][:formatString]}

必须使用成对的大括号({})。

格式设置操作产生的结果字符串由原始固定文本和列表中对象的字符串表示形式混和组成。 有关更多信息,请参见复合格式设置

在运算符左侧输入复合格式字符串,以及要设置运算符右侧格式的对象。

"{0} {1,-10} {2:N}" -f 1,"hello",[math]::pi
1 hello      3.14

可以使用“0”自定义说明符对数值进行零填充。 : 后面的零的数目指示将格式化字符串填充到的最大宽度。

"{0:00} {1:000} {2:000000}" -f 7, 24, 365
07 024 000365

如果需要保留格式化字符串中的大括号 ({}),可通过使用两对大括号来对它们进行转义。

"{0} vs. {{0}}" -f 'foo'
foo vs. {0}

索引运算符 [ ]

从索引集合中选择对象,例如数组和哈希表。 数组索引从零开始,因此第一个对象被索引为 [0]。 还可以使用负索引获取最后一个值。 哈希表按键值进行索引。

给定索引列表后,索引运算符将返回与这些索引对应的成员列表。

PS> $a = 1, 2, 3
PS> $a[0]
1
PS> $a[-1]
3
PS> $a[2, 1, 0]
3
2
1
(Get-HotFix | Sort-Object installedOn)[-1]
$h = @{key="value"; name="PowerShell"; version="2.0"}
$h["name"]
PowerShell
$x = [xml]"<doc><intro>Once upon a time...</intro></doc>"
$x["doc"]
intro
-----
Once upon a time...

当对象不是索引集合时,使用索引运算符访问第一个元素时将返回对象本身。 超出第一个元素的索引值会返回 $null

PS> (2)[0]
2
PS> (2)[-1]
2
PS> (2)[1] -eq $null
True
PS> (2)[0,0] -eq $null
True

管道运算符 |

将它前面的命令的输出发送(“管道传递”)到它后面的命令。 当输出包含多个对象(“集合”)时,管道运算符一次发送一个对象。

Get-Process | Get-Member
Get-Service | Where-Object {$_.StartType -eq 'Automatic'}

范围运算符 ..

范围运算符可用于表示顺序整数的数组。 范围运算符联接的值定义了范围的开始值和结束值。

1..10
$max = 10
foreach ($a in 1..$max) {Write-Host $a}

还可以按相反顺序创建范围。

10..1
5..-5 | ForEach-Object {Write-Output $_}

范围的开始值和结束值可以是计算结果为整数或字符的任何表达式对。 范围的终结点必须可转换为有符号的 32 位整数([int32])。 较大的值会导致错误。 此外,如果在数组中捕获该范围,则生成的数组的大小限制为 268435448 (或 256mb - 8)。 这是 .NET Framework 中数组的最大大小。

例如,可以将枚举的成员用于开始值和结束值。

PS> enum Food {
      Apple
      Banana = 3
      Kiwi = 10
    }
PS> [Food]::Apple..[Food]::Kiwi
0
1
2
3
4
5
6
7
8
9
10

重要

生成的范围不限于枚举的值, 而是表示提供的两个值之间的值范围。 不能使用范围运算符可靠地表示枚举的成员。

成员访问运算符 .

访问对象的属性和方法。 成员名称可以是表达式。

$myProcess.peakWorkingSet
(Get-Process PowerShell).kill()
'OS', 'Platform' | Foreach-Object { $PSVersionTable. $_ }

从 PowerShell 3.0 开始,在对没有成员的列表集合对象使用运算符时,PowerShell 会自动枚举该集合中的项,并在其中每个项上使用运算符。 有关详细信息,请参阅 about_Member Access_Enumeration

静态成员运算符 ::

调用 .NET 类的静态属性和方法。 若要查找对象的静态属性和方法,请使用 Get-Member cmdlet 的 Static 参数。 成员名称可以是表达式。

[datetime]::Now
'MinValue', 'MaxValue' | Foreach-Object { [int]:: $_ }

另请参阅