3. 基本概念

编辑说明

重要

Windows PowerShell 语言规范 3.0 于 2012 年 12 月发布,基于 Windows PowerShell 3.0。 此规范不反映 PowerShell 的当前状态。 没有计划更新本文档以反映当前状态。 此处提供了本文档供历史参考。

该规范文档可从 Microsoft 下载中心获取为 Microsoft Word 文档:https://www.microsoft.com/download/details.aspx?id=36389 该文档已在此 Microsoft Learn 上转换为演示文稿。 转换期间,进行了一些编辑更改,以适应 Docs 平台的格式设置。 已更正某些拼写错误和次要错误。

3.1 提供程序和驱动程序

提供程序允许访问通过命令行难以访问的数据和组件。 数据以与文件系统驱动器类似的一致格式显示。

提供程序公开的数据会出现在 驱动器上,并且数据通过 路径 进行访问,就像使用磁盘驱动器一样。 每个提供程序的内置 cmdlet 管理提供程序驱动器上的数据。

PowerShell 包含以下一组内置提供程序,用于访问不同类型的数据存储:

提供程序 驱动器名称 描述 参考
别名 别名: PowerShell 别名 §3.1.1
环境 环境: 环境变量 §3.1.2
FileSystem A:,B:,C:,... 磁盘驱动器、目录和文件 §3.1.3
功能 功能: PowerShell 函数 §3.1.4
变量 变量: PowerShell 变量 §3.1.5

Windows PowerShell:

提供程序 驱动器名称 描述
证书 证书: 用于数字签名的 x509 证书
注册表 HKLM: (HKEY_LOCAL_MACHINE), HKCU: (HKEY_CURRENT_USER) Windows 注册表
WSMan WSMan: WS-Management 配置信息

以下 cmdlet 用于处理提供程序和驱动器:

  • Get-PSProvider:获取有关一个或多个提供程序的信息
  • Get-PSDrive:获取有关一个或多个驱动器的信息

表示提供程序的对象的类型在 §4.5.1中介绍。 表示驱动器的对象的类型在 §4.5.2中介绍。

3.1.1 别名

别名 是命令的备用名称。 命令可以有多个别名,原始名称及其所有别名都可以互换使用。 可以重新分配别名。 别名是项 (§3.3)。

别名可以分配给另一个别名;但是,新别名不是原始命令的别名。

提供程序 Alias 是一个平面命名空间,仅包含表示别名的对象。 变量没有子项。

PowerShell 附带一组内置别名。

以下 cmdlet 处理别名:

  • 新别名:创建别名
  • Set-Alias:创建或更改一个或多个别名
  • Get-Alias:获取有关一个或多个别名的信息
  • Export-Alias:将一个或多个别名导出并保存到文件中

使用 New-Alias为命令创建别名时,该命令的参数不能包含在该别名中。 但是,直接赋值给 Alias 中的变量:命名空间确实允许包含参数。

注意

然而,创建一个只包含对该命令的调用以及所有所需参数的函数,并为该函数分配一个别名,这是一件简单的事情。

表示别名的对象的类型在 §4.5.4中介绍。

别名对象存储在名为“Alias”的驱动器上:(§3.1)。

3.1.2 环境变量

PowerShell 环境提供程序允许检索、添加、更改、清除和删除操作系统环境变量。

提供程序环境是一个平面命名空间,仅包含表示环境变量的对象。 变量没有子项。

环境变量的名称不能包含等号(=)。

对环境变量的更改仅影响当前会话。

环境变量是项(§3.3)。

表示环境变量的对象的类型在 §4.5.6中介绍。

环境变量对象存储在驱动器 Env 上:(§3.1)。

3.1.3 文件系统

PowerShell 文件系统提供程序允许创建、打开、更改和删除目录和文件。

文件系统提供程序是一个分层命名空间,其中包含表示基础文件系统的对象。

文件存储在名称为 A:、B:、C:等的驱动器上(§3.1)。 使用路径表示法(§3.4)访问目录和文件。

目录或文件是项(§3.3)。

3.1.4 函数

PowerShell 函数提供程序允许检索、添加、更改、清除和删除的函数(§8.10)和筛选器(§8.10.1)。

提供者函数是一个仅包含函数对象和筛选器对象的平面命名空间。 函数和筛选器都没有子项。

对函数的更改仅影响当前会话。

函数是项(§3.3)。

表示函数的对象的类型在 §4.5.10中介绍。 表示筛选器的对象的类型在 §4.5.11中介绍。

函数对象存储在驱动器函数上:(§3.1)。

3.1.5 变量

可以直接在 PowerShell 语言中定义和操作变量。

提供者变量是一个平面命名空间,仅包含用于表示变量的对象。 变量没有子项。

以下 cmdlet 还处理变量:

由于变量是一个项 (§3.3),所以它可以被大多数与项相关的 cmdlet 操作。

表示变量的对象的类型在 §4.5.3中介绍。

变量对象存储在驱动器变量上:(§3.1)。

3.2 工作位置

当前工作位置 是命令指向的默认位置。 如果在调用命令时未提供显式路径(§3.4),则使用此位置。 此位置包括当前驱动器

PowerShell 主机可能有多个驱动器,在这种情况下,每个驱动器都有自己的当前位置。

在没有目录的情况下指定驱动器名称时,隐含该驱动器的当前位置。

当前工作位置可以保存在堆栈上,然后设置为新位置。 稍后,可以从该堆栈还原保存的位置,并生成当前工作位置。 有两种类型的位置堆栈:默认工作位置堆栈,以及零个或多个用户定义的 命名工作位置堆栈。 会话开始时,默认工作位置堆栈也是 当前工作位置堆栈。 但是,任何已命名的工作位置栈都可以成为当前工作位置栈。

以下 cmdlet 处理位置:

  • Set-Location:建立当前工作位置
  • Get-Location:确定指定驱动器的当前工作位置或指定堆栈的工作位置
  • Push-Location:将当前工作位置保存在指定位置堆栈的顶部
  • Pop-Location:从指定位置堆栈顶部还原当前工作位置

§4.5.5中介绍了表示工作位置和工作位置堆栈的对象类型。

3.3 个项

是别名(§3.1.1)、变量(§3.1.5)、函数(§3 .1.4)、环境变量(§3.1.2),或文件系统中的文件或目录(§3.1.3)。

以下 cmdlet 处理项:

  • 新项:创建新项
  • Set-Item:更改一个或多个项的值
  • Get-Item:获取位于指定位置的项
  • Get-ChildItem:获取位于指定位置的项和子项
  • 复制项:将一个或多个项目从一个位置复制到另一个位置
  • 移动项:将一个或多个项目从一个位置移动到另一个位置
  • Rename-Item:重命名项
  • 调用项:对一个或多个项执行默认操作
  • Clear-Item:删除一个或多个项的内容,但不删除这些项(请参阅
  • Remove-Item:删除指定的项

以下 cmdlet 处理项的内容:

表示目录的对象的类型在 §4.5.17中介绍。 表示文件的对象的类型在 §4.5.18中介绍。

3.4 路径名称

通过 PowerShell 提供程序可访问的数据存储中的所有项都可以通过其路径名唯一标识。 路径名称 是通过将项名称、其所在容器及子容器,以及用于访问容器的 PowerShell 驱动器组合在一起构成的。

路径名称分为两种类型之一:完全限定和相对。 完全限定的路径名称 包含构成路径的所有元素。 以下语法显示了完全限定路径名称中的元素:

提示

语法定义中的 ~opt~ 表示法指示词法实体在语法中是可选的。

path:
    provider~opt~   drive~opt~   containers~opt~   item

provider:
    module~opt~   provider   ::

module:
    module-name   \

drive:
    drive-name   :

containers:
    container   \
    containers container   \

模块名称 指的是父模块。

提供程序是指访问数据存储的 PowerShell 提供程序。

驱动器是指由特定 PowerShell 提供程序支持的 PowerShell 驱动器。

一个容器可以包含其他容器,这些容器可以包含其他容器,以此类推,最后一个容器包含一个。 容器必须按数据存储中存在的分层顺序指定。

下面是路径名称的示例:

E:\Accounting\InvoiceSystem\Production\MasterAccount\MasterFile.dat

如果路径中的最后一个元素包含其他元素,则它是 容器元素;否则,它是 叶元素

在某些情况下,不需要完全限定的路径名称;相对路径名称将足够。 相对路径名称基于当前工作位置。 PowerShell 允许根据项相对于当前工作位置的位置来识别项。 相对路径名称涉及使用某些特殊字符。 下表描述了这些字符中的每一个,并提供相对路径名称和完全限定的路径名称的示例。 表中的示例基于当前工作目录设置为 C:\Windows:

符号 描述 相对路径 完全限定的路径
. 当前工作位置 .\System C:\Windows\System
.. 当前工作位置的父级 ..\Program Files C:\Program Files
\ 当前工作位置的驱动器根目录 \Program Files C:\Program Files
没有 无特殊字符 System C:\Windows\System

若要在命令中使用路径名称,请将该名称作为完全限定的名称或相对路径名输入。

以下 cmdlet 处理路径:

  • Convert-Path:将路径从 PowerShell 路径转换为 PowerShell 提供程序路径
  • Join-Path:将路径和子路径合并到单个路径中
  • Resolve-Path:解析路径中的通配符
  • 拆分路径:返回路径的指定部分
  • 检查路径:确定路径的元素是否存在或路径格式是否正确

某些 cmdlet(例如 Add-ContentCopy-Item)使用文件筛选器。 文件筛选器 是用于指定从一组路径中进行选择的条件的机制。

表示解析路径的对象类型在 §4.5.5中介绍。 路径经常被处理为字符串。

3.5 范围

3.5.1 简介

名称可以表示变量、函数、别名、环境变量或驱动器。 同名可能表示脚本中不同位置的不同项。 对于一个名称所表示的每个不同项,该名称仅在被称为其 作用域的脚本文本区域中可见。 以相同名称表示的不同项要么具有不同的范围,要么位于不同的名称空间中。

范围可以嵌套,在这种情况下,外层范围称为父范围,任何嵌套的范围都是该父范围的子范围。 名称的范围是定义它的范围和所有子范围,除非它被设为专用。 在子范围中,定义的名称会隐藏在父范围中以相同名称定义的任何项。

除非使用点源表示法(§3.5.5),否则以下每个表示法都会创建新的范围:

  • 脚本文件
  • 脚本块
  • 函数或筛选器

请考虑以下示例:

# Start of script
$x = 2; $y = 3
Get-Power $x $y

# Function defined in script
function Get-Power([int]$x, [int]$y) {
    if ($y -gt 0) {
        return $x * (Get-Power $x (--$y))
    } else {
        return 1
    }
}
# End of script

在脚本中创建的变量 $x$y 的范围是该脚本的主体,包括在其中定义的函数。 函数 Get-Power 定义两个具有相同名称的参数。 由于每个函数都有自己的作用域,这些变量与父范围中定义的变量不同,它们将隐藏父范围中的变量。 函数范围嵌套在脚本作用域内。

请注意,函数以递归方式调用自身。 每次执行此操作时,它都会创建另一个嵌套作用域,每个作用域都有其自己的变量 $x$y

下面是一个更复杂的示例,其中还显示了嵌套的范围和名称重用:

# start of script scope
$x = 2              # top-level script-scope $x created
                    # $x is 2
F1                  # create nested scope with call to function F1
                    # $x is 2
F3                  # create nested scope with call to function F3
                    # $x is 2

function F1 {       # start of function scope
                    # $x is 2
    $x = $true      # function-scope $x created
                    # $x is $true

    & {             # create nested scope with script block
                    # $x is $true
        $x = 12.345 # scriptblock-scope $x created
                    # $x is 12.345
    }               # end of scriptblock scope, local $x goes away

                    # $x is $true
    F2              # create nested scope with call to function F2
                    # $x is $true
}                   # end of function scope, local $x goes away

function F2 {       # start of function scope
                    # $x is $true
    $x = "red"      # function-scope $x created
                    # $x is "red"
}                   # end of function scope, local $x goes away

function F3 {       # start of function scope
                    # $x is 2
    if ($x -gt 0) {
                    # $x is 2
        $x = "green"
                    # $x is "green"
    }               # end of block, but not end of any scope
                    # $x is still "green"
}                   # end of function scope, local $x goes away
# end of script scope

3.5.2 范围名称和数字

PowerShell 支持以下范围:

  • 全局:这是最高级别的范围。 在此范围内定义所有自动变量和首选项变量。 全局作用域是所有其他作用域的父作用域,所有其他作用域都是全局作用域的子作用域。

  • 本地:这是脚本、脚本块或函数中的任何执行点的当前范围。 任何范围都可以是本地范围。

  • 脚本:此范围存在于每个执行的脚本文件中。 脚本范围是从其中创建的所有范围的父范围。 脚本块没有自己的脚本范围;相反,它的脚本范围是它最近的上级脚本文件的范围。 虽然模块范围没有此类内容,但脚本范围提供等效项。

名称可以声明为专用属性,在这种情况下,它们在其父范围之外不可见,甚至对子范围也不可见。 专用概念不是一个单独的范围;它是本地范围的别名,如果用作可写位置,则会隐藏名称。

范围可以由一个数字引用,该数字描述一个范围到另一个范围的相对位置。 范围 0 表示本地范围,范围 1 表示 1 代上级范围,范围 2 表示 2 代祖先范围等。 (范围编号由操纵变量的 cmdlet 使用。)

3.5.3 变量名称范围

如下图所示,变量名可以用六个不同范围中的任何一个指定:

variable-scope:
    global:
    local:
    private:
    script:
    using:
    workflow:
    variable-namespace

范围是可选的。 下表显示了所有可能上下文中每个上下文的含义。 当没有明确指定范围时,它还会显示范围:

范围修饰符 在脚本文件中 在脚本块中 在函数中
global 全局范围 全局范围 全局范围
脚本 最近上级脚本文件的范围,如果没有最近上级脚本文件,则为全局 最近上级脚本文件的范围,如果没有最近上级脚本文件,则为全局 最近上级脚本文件的范围,如果没有最近上级脚本文件,则为全局
private 全局/脚本/本地范围 本地范围 本地范围
local 全局/脚本/本地范围 本地范围 本地范围
using 实现定义的 实现定义的 实现定义的
工作流 实现定义的 实现定义的 实现定义的
没有 全局/脚本/本地作用域范围 本地范围 本地范围

使用 (§3.1.5) 中列出的 cmdlet 系列时,也可以指定变量范围信息。 具体而言,请参阅参数 Scope,以及参数 Option PrivateOption AllScope 以获取详细信息。

范围 using 用于在通过 cmdlet(如 Start-JobInvoke-Command)或内联语句运行脚本时访问在另一个范围中定义的变量。 例如:

$a = 42
Invoke-Command --ComputerName RemoteServer { $using:a } # returns 42
workflow foo
{
    $b = "Hello"
    inlinescript { $using:b }
}
foo # returns "Hello"

范围工作流与 并行语句序列语句 一起使用,以访问工作流中定义的变量。

3.5.4 函数名称范围

函数名称也可能具有四个不同的范围之一,并且该名称的可见性与变量的可见性相同(§3.5.3)。

3.5.5 点源表示法

当脚本文件、脚本块或函数从另一个脚本文件、脚本块或函数内执行时,执行脚本文件将创建新的嵌套范围。 例如,

Script1.ps1
& "Script1.ps1"
& { ... }
FunctionA

但是,当使用 点源表示法 时,在执行命令之前不会创建任何新的作用域,因此原本应在其自身局部作用域进行的添加/更改转而应用于当前作用域。 例如,

. Script2.ps1
. "Script2.ps1"
. { ... }
. FunctionA

3.5.6 模块

就像顶级脚本文件位于分层嵌套范围树的根目录一样,每个模块(§3.14) 也是如此。 但是,默认情况下,只有模块导出的名称才能在导入上下文中按名称使用。 在 cmdlet Import-Module 中,使用全局参数可以使导出的名称更容易被发现。

3.6 只读和常量属性

变量和别名由包含多个属性的对象描述。 这些属性由两个 cmdlet 系列设置和操作(§3.1.5§3.1.1)。 其中一个这样的属性是 Options,可以设置为 ReadOnly 或 Constant(使用 Option 参数)。 可以删除标记为 ReadOnly 的变量或别名,并且可以在指定 Force 参数后更改其属性。 但是,无法删除标记为 Constant 的变量或别名,也不能更改其属性。

3.7 方法重载和调用解析

3.7.1 简介

如 §1 中所述,执行环境(以 PowerShell 以外的某种语言编写)提供的外部过程称为 方法

方法的名称及其参数的数量和类型统称为该方法 签名。 (请注意,签名不包括方法的返回类型。)执行环境可能允许一个类型具有多个具有相同名称的方法,前提是每个方法具有不同的签名。 当定义了某个方法的多个版本时,该方法被称为重载。 例如,Math 类型(§4.3.8)包含一组名为 Abs的方法,该方法计算指定数字的绝对值,其中指定数字可以具有多个类型之一。 该集合中的方法具有以下签名:

Abs(decimal)
Abs(float)
Abs(double)
Abs(int)
Abs(long)
Abs(SByte)
Abs(Int16)

在这种情况下,所有方法都具有相同的参数数;其签名因参数类型而异。

另一个示例涉及 array 类型(§4.3.2),其中包含一组称为 Copy 的方法,该方法将一系列元素从一个数组复制到另一个数组,从每个数组的开头(默认情况下)或在某些指定元素的开头开始。 该集合中的方法具有以下签名:

Copy(Array, Array, int)
Copy(Array, Array, long)
Copy(Array, int, Array, int, int)
Copy(Array, long, Array, long, long)

在这种情况下,签名因参数类型而异,在某些情况下,签名也因参数编号而异。

在对重载方法的大多数调用中,传递的参数的数量和类型与其中一个重载完全匹配,并且所选的方法很明显。 但是,如果情况并非如此,则需要有一种方法来解决调用哪个重载版本(如果有的话)。 例如,

[Math]::Abs([byte]10) # no overload takes type byte
[Array]::Copy($source, 3, $dest, 5L, 4) # both int and long indexes

其他示例包括类型 字符串(即 System.String),其具有大量重载的方法。

尽管 PowerShell 有解决与重载签名不完全匹配的方法调用的规则,但 PowerShell 本身并没有提供定义重载方法的方法。

注意

编辑器说明:PowerShell 5.0 添加了定义基于脚本的类的功能。 这些类可以包含重载的方法。

3.7.2 方法重载解析

给定方法调用(§7.1.3)具有参数表达式的列表,以及一组 候选方法s(即可以调用的方法),选择 最佳方法 的机制称为 重载解析

鉴于适用的候选方法集(§3.7.3),则选择该集中的最佳方法。 如果集仅包含一种方法,则该方法是最佳方法。 否则,最佳方法是在遵循 §3.7.4中所示规则的前提下,相较于给定参数列表中的其他所有方法更优的方法。 如果没有一种方法比所有其他方法都好,那么方法调用是不明确的,并且会报告错误。

最佳方法必须在调用它的上下文中可访问。 例如,PowerShell 脚本无法调用私有或受保护的方法。

对静态方法的调用的最佳方法必须是静态方法,对实例方法的调用的最佳方法必须是实例方法。

3.7.3 适用的方法

当下列条件之一为 true ,对于参数列表 A,一个方法被称为适用

  • A 中的参数数与方法接受的参数数相同。
  • 该方法具有 M 必需参数和 N 个可选参数,A 中的参数数大于或等于 M,但小于 N。
  • 该方法接受可变数量的自变量和 A 中的参数数大于该方法接受的参数数。

除了具有适当的参数数外,A 中的每个参数都必须与参数的参数传递模式匹配,参数类型必须与参数类型匹配,或者必须有从参数类型到参数类型的转换。

如果参数类型为 ref(§4.3.6),则相应的参数也必须为 ref,并且用于转换的自变量类型是 ref 参数中的属性值的类型。

如果参数类型 ref,则相应的参数可以 out 而不是 ref

如果方法接受可变数量的参数,则该方法可能适用于 普通形式扩展形式。 如果 A 中的参数数与方法接受的参数数相同,并且最后一个参数是数组,则窗体取决于两种可能的转换之一的排名:

  • 从 A 中最后一个参数的类型到最后一个参数的数组类型的转换的排名。
  • 从 A 中最后一个参数的类型到最后一个参数的数组类型的元素类型的转换排名。

如果第一个转换(到数组类型)优于第二个转换(到数组的元素类型),则该方法以普通形式适用,否则它适用于扩展形式。

如果参数多于参数,则该方法可能仅适用于扩展形式。 若要以扩展形式适用,最后一个参数必须具有数组类型。 该方法被替换为等效的方法,该方法最后一个参数替换为足够的参数,以考虑 A 中的每个不匹配参数。每个附加参数类型都是原始方法中最后一个参数的数组类型的元素类型。 适用于适用方法的上述规则将应用于此新方法和参数列表 A。

3.7.4 更好的方法

给定一个参数列表 A,其中包含一组参数表达式 { E~1~, E~2~, ..., E~N~ },以及参数类型 { P~1~, P~2~, ..., P~N~ }{ Q~1~, Q~2~, ..., Q~N~ } 的两个应用方法 M~P~M~Q~,如果 M~P~转换累积排名优于 M~Q~,则 M~P~ 被定义为比 M~Q~ 更好的方法。

转换结果的累积排序按如下方式计算。 每个转换根据参数的数量而价值不同,其中 E~1~ 的价值为 N,E~2~ 为 N-1,而 E~N~ 为 1。 如果从 E~X~P~X~ 的转换优于从 E~X~Q~X~,则 M~P~ 累积 N-X+1;否则,M~Q~ 累积 N-X+1。 如果 M~P~M~Q~ 具有相同的值,则按照顺序应用以下决胜规则:

  • 参数类型(忽略自变量类型)之间的累积转换排名与上一个排名类似,因此 P~1~Q~1~进行比较,P~2~Q~2~进行比较,...,P~N~Q~N~进行比较。 如果参数 $null,或者参数类型不是数值类型,则会跳过比较。 如果参数转换 E~X~ 转换为 P~X~ 时丢失信息,但在转换为 Q~X~时不会丢失信息,则也会跳过比较,反之亦然。 如果比较参数转换类型,则如果从 P~X~Q~X~ 的转换优于从 Q~X~P~X~,则 M~P~ 会累积 N-X+1;否则,M~Q~ 累积 N-X+1。 此决策规则旨在在转换不会导致信息丢失的情况下首选 最具体的方法(即参数具有最小数据类型的方法),或者在转换导致信息丢失时,首选 最通用的方法(即参数具有最大数据类型的方法)。
  • 如果两种方法都使用其扩展形式,则具有更多参数的方法是更好的方法。
  • 如果一种方法使用扩展窗体,另一种方法使用普通窗体,则使用普通窗体的方法是更好的方法。

3.7.5 更好的转换

下面标记为这样的文本是特定于 Windows PowerShell 的。

转换按以下方式进行排名,从最低到最高:

  • T~1~[]T~2~[],其中 T~1~T~2~ 之间不存在可分配的转换
  • 将 T 转换为字符串,其中 T 是任意类型
  • T~1~T~2~,其中 T~1~T~2~ 以实现定义的方式定义自定义转换
  • T~1~T~2~,其中 T~1~ 实现 IConvertible
  • T~1~T~2~,其中 T~1~T~2~ 实现了方法 T~2~ op_Implicit(T1)
  • T~1~T~2~,其中T~1~T~2~实现了方法T~2~ op_Explicit(T1)
  • T~1~T~2~,其中 T~2~ 实现一个接受类型 T~1~ 的单个参数的构造函数
  • 以下任一转换:
    • 字符串到 T,其中 T 实现静态方法 T Parse(string)T Parse(string, IFormatProvider)
    • T~1~T~2~ 其中 T~2~ 是任何枚举,T~1~ 是字符串或可转换为字符串的对象集合
  • T 到 PSObject,其中 T 为任何类型
  • 下列任何一种转换:Language
    • T 到 bool,其中 T 是任何数字类型
    • 将字符串转换为 T,其中 Tregexwmisearcherwmiwmiclassadsiadsisearchertype
    • Tbool
    • T~1~ 到 Nullable[T~2~],其中存在从 T~1~T~2~ 的转换
    • T 到 void
    • T~1~[]T~2~[],其中 T~1~T~2~ 之间存在可分配的转换
    • T~1~T~2~[] 其中 T~1~ 是一个集合
    • IDictionaryHashtable
    • Tref
    • Txml
    • scriptblockdelegate
    • T~1~T~2~ 其中 T~1~ 为整数类型,T~2~ 为枚举
  • $nullT,其中 T 是任何值类型
  • $nullT,其中 T 是任何引用类型
  • 下列任何一种转换:
    • 字节到 T,其中 TSByte

    • UInt16T,其中 TSBytebyteInt16

    • Int16T,其中 TSBytebyte

    • UInt32T,其中TSBytebyteInt16UInt16int

    • intT,其中 TSBytebyteInt16UInt16

    • UInt64T,其中 TSBytebyteInt16UInt16intUInt32long

    • longT 其中 TSBytebyteInt16UInt16intUInt32

    • floatT 其中 T 是任何整数类型或 decimal

    • doubleT,其中 T 是任何整数类型或 decimal

    • decimalT 其中 T 是任何整数类型

  • 下列任何一种转换:
    • SByteT,其中 Tbyteuint6UInt32UInt64
    • Int16T,其中TUInt16UInt32UInt64
    • intT,其中 TUInt32UInt64
    • longUInt64
    • decimalT,其中 Tfloatdouble
  • 下列任何一种转换:
    • Tstring,其中 T 是任何数值类型
    • Tchar,其中 T 是任何数值类型
    • stringT,其中 T 是任何数值类型
  • 以下任一转换,这些转换被视为可分配的转换:
    • byteT 的范围内,当 TInt16UInt16intUInt32longUInt64singledoubledecimal
    • SByteT,其中 TInt16UInt16intUInt32longUInt64singledoubledecimal
    • UInt16T,其中 TintUInt32longUInt64singledoubledecimal
    • Int16T,其中T可能是intUInt32longUInt64,也可能是singledoubledecimal
    • UInt32T,其中 TlongUInt64singledoubledecimal
    • intT,其中 TlongUInt64singledoubledecimal
    • singledouble
  • T~1~T~2~ 其中 T~2~T~1~的基类或接口。 此转换被视为可分配的转换。
  • stringchar[]
  • TT - 此转换被视为可分配的转换。

对于 T~1~T~2~[] 的每一个类型转换,其中 T~1~ 不是数组且没有其他转换可用的情况下,如果存在从 T~1~T~2~ 的转换,则该转换的排名低于从 T~1~T~2~ 的转换,但优于排名低于从 T~1~T~2~ 的转换

3.8 名称查找

可以让不同类型的命令具有相同的名称。 在这种情况下执行名称查找的顺序是别名、函数、cmdlet 和外部命令。

3.9 类型名称查找

§7.1.10 包含以下语句:“类型字面量在实现中由某个未指定的基础类型表示。 因此,类型名称是其基础类型的同义词。类型的示例包括 intdoublelong[]Hashtable

类型名称的匹配方式如下:将给定的类型名称与内置类型加速器列表进行比较,例如 int、long、double。 如果找到匹配项,则为类型。 否则,假定类型名称是完全限定的,并查看主机系统上是否存在此类类型。 如果找到匹配项,则为类型。 否则,添加命名空间前缀 System.。 如果找到匹配项,则为类型。 否则,类型名称出错。 此算法适用于泛型类型的每种类型参数。 但是,无需指定 Arity(即函数或运算符的参数或操作数的数量)。

3.10 自动内存管理

各种运算符和 cmdlet 会导致为引用类型对象(如字符串和数组)分配内存。 此内存的分配和释放由 PowerShell 运行时系统管理。 也就是说,PowerShell 提供自动垃圾回收

3.11 执行顺序

副作用是命令执行环境状态的变化。 变量值的更改(通过赋值运算符或前后递增和递减运算符)是一种副作用,对文件内容所做的更改也是一种副作用。

除非另有指定,否则语句按词法顺序执行。

除为某些运算符指定外,表达式中字词的计算顺序和副作用的发生顺序均未指定。

调用命令的表达式涉及指定命令的表达式,以及指定要传递给该命令的值的参数的零个或多个表达式。 未指定这些表达式相互之间的计算顺序。

3.12 错误处理

命令失败时,这被视为 错误,有关该错误的信息记录在 错误记录中,其类型未指定(§4.5.15),但是,该类型可以使用下标。

错误分为两类之一。 要么终止操作(终止错误),要么不会(非终止错误)。 发生终止错误时,将记录该错误并停止操作。 发生非终止错误时,将记录该错误,并继续操作。

非终止性错误被写入错误流。 尽管该信息可以重定向到文件,但错误对象首先转换为字符串,并且不会捕获这些对象中的重要信息,因此如果不是不可能,则无法进行诊断。 相反,可以重定向错误文本(§7.12)和错误对象保存在变量中,如在 $Error1 = command 2>&1中一样。

自动变量 $Error 包含表示最近错误的错误记录的集合,最近的错误位于 $Error[0]中。 此集合保留在缓冲区中,以便旧记录在添加新记录时被丢弃。 自动变量 $MaximumErrorCount 控制可存储的记录数。

$Error 包含来自所有命令的错误,这些错误被混合在一起形成一个集合。 若要从特定命令收集错误,请使用公共参数 errorVariable,该参数允许指定用户定义变量来保存错误集合。

3.13 管道

管道是一系列一个或多个命令,每个命令由管道运算符 | (U+007C) 分隔。 每个命令接收其前置任务的输入,并将输出写入其后续命令。 除非管道末尾的输出被丢弃或重定向到文件,否则会将其发送到主机环境,该环境可以选择将其写入标准输出。 管道中的命令也可能从参数接收输入。 例如,请考虑使用以下命令 Get-ChildItemSort-ObjectProcess-File,这些命令在给定文件系统目录中创建文件名列表,对一组文本记录进行排序,并分别对文本记录执行一些处理:

Get-ChildItem
Get-ChildItem e:*.txt | Sort-Object -CaseSensitive | Process-File >results.txt

在第一种情况下,Get-ChildItem 在当前/默认目录中创建文件的名称集合。 该集合将发送到主机环境,默认情况下,将每个元素的值写入标准输出。

第二种情况下,Get-ChildItem 使用参数 e:*.txt在指定的目录中创建文件的名称集合。 该集合被写入命令 Sort-Object,默认情况下按升序排序,并区分大小写(通过 CaseSensitive 参数)。 然后将生成的集合写入命令 Process-File,该命令执行一些(未知)处理。 然后,该命令的输出将重定向到文件 results.txt

如果一个命令写入单个对象,则其后续命令会接收该对象,然后在将其自己的对象写入其后续命令后终止。 但是,如果命令写入多个对象,则会一次将一个对象传递到后续命令,该命令每个对象执行一次。 此行为称为流式处理。 在流处理中,对象一旦可用,便立即写入管道,而不是等到整个集合生成后才写入。

处理集合时,可以编写命令,以便它可以在初始元素和最终元素之后执行特殊处理。

3.14 模块

模块 是一个自包含的可重用单元,允许对 PowerShell 代码进行分区、组织和抽象。 模块可以包含命令(如 cmdlet 和函数)以及可用作单个单元的项(如变量和别名)。

创建模块后,必须将其导入会话中,然后才能使用其中的命令和项。 导入后,命令和项的行为就像在本地定义一样。 使用 Import-Module 命令显式导入模块。 还可以按照定义的实现方式自动导入模块。

表示模块的对象的类型在 §4.5.12中介绍。

§11 中详细介绍了模块。

3.15 通配符表达式

通配符表达式可能包含以下元素中的零个或多个:

元素 描述
除 *、?或 [ 以外的字符 与这一个字符匹配
* 与零个或多个字符匹配。 若要匹配 * 字符,请使用 [*]。
? 匹配任意一个字符。 匹配一个? 字符,使用 [?]。
[]

匹配中的任何一个字符,该字符不能为空。

如果 以 ]开头,则右方括号被视为 的一部分,下一个右方括号将终止该集;否则,第一个右方括号将终止集。

如果以 - 开头或结尾,则连字符减号被视为的一部分。否则,它表示连续的 Unicode 码点范围,其中连字符减号两侧的字符为包含范围分隔符。 例如,A-Z 指示 26 个大写英文字母,0-9 表示十进制数字。

注意

有关详细信息,请参阅 开放组基础规范:模式匹配“,IEEE Std 1003.1, 2004 Edition。。 但是,在 PowerShell 中,转义字符为反引号,而不是反斜杠。

3.16 正则表达式

正则表达式可能包含以下元素中的零个或多个:

元素 描述
除 .、[、^、*、$或 \ 以外的字符 与这一个字符匹配
. 匹配任意一个字符。 匹配一个 . 字符,使用 \..
[]
[^]

[] 格式匹配中的任何一个字符。 [^] 不匹配中的任何字符。 不能为空。

如果 以 ] 或 ^] 开头,则此右方括号视为 的一部分,随后的右方括号将终止该集,否则,第一个右方括号将直接终止该集。

如果 集合 以 - 或 ^- 开头,或以 - 结尾,则该连字符减号属于 集合的一部分;否则,它表示一段连续的 Unicode 码点范围,其中连字符两侧的字符为包含性的范围分隔符。 例如,A-Z 指示 26 个大写英文字母,0-9 表示十进制数字。

* 匹配前一个元素的零次或多次出现。
+ 匹配前一个元素的多次出现之一。
? 匹配前一个元素的零次出现。
^ 与字符串的开头匹配。 若要匹配 ^ 字符,请使用 \^。
$ 与字符串的结尾匹配。 若要匹配 $ 字符,请使用 $。
\c 对字符 c 进行转义,因此它不会被识别为正则表达式元素。

Windows PowerShell:支持 Microsoft .NET Framework 正则表达式中提供的字符类,如下所示:

元素 描述
\p{name} 匹配由名称指定的命名字符类中的任何字符。 支持的名称包括 Unicode 字符类别和块范围,例如 Ll、Nd、Z、IsGreek 和 IsBoxDrawing。
\P{name} 匹配未包含在名称中指定的组和块范围中的文本。
\w 与任何单词字符匹配。 等效于 Unicode 字符类别 [\p{Ll}\p{Lu}\p{Lt}\p{Lo}\p{Nd}\p{Pc}]。 如果使用 ECMAScript 选项指定符合 ECMAScript 的行为,则 \w 等效于 [a-zA-Z_0-9]
\W 与任何非单词字符匹配。 等效于 Unicode 类别 [\^\p{Ll}\p{Lu}\p{Lt}\p{Lo}\p{Nd}\p{Pc}]
\s 与任何空白字符匹配。 等效于 Unicode 字符类别 [\f\n\r\t\v\x85\p{Z}]
\S 与任何非空白字符匹配。 等效于 Unicode 字符类别 [\^\f\n\r\t\v\x85\p{Z}]
\d 与任何十进制数字匹配。 等效于 Unicode 行为的 \p{Nd} 和非 Unicode 行为的 [0-9]
\D 匹配任何非数字。 等效于 Unicode 行为的 \P{Nd} 和非 Unicode 行为的 [\^0-9]

支持 Microsoft .NET Framework 正则表达式中提供的限定符,如下所示:

元素 描述
* 指定零个或多个匹配项;例如,\w* (abc)*. 等效于 {0,}
+ 匹配上述字符的重复实例。
? 指定零个或一个匹配项;例如,\w?(abc)?。 等效于 {0,1}
{n} 指定恰好 n 个匹配项;例如,(pizza){2}
{n,} 指定至少 n 个匹配项;例如,(abc){2,}
{n,m} 指定至少 n 个但不多于 m 个匹配项。