about_Operators

简短说明

介绍 PowerShell 支持的运算符。

长说明

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

算术运算符

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

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

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

有关详细信息,请参阅 about_Arithmetic_Operators

赋值运算符

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

有关详细信息,请参阅 about_Assignment_Operators

比较运算符

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

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

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

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

有关详细信息,请参阅 about_Comparison_Operators

逻辑运算符

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

有关详细信息,请参阅 about_Logical_Operators

重定向运算符

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

有关详细信息,请参阅 about_Redirection

拆分和联接运算符

-split-join运算符将子字符串除以并组合。 运算符 -split 将字符串拆分为子字符串。 运算符 -join 将多个字符串串联成一个字符串。

有关详细信息,请参阅 about_Splitabout_Join

类型运算符

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

有关详细信息,请参阅 about_Type_Operators

一元运算符

使用一元 ++-- 运算符递增或递减值,以及 - 求反。 例如,若要从中910递增变量$a,请键入$a++

有关详细信息,请参阅 about_Arithmetic_Operators

特殊运算符

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

分组运算符 ( )

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

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

  • (...) 允许 命令 的输出参与表达式。 例如:

    PS> (Get-Item *.txt).Count -gt 10
    True
    
  • 当用作管道的第一段时,将命令或表达式包装在括号中总是会导致表达式结果的 枚举 。 如果括号包装命令,则会在通过管道发送结果之前,运行该 命令以完成内存 中收集 的所有输出。

子表达式运算符 $( )

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

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

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

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 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
+ & "1+1"
+  ~~~~~
    + CategoryInfo          : ObjectNotFound: (1+1:String) [], CommandNotFoundException
    + FullyQualifiedErrorId : CommandNotFoundException
PS> Invoke-Expression "1+1"
2

可以使用调用运算符使用其文件名执行脚本。 下面的示例显示了包含空格的脚本文件名。 尝试执行脚本时,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 对象。 此对象可用于 Receive-JobRemove-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 需要参数,您必须将表达式置于括号中。

点溯运算符 .

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

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

注意

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

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

. .\sample.ps1

Format 运算符 -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 方法和 复合格式设置

索引运算符 [ ]

从索引集合中选择对象,例如数组和哈希表。 数组索引是从零开始的,因此第一个对象被索引为 [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

管道运算符 |

(“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 运算符 ..

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

注意

PowerShell 6 中添加了对字符范围的支持。

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

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

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

若要创建一系列字符,请将字符括在引号中。

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 值决定。 例如,ASCII 值cX分别为 99 和 88。 该范围将按相反的顺序显示。

PS> 'c'..'X'
c
b
a
`
_
^
]
\
[
Z
Y
X

范围的开始和结束值可以是计算结果为整数或字符的任何表达式对。 例如,可以将枚举的成员用于开始值和结束值。

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

重要

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

Member-access 运算符 .

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

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

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

静态成员运算符 ::

调用.NET Framework类的静态属性和方法。 若要查找对象的静态属性和方法,请使用 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()
1/10/2020

Null 条件运算符 ?.?[]

注意

这是一项实验性功能。 有关详细信息 ,请参阅about_Experimental_Features

仅当操作数的计算结果为非 NULL 时,NULL 条件运算符才对其操作数应用成员访问 ?. 或元素访问 ?[] 操作;否则,它会返回 NULL。

由于 PowerShell 允许 ? 作为变量名称的一部分,因此使用这些运算符需要变量名称的形式规范。 因此,使用 {} 将变量名称括起来(如 ${a})或 ? 是变量名称 ${a?} 的一部分时需要形式规范。

在以下示例中,返回 PropName 的值。

$a = @{ PropName = 100 }
${a}?.PropName
100

以下示例将返回 NULL,而不尝试访问成员名称 PropName。

$a = $null
${a}?.PropName

同样,将返回元素的值。

$a = 1..10
${a}?[0]
1

如果操作数为 NULL,则不会访问元素并返回 NULL。

$a = $null
${a}?[0]

备注

由于 PowerShell 允许 ? 作为变量名称的一部分,因此使用这些运算符需要变量名称的形式规范。 因此,使用 {} 将变量名称括起来(如 ${a})或 ? 是变量名称 ${a?} 的一部分时需要形式规范。

不应将变量名称语法 ${<name>}$() 子表达式运算符混淆。 有关详细信息,请参阅 about_Variables 的“变量名称”部分。

请参阅