about_Operators
简短说明
介绍 PowerShell 支持的运算符。
长说明
运算符是可以在命令或表达式中使用的语言元素。 PowerShell 支持多种类型的运算符来帮助操作值。
算术运算符
使用算术运算符 (+
、、-
、 *
/
%
、) 来计算命令或表达式中的值。 使用这些运算符,可以加、减、乘或除值,并计算除法运算的余数 (取模) 。
加法运算符连接元素。 乘法运算符返回每个元素的指定副本数。 可以在实现算术运算符的任何 .NET 类型上使用算术运算符,例如: Int
、 String
、 DateTime
、 Hashtable
和 数组。
位运算符 (-band
、-bor
、、-bxor
-bnot
、-shl
、 -shr
) 操作值中的位模式。
有关详细信息,请参阅 about_Arithmetic_Operators。
赋值运算符
使用赋值运算符 (=
、+=
、、-=
*=
、 /=
%=
) 将值赋值、更改或追加到变量。 可以将算术运算符与赋值结合使用,以将算术运算的结果分配给变量。
有关详细信息,请参阅 about_Assignment_Operators。
比较运算符
使用比较运算符 (-eq
、-ne
、、-gt
-lt
、 -le
-ge
) 来比较值和测试条件。 例如,可以比较两个字符串值以确定它们是否相等。
比较运算符还包括查找或替换文本中的模式的运算符。 (、 、) 运算符使用正则表达式, (-like
) -notlike
使用通配符 *
。 -replace
-notmatch
-match
包含比较运算符确定测试值是否出现在 (-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_Split 和 about_Join。
类型运算符
使用 、、 -as
) (-is
-isnot
类型运算符查找或更改对象的 .NET 类型。
有关详细信息,请参阅 about_Type_Operators。
一元运算符
使用一元 ++
和 --
运算符递增或递减值,并 -
用于求反。 例如,若要将变量$a
从 递增为 10
,请键入 $a++
9
。
有关详细信息,请参阅 about_Arithmetic_Operators。
特殊运算符
特殊运算符具有不适合任何其他运算符组的特定用例。 例如,特殊运算符允许运行命令、更改值的数据类型或从数组中检索元素。
分组运算符 ( )
与其他语言一样, (...)
用于替代表达式中的运算符优先级。 例如: (1 + 2) / 3
但是,在 PowerShell 中,还有其他行为。
对结果表达式进行分组
(...)
允许 命令的输出 参与表达式。
例如:
PS> (Get-Item *.txt).Count -gt 10
True
管道分组表达式
用作管道的第一段时,将命令或表达式括在括号中总是会导致表达式结果的 枚举 。 如果括号包装 命令,则会在通过管道发送结果之前,在 内存中收集 的所有输出运行到完成。
在管道之前对表达式进行分组还可确保后续的逐个对象处理不会干扰命令用于生成其输出的枚举。
分组赋值语句
未分组的赋值语句不输出值。 对赋值语句进行分组时,将 传递 分配的变量的值,并且可以在较大的表达式中使用。 例如:
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
) 混淆。
Subexpression 运算符 $( )
返回一个或多个 语句的结果。 对于单个结果, 返回 标量。 对于多个结果, 返回一个数组。 如果要在另一个表达式中使用表达式,请使用此选项。 例如,在字符串表达式中嵌入命令的结果。
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
Array subexpression 运算符 @( )
以数组形式返回一个或多个语句的结果。 结果始终是包含 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。
此示例将命令存储在字符串中,并使用 call 运算符执行该命令。
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.
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.
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 作业的后台运行管道之前。 此运算符的行为类似于 UNIX 控件运算符和 (&
) ,后者在子shell 中以作业方式异步运行命令。
此运算符在功能上等效于 Start-Job
。 默认情况下,后台操作员启动启动并行任务的调用方当前工作目录中的作业。 以下示例演示后台作业运算符的基本用法。
Get-Process -Name pwsh &
该命令在功能上等效于 的以下用法 Start-Job
:
Start-Job -ScriptBlock {Get-Process -Name pwsh}
与 一样 Start-Job
, &
后台运算符返回 Job
对象。 此对象可以与 和 Remove-Job
一起使用Receive-Job
,就像用于Start-Job
启动作业一样。
$job = Get-Process -Name pwsh &
Receive-Job $job -Wait
NPM(K) PM(M) WS(M) CPU(s) Id SI ProcessName
------ ----- ----- ------ -- -- -----------
0 0.00 221.16 25.90 6988 988 pwsh
0 0.00 140.12 29.87 14845 845 pwsh
0 0.00 85.51 0.91 19639 988 pwsh
Remove-Job $job
后台 &
运算符也是语句终止符,就像 UNIX 控件运算符和 (&
) 一样。 这允许在后台运算符之后 &
调用其他命令。 以下示例演示在后台运算符之后 &
调用其他命令。
$job = Get-Process -Name pwsh & Receive-Job $job -Wait
NPM(K) PM(M) WS(M) CPU(s) Id SI ProcessName
------ ----- ----- ------ -- -- -----------
0 0.00 221.16 25.90 6988 988 pwsh
0 0.00 140.12 29.87 14845 845 pwsh
0 0.00 85.51 0.91 19639 988 pwsh
这等效于以下脚本:
$job = Start-Job -ScriptBlock {Get-Process -Name pwsh}
Receive-Job $job -Wait
如果要运行多个命令,每个命令在其自己的后台进程中,但全部位于一行中,只需在每个命令之间和之后放置 &
即可。
Get-Process -Name pwsh & Get-Service -Name BITS & Get-CimInstance -ClassName Win32_ComputerSystem &
有关 PowerShell 作业的详细信息,请参阅 about_Jobs。
强制转换运算符 [ ]
将对象转换为指定类型或将其限制为指定类型。 如果无法转换对象,PowerShell 将生成错误。
[DateTime] '2/20/88' - [DateTime] '1/20/88' -eq [TimeSpan] '31'
使用强制转换表示法将变量分配给时,还可以执行 强制转换。
逗号运算符 ,
作为二进制运算符,逗号创建数组或追加到要创建的数组。 在表达式模式下,逗号作为一元运算符创建一个仅包含一个成员的数组。 将逗号放在成员前面。
$myArray = 1,2,3
$SingleArray = ,1
Write-Output (,1)
由于 Write-Output
需要参数,必须将表达式放在括号中。
Dot sourcing 运算符 .
在当前作用域中运行脚本,以便脚本创建的任何函数、别名和变量都添加到当前范围,并重写现有函数、 别名和变量。 脚本声明的参数将成为变量。 未为其指定任何值的参数将成为没有值的变量。 但是,自动变量 $args
将保留。
. c:\scripts\sample.ps1 1 2 -Also:3
注意
点寻源运算符后跟一个空格。 使用空格将点与表示当前目录的 .
点 () 符号区分开来。
在以下示例中,当前目录中的 Sample.ps1 脚本在当前范围内运行。
. .\sample.ps1
格式运算符 -f
使用字符串对象的 format 方法设置字符串格式。 在运算符左侧输入格式字符串,并在运算符右侧输入要格式化的对象。
"{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}
有关详细信息,请参阅 String.Format 方法和 复合格式设置。
Index 运算符 [ ]
从索引集合中选择对象,例如数组和哈希表。 数组索引从零开始,因此第一个对象索引为 [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...
当对象不是索引集合时,使用 index 运算符访问第一个元素将返回对象本身。 超出第一个元素的索引值返回 $null
。
PS> (2)[0]
2
PS> (2)[-1]
2
PS> (2)[1] -eq $null
True
PS> (2)[0,0] -eq $null
True
管道运算符 |
将 (“pipes”) 它前面的命令的输出发送到它后面的命令。 当输出包含多个对象 (“集合”) 时,管道运算符一次发送一个对象。
Get-Process | Get-Member
Get-Service | Where-Object {$_.StartType -eq 'Automatic'}
管道链运算符 &&
和 ||
根据左侧管道的成功有条件地执行右侧管道。
# If Get-Process successfully finds a process called notepad,
# Stop-Process -Name notepad is called
Get-Process notepad && Stop-Process -Name notepad
# If npm install fails, the node_modules directory is removed
npm install || Remove-Item -Recurse ./node_modules
有关详细信息,请参阅 About_Pipeline_Chain_Operators。
范围运算符 ..
range 运算符可用于表示顺序整数或字符的数组。 由 range 运算符联接的值定义范围的开始和结束值。
注意
PowerShell 6 中添加了对字符范围的支持。
数字范围
1..10
$max = 10
foreach ($a in 1..$max) {Write-Host $a}
还可以按相反顺序创建区域。
10..1
5..-5 | ForEach-Object {Write-Output $_}
范围的起始值和结束值可以是计算结果为整数或字符的任意表达式对。 范围的终结点必须可转换为有符号 32 位整数 ([int32]
) 。 较大的值会导致错误。 此外,如果在数组中捕获范围,则生成的数组的大小限制为 [int]::MaxValue - 56
。 这是 .NET 中数组的最大大小。
例如,可以将枚举的成员用于开始值和结束值。
PS> enum Food {
Apple
Banana = 3
Kiwi = 10
}
PS> [Food]::Apple..[Food]::Kiwi
0
1
2
3
4
5
6
7
8
9
10
重要
生成的范围不限于枚举的值。 相反,它表示提供的两个值之间的值范围。 不能使用 range 运算符可靠地表示枚举的成员。
字符范围
若要创建一系列字符,请将字符括在引号中。
PS> 'a'..'f'
a
b
c
d
e
f
PS> 'F'..'A'
F
E
D
C
B
A
如果将字符范围分配给字符串,则将其视为将字符数组分配给字符串的相同。
PS> [string]$s = 'a'..'e'
$s
a b c d e
$a = 'a', 'b', 'c', 'd', 'e'
$a
a b c d e
数组中的字符联接到字符串中。 字符由首选项变量的值 $OFS
分隔。 有关详细信息,请参阅 about_Preference_Variables。
数组中字符的顺序由字符的 ASCII 值决定。 例如,和 X
的 c
ASCII 值分别为 99 和 88。 该范围将按相反顺序显示。
PS> 'c'..'X'
c
b
a
`
_
^
]
\
[
Z
Y
X
成员访问运算符 .
访问 对象的属性和方法。 成员名称可以是表达式。
$myProcess.peakWorkingSet
(Get-Process PowerShell).kill()
'OS', 'Platform' | Foreach-Object { $PSVersionTable. $_ }
从 PowerShell 3.0 开始,当你对没有 成员的列表集合对象使用 运算符时,PowerShell 会自动枚举该集合中的项,并在其中每个项上使用 运算符。 有关详细信息,请参阅 about_Member-Access_Enumeration。
静态成员运算符 ::
调用 .NET 类的静态属性和方法。 若要查找对象的静态属性和方法,请使用 cmdlet 的 Get-Member
Static 参数。 成员名称可以是表达式。
[datetime]::Now
'MinValue', 'MaxValue' | Foreach-Object { [int]:: $_ }
三元运算符 ? <if-true> : <if-false>
在简单条件情况下,可以使用三元运算符来替换 if-else
语句。
有关详细信息,请参阅 about_If。
Null 合并操作符 ??
如果 null 合并运算符 ??
不为 null,则它返回其左操作数的值。 否则,它将计算右操作数并返回其结果。 如果左操作数的计算结果为非 null,则 ??
运算符不会计算其右操作数。
$x = $null
$x ?? 100
100
在下面的示例中,不会计算右操作数。
[string] $todaysDate = '1/10/2020'
$todaysDate ?? (Get-Date).ToShortDateString()
1/10/2020
Null 合并赋值运算符 ??=
仅当左操作数的计算结果为 NULL 时,Null 合并赋值运算符 ??=
才会将其右操作数的值赋值给其左操作数。 如果左操作数的计算结果为非 null,则 ??=
运算符不会计算其右操作数。
$x = $null
$x ??= 100
$x
100
在下面的示例中,不会计算右操作数。
[string] $todaysDate = '1/10/2020'
$todaysDate ??= (Get-Date).ToShortDateString()
$todaysDate
1/10/2020
Null 条件运算符 ?.
和 ?[]
备注
在 PowerShell 7.1 中,此功能已从实验性功能转变为主要功能。
仅当操作数的计算结果为非 NULL 时,NULL 条件运算符才对其操作数应用成员访问 ?.
或元素访问 ?[]
操作;否则,它会返回 NULL。
由于 PowerShell 允许 ?
作为变量名称的一部分,因此使用这些运算符需要变量名称的形式规范。 当 是变量名称 的${a?}
一部分时?
,必须使用大括号 ({}
变量名称周围) ,例如 ${a}
或 。
注意
的变量名称语法 ${<name>}
不应与 $()
subexpression 运算符混淆。 有关详细信息,请参阅 about_Variables 的“变量名称”部分。
在以下示例中,返回 PropName 的值。
$a = @{ PropName = 100 }
${a}?.PropName
100
以下示例返回 null,但不尝试访问成员名称 PropName。
$a = $null
${a}?.PropName
在此示例中,返回索引元素的值。
$a = 1..10
${a}?[0]
1
以下示例在不尝试访问索引元素的情况下返回 null。
$a = $null
${a}?[0]