about_Automatic_Variables

简短说明

描述存储 PowerShell 状态信息的变量。 这些变量由 PowerShell 创建和维护。

长说明

从概念上讲,这些变量被视为只读的。 即使 可以 写入它们,但为了向后兼容, 不应 将其写入。

下面是 PowerShell 中自动变量的列表:

$$

包含会话收到的最后一行中的最后一个令牌。

$?

包含最后一个命令的执行状态。 如果最后一个命令成功,则包含 True ;如果失败,则为 False

对于在管道中的多个阶段运行的 cmdlet 和高级函数,例如,在两processend个阶段和块中,调用this.WriteError()$PSCmdlet.WriteError()分别在任何点将设置为 $?False,如下所示this.ThrowTerminatingError()$PSCmdlet.ThrowTerminatingError()

Write-Error cmdlet 在 $? 执行该 cmdlet 后会立即设置为 False ,但对于调用它的函数,该 cmdlet 不会设置为 $?False

function Test-WriteError
{
    Write-Error "Bad"
    $? # $false
}

Test-WriteError
$? # $true

出于后者的目的, $PSCmdlet.WriteError() 应改用。

对于本机命令 (可执行文件) ,$?设置为 True(如果$LASTEXITCODE为 0),当为任何其他值时$LASTEXITCODE设置为 False

注意

在 PowerShell 7 之前,在括号 (...)中包含语句,子表达式语法 $(...) 或数组表达式 @(...) 始终重置 $?True,以便显示为 (Write-Error)$?True。 PowerShell 7 中已更改此项,因此 $? 始终反映这些表达式中最后一个命令运行的实际成功。

$^

包含会话收到的最后一行中的第一个令牌。

$_

$PSItem 相同。 包含管道对象中的当前对象。 可以在对每个对象或管道中的选定对象执行操作的命令中使用此变量。

$args

包含传递给函数、脚本或脚本块的未声明参数的值数组。 创建函数时,可以使用关键字或在函数名称后面添加以逗号分隔的参数列表来声明参数 param

在事件操作中 $args ,变量包含表示正在处理的事件的事件参数的对象。 此变量仅在事件注册命令块内 Action 填充。 也可以在返回的 PSEventArgs 对象的 Get-EventSourceArgs 属性中找到此变量的值。

$ConsoleFileName

包含会话中最近使用的控制台文件 .psc1 () 的路径。 当使用 PSConsoleFile 参数启动 PowerShell 或使用该 Export-Console cmdlet 将管理单元名称导出到控制台文件时,将填充此变量。

在没有参数的情况下使用 Export-Console cmdlet 时,它会自动更新会话中最近使用的控制台文件。 可以使用此自动变量来确定将更新哪个文件。

$Error

包含表示最新错误的错误对象的数组。 最近的错误是数组 $Error[0]中的第一个错误对象。

若要防止将错误添加到 $Error 数组,请使用 ErrorAction 通用参数和 值 Ignore 值。 有关详细信息,请参阅 about_CommonParameters

$ErrorView

包含控制显示错误的视图的值。 该 $ErrorView 变量接受字符串或 ErrorView 对象,其默认值为 ConciseView. 如果定义了非接受值的字符串,则会引发错误。

接受的值:

  • CategoryView - 仅显示错误类别信息。
  • ConciseView - 仅显示错误消息。 如果错误是分析器错误或来自脚本,则包含位置指针。 此视图已在 PowerShell 7.0 中添加
  • NormalView - 提供包含错误消息、位置、类别信息等的标准 PowerShell 错误视图。

$Event

包含一个 PSEventArgs 对象,该对象表示正在处理的事件。 此变量仅在 Action 事件注册命令块内填充,例如 Register-ObjectEvent。 此变量的值与 cmdlet 返回的对象 Get-Event 相同。 因此,可以在脚本块中使用变量的属性Event,例如$Event.TimeGeneratedAction

$EventArgs

包含一个对象,该对象表示从正在处理的事件的 EventArgs 派生的第一个事件参数。 此变量仅在事件注册命令块内 Action 填充。 也可以在返回的 PSEventArgs 对象的Get-EventSourceEventArgs 属性中找到此变量的值。

$EventSubscriber

包含一个 PSEventSubscriber 对象,该对象表示正在处理的事件的事件订阅者。 此变量仅在事件注册命令块内 Action 填充。 此变量的值与 cmdlet 返回的对象 Get-EventSubscriber 相同。

$ExecutionContext

包含一个 EngineIntrinsics 对象,该对象表示 PowerShell 主机的执行上下文。 可以使用此变量查找可用于 cmdlet 的执行对象。

$false

包含 False。 可以使用此变量在命令和脚本中表示 False ,而不是使用字符串“false”。 如果字符串转换为非空字符串或非零整数,则可以将其解释为 True

$foreach

包含枚举器 (不是 ForEach 循环) 生成的值。 该 $ForEach 变量仅在循环正在运行时 ForEach 存在;该变量在完成循环后被删除。

枚举器包含可用于检索循环值和更改当前循环迭代的属性和方法。 有关详细信息,请参阅 使用枚举器

$HOME

包含用户主目录的完整路径。 此变量通常C:\Users\<UserName>相当于 "$env:homedrive$env:homepath" Windows 环境变量。

$Host

包含一个对象,该对象表示 PowerShell 的当前主机应用程序。 可以使用此变量在命令中表示当前主机,或者显示或更改主机的属性,例如$Host.version$Host.CurrentCulture或。$host.ui.rawui.setbackgroundcolor("Red")

$input

包含一个枚举器,该枚举器枚举传递给函数的所有输入。 该 $input 变量仅适用于) 未命名函数 (函数和脚本块。

  • 在不包含 、BeginProcessEnd块的函数中,$input变量枚举函数的所有输入的集合。

  • 在块中 Begin$input 变量不包含任何数据。

  • 在块中Process$input,变量包含当前位于管道中的对象。

  • 在块中 End$input 变量枚举函数的所有输入的集合。

    注意

    不能在同 $input 一函数或脚本块中使用 Process 块和 End 块内的变量。

由于 $input 是枚举器,因此访问其任何属性会导致 $input 不再可用。 可以存储在 $input 另一个变量中以重用 $input 属性。

枚举器包含可用于检索循环值和更改当前循环迭代的属性和方法。 有关详细信息,请参阅 使用枚举器

$input变量还可用于从命令行调用时由参数pwsh指定的-Command命令。 以下示例从 Windows 命令 shell 运行。

echo Hello | pwsh -Command """$input World!"""

$IsCoreCLR

包含 $True 当前会话是否在 .NET Core 运行时 (CoreCLR) 上运行。 否则包含 $False

$IsLinux

包含 $True 当前会话是否在 Linux 操作系统上运行。 否则包含 $False

$IsMacOS

包含 $True 当前会话是否在 MacOS 操作系统上运行。 否则包含 $False

$IsWindows

包含 $TRUE 当前会话是否在 Windows 操作系统上运行。 否则包含 $FALSE

$LastExitCode

包含运行的最后一个本机程序的退出代码。

$Matches

$Matches 变量适用于 -match 运算符和 -notmatch 运算符。 向或-notmatch运算符提交标量输入-match时,两者都检测到匹配项,返回布尔值,并使用匹配的任何字符串值的哈希表填充$Matches自动变量。 $Matches在运算符中使用正则表达式-match时,还可以使用捕获填充哈希表。

有关运算符的详细信息 -match ,请参阅 about_Comparison_Operators。 有关正则表达式的详细信息,请参阅 about_Regular_Expressions

$Matches 变量也适用于 switch 具有参数的 -Regex 语句。 它填充的方式与 -match 运算符相同 -notmatch 。 有关语句的详细信息 switch ,请参阅 about_Switch

注意

在会话中填充时 $Matches ,它会保留匹配的值,直到被另一个匹配项覆盖。 如果 -match 再次使用且未找到匹配项,则不会重置 $Matches$null。 在找到另一个匹配项之前,将保留 $Matches 以前匹配的值。

$MyInvocation

包含有关当前命令的信息,例如名称、参数、参数值,以及有关如何启动、调用或调用命令的信息,例如调用当前命令的脚本的名称。

$MyInvocation 仅针对脚本、函数和脚本块填充。 可以使用 System.Management.Automation.InvocationInfo 对象 $MyInvocation 中返回的信息,例如脚本的路径和文件名 () $MyInvocation.MyCommand.Path 或函数的名称 ($MyInvocation.MyCommand.Name) 标识当前命令。 这对于查找当前脚本的名称特别有用。

从 PowerShell 3.0 开始, MyInvocation 具有以下新属性。

  • PSScriptRoot - 包含调用当前命令的脚本的完整路径。 仅当调用方是脚本时,才会填充此属性的值。
  • PSCommandPath - 包含调用当前命令的脚本的完整路径和文件名。 仅当调用方是脚本时,才会填充此属性的值。

与自动变量不同,自动变量的 $MyInvocationPSScriptRootPSCommandPath 属性包含有关调用程序或调用脚本的信息,而不是当前脚本。$PSScriptRoot$PSCommandPath

$NestedPromptLevel

包含当前提示级别。 值为 0 表示原始提示级别。 当输入嵌套级别并在退出时递减时,该值将递增。

例如,使用该方法时 $Host.EnterNestedPrompt ,PowerShell 会提供嵌套的命令提示符。 在 PowerShell 调试器中到达断点时,PowerShell 还会显示嵌套的命令提示符。

输入嵌套提示时,PowerShell 会暂停当前命令,保存执行上下文,并递增变量的值 $NestedPromptLevel 。 若要创建其他嵌套命令提示符, (最多 128 个级别) 或返回到原始命令提示符,请完成命令或键入 exit

$NestedPromptLevel 变量可帮助你跟踪提示级别。 可以创建包含此值的备用 PowerShell 命令提示符,使其始终可见。

$null

$null 是一个包含 null 或空值的自动变量。 可以使用此变量在命令和脚本中表示缺失值或未定义值。

PowerShell 将 $null 值视为具有值的对象,即显式占位符,因此可用于 $null 表示一系列值中的空值。

例如,当包含在集合中时 $null ,它被计为其中一个对象。

$a = "one", $null, "three"
$a.count
3

如果将变量通过管道 $null 传递给 ForEach-Object cmdlet,它将生成一个值 $null,就像对其他对象所做的那样

"one", $null, "three" | ForEach-Object { "Hello " + $_}
Hello one
Hello
Hello three

因此,不能用于 $null 表示 无参数值。 参数 $null 值替代默认参数值。

但是,由于 PowerShell 将 $null 变量视为占位符,因此可以在脚本(如以下脚本)中使用该变量,如果 $null 被忽略,则不起作用。

$calendar = @($null, $null, "Meeting", $null, $null, "Team Lunch", $null)
$days = "Sunday","Monday","Tuesday","Wednesday","Thursday",
        "Friday","Saturday"
$currentDay = 0
foreach($day in $calendar)
{
    if($day -ne $null)
    {
        "Appointment on $($days[$currentDay]): $day"
    }

    $currentDay++
}
Appointment on Tuesday: Meeting
Appointment on Friday: Team lunch

$PID

包含托管当前 PowerShell 会话的进程 (PID) 的进程标识符。

$PROFILE

包含当前用户和当前主机应用程序 PowerShell 配置文件的完整路径。 可以使用此变量在命令中表示配置文件。 例如,可以在命令中使用它来确定是否已创建配置文件:

Test-Path $PROFILE

或者,可以在命令中使用它来创建配置文件:

New-Item -ItemType file -Path $PROFILE -Force

可以在命令中使用它打开 notepad.exe中的配置文件:

notepad.exe $PROFILE

$PSBoundParameters

包含传递给脚本或函数的参数及其当前值的字典。 此变量仅在声明参数的范围(如脚本或函数)中具有值。 可以使用它来显示或更改参数的当前值,或者将参数值传递给另一个脚本或函数。

在此示例中, Test2 函数将传递给 $PSBoundParametersTest1 函数。 以$PSBoundParameters的格式显示。

function Test1 {
   param($a, $b)

   # Display the parameters in dictionary format.
   $PSBoundParameters
}

function Test2 {
   param($a, $b)

   # Run the Test1 function with $a and $b.
   Test1 @PSBoundParameters
}
Test2 -a Power -b Shell
Key   Value
---   -----
a     Power
b     Shell

$PSCmdlet

包含表示正在运行的 cmdlet 或高级函数的对象。

可以使用 cmdlet 或函数代码中对象的属性和方法来响应使用条件。 例如, ParameterSetName 属性包含正在使用的参数集的名称, ShouldProcess 方法将 WhatIfConfirm 参数动态添加到 cmdlet。

有关自动变量的详细信息 $PSCmdlet ,请参阅 about_Functions_CmdletBindingAttributeabout_Functions_Advanced

$PSCommandPath

包含正在运行的脚本的完整路径和文件名。 此变量在所有脚本中都有效。

$PSCulture

从 PowerShell 7 开始, $PSCulture 反映当前 PowerShell runspace (会话) 区域性。 如果在 PowerShell Runspace 中更改了区域性,则会 $PSCulture 更新该 Runspace 的值。

区域性确定项目(如数字、货币和日期)的显示格式,并存储在 System.Globalization.CultureInfo 对象中。 用于 Get-Culture 显示计算机的区域性。 $PSCulture 包含 Name 属性值。

$PSDebugContext

调试时,此变量包含有关调试环境的信息。 否则,它包含 null 值。 因此,可以使用它来指示调试器是否具有控制权。 填充后,它包含具有断点InvocationInfo 属性的 PsDebugContext 对象。 InvocationInfo 属性具有多个有用的属性,包括 Location 属性。 Location 属性指示正在调试的脚本的路径。

$PSHOME

包含 PowerShell 安装目录的完整路径,通常是 $env:windir\System32\PowerShell\v1.0 在 Windows 系统中。 可以在 PowerShell 文件的路径中使用此变量。 例如,以下命令在概念帮助主题中搜索单词 变量

Select-String -Pattern Variable -Path $pshome\*.txt

$PSItem

$_ 相同。 包含管道对象中的当前对象。 可以在对每个对象或管道中的选定对象执行操作的命令中使用此变量。

$PSScriptRoot

包含执行脚本的父目录的完整路径。

在 PowerShell 2.0 中,此变量仅在脚本模块中有效, (.psm1) 。 从 PowerShell 3.0 开始,它在所有脚本中都有效。

$PSSenderInfo

包含有关启动 PSSession 的用户的信息,包括用户标识和发起计算机的时区。 此变量仅在 PSSessions 中可用。

$PSSenderInfo 变量包含用户可配置的属性 ApplicationArguments,默认情况下仅 $PSVersionTable 包含来自原始会话的属性。 若要将数据添加到 ApplicationArguments 属性,请使用 cmdlet 的 New-PSSessionOptionApplicationArguments 参数。

$PSUICulture

包含当前在操作系统中使用的用户界面 (UI) 区域性的名称。 UI 区域性确定哪些文本字符串用于用户界面元素,例如菜单和消息。 这是 System.Globalization.CultureInfo 的值。Current系统 UICulture.Name 属性。 若要获取系统的 System.Globalization.CultureInfo 对象,请使用 Get-UICulture cmdlet。

$PSVersionTable

包含一个只读哈希表,该表显示有关当前会话中运行的 PowerShell 版本的详细信息。 该表包含以下项:

  • PSVersion - PowerShell 版本号
  • PSEdition 此属性具有适用于 PowerShell 4 及更低版本以及功能齐全的 Windows 版本的 PowerShell 5.1 的值。 此属性具有在缩减版本(如 Windows Nano Server 或 Windows IoT)上的 PowerShell 6 及更高版本以及 PowerShell PowerShell 5.1 的值 Core
  • GitCommitId - GitHub 中源文件的提交 ID,
  • OS - PowerShell 正在运行的操作系统的说明。
  • 平台 - 操作系统正在运行的平台。 Linux 和 macOS 上的值为 Unix。 请参见 $IsMacOs$IsLinux
  • PSCompatibleVersions - 与当前版本兼容的 PowerShell 版本
  • PSRemotingProtocolVersion - PowerShell 远程管理协议的版本。
  • SerializationVersion - 序列化方法的版本
  • WSManStackVersion - WS-Management堆栈的版本号

$PWD

包含一个路径对象,该对象表示当前 PowerShell 运行空间的当前目录位置的完整路径。

注意

PowerShell 支持每个进程的多个运行空间。 每个 Runspace 都有其自己的 当前目录。 这与进程的当前目录不同: [System.Environment]::CurrentDirectory

$Sender

包含生成此事件的对象。 此变量仅在事件注册命令的操作块内填充。 也可以在返回的 PSEventArgs 对象的 Get-Event Sender 属性中找到此变量的值。

$ShellId

包含当前 shell 的标识符。

$StackTrace

包含最新错误的堆栈跟踪。

$switch

包含枚举器,而不是语句的结果值 Switch 。 该 $switch 变量仅在语句正在运行时 Switch 存在;在 switch 语句完成执行时会将其删除。 有关详细信息,请参阅 about_Switch

枚举器包含可用于检索循环值和更改当前循环迭代的属性和方法。 有关详细信息,请参阅 使用枚举器

$this

$this 变量用于扩展类以引用类本身的实例的脚本块中。

使用 PowerShell 的可扩展类型系统 (ETS) ,可以使用脚本块将属性添加到类。 在定义脚本属性或脚本方法的脚本块中 $this ,变量引用正在扩展的类的实例。 例如,PowerShell 使用 ETS 将 BaseName 属性添加到 FileInfo 类。

PS> Get-ChildItem .\README.md | Get-Member BaseName | Format-List

TypeName   : System.IO.FileInfo
Name       : BaseName
MemberType : ScriptProperty
Definition : System.Object BaseName {get=if ($this.Extension.Length -gt 0){$this.Name.Remove($this.Name.Length -
             $this.Extension.Length)}else{$this.Name};}

有关详细信息,请参阅 about_Types.ps1xml

在 PowerShell 类中 $this ,变量引用类本身的实例对象,允许访问类中定义的属性和方法。 有关详细信息,请参阅 about_Classes

$this 变量还由将脚本块用作事件处理程序的委托的 .NET 事件类使用。 在此方案中, $this 表示发起事件的对象,称为事件发送方。

$true

包含 True。 可以使用此变量在命令和脚本中表示 True

使用枚举器

$foreach$switch$input变量都是用于循环访问其包含代码块处理的值的所有枚举器。

枚举器包含可用于推进或重置迭代或检索迭代值的属性和方法。 直接操作枚举器并不被视为最佳做法。

MoveNext

MoveNext 方法将枚举器推进到集合的下一个元素。 如果枚举器已成功高级, False则 MoveNext 返回True该枚举器是否已传递集合末尾。

注意

MoveNext 返回的布尔值将发送到输出流。 可以通过键入输出或将其管道传递给 [void]Out-Null 来禁止输出。

$input.MoveNext() | Out-Null
[void]$input.MoveNext()

Reset

该方法 Reset 将枚举器设置为其初始位置,该位置位于集合中的第一个元素 之前

Current

Current 属性获取集合或管道中的元素,该元素位于枚举器的当前位置。

在调用 MoveNext 之前,该Current属性将继续返回相同的属性。

示例

示例 1:使用 $input 变量

在下面的示例中,访问 $input 变量将清除变量,直到下一次执行进程块为止。 Reset使用该方法将$input变量重置为当前管道值。

function Test
{
    begin
    {
        $i = 0
    }

    process
    {
        "Iteration: $i"
        $i++
        "`tInput: $input"
        "`tAccess Again: $input"
        $input.Reset()
        "`tAfter Reset: $input"
    }
}

"one","two" | Test
Iteration: 0
    Input: one
    Access Again:
    After Reset: one
Iteration: 1
    Input: two
    Access Again:
    After Reset: two

即使无法访问该变量, $input 进程块也会自动推进该变量。

$skip = $true
function Skip
{
    begin
    {
        $i = 0
    }

    process
    {
        "Iteration: $i"
        $i++
        if ($skip)
        {
            "`tSkipping"
            $skip = $false
        }
        else
        {
            "`tInput: $input"
        }
    }
}

"one","two" | Skip
Iteration: 0
    Skipping
Iteration: 1
    Input: two

示例 2:在进程块外部使用$input

在进程块之外, $input 变量表示通过管道传递到函数的所有值。

  • 访问 $input 变量会清除所有值。
  • 该方法 Reset 重置整个集合。
  • Current 不填充该属性。
  • MoveNext 方法返回 false,因为集合不能是高级的。
    • 调用 MoveNext$input 清除变量。
Function All
{
    "All Values: $input"
    "Access Again: $input"
    $input.Reset()
    "After Reset: $input"
    $input.MoveNext() | Out-Null
    "After MoveNext: $input"
}

"one","two","three" | All
All Values: one two three
Access Again:
After Reset: one two three
After MoveNext:

示例 3:使用$input。Current 财产

通过使用 Current 属性,可以在不使用该方法的情况下 Reset 多次访问当前管道值。 进程块不会自动调用 MoveNext 方法。

Current除非显式调用 MoveNext,否则永远不会填充该属性。 可以在进程块内多次访问该 Current 属性,而无需清除其值。

function Current
{
    begin
    {
        $i = 0
    }

    process
    {
        "Iteration: $i"
        $i++
        "`tBefore MoveNext: $($input.Current)"
        $input.MoveNext() | Out-Null
        "`tAfter MoveNext: $($input.Current)"
        "`tAccess Again: $($input.Current)"
    }
}

"one","two" | Current
Iteration: 0
    Before MoveNext:
    After MoveNext: one
    Access Again: one
Iteration: 1
    Before MoveNext:
    After MoveNext: two
    Access Again: two

示例 4:使用$foreach变量

$input 变量不同,当 $foreach 直接访问时,变量始终表示集合中的所有项。 Current使用属性访问当前集合元素,以及Reset用于更改其值的 MoveNext 方法。

注意

循环的每个 foreach 迭代都会自动调用 MoveNext 方法。

以下循环仅执行两次。 第二次迭代中,集合在迭代完成之前移动到第三个元素。 第二次迭代后,现在不再有循环访问的值,循环将终止。

MoveNext 属性不会影响选择循环访问集合 () $Num 的变量。

$i = 0
foreach ($num in ("one","two","three"))
{
    "Iteration: $i"
    $i++
    "`tNum: $num"
    "`tCurrent: $($foreach.Current)"

    if ($foreach.Current -eq "two")
    {
        "Before MoveNext (Current): $($foreach.Current)"
        $foreach.MoveNext() | Out-Null
        "After MoveNext (Current): $($foreach.Current)"
        "Num has not changed: $num"
    }
}
Iteration: 0
        Num: one
        Current: one
Iteration: 1
        Num: two
        Current: two
Before MoveNext (Current): two
After MoveNext (Current): three
Num has not changed: two

Reset使用该方法重置集合中的当前元素。 下面的示例循环访问前两 个元素, 因为 Reset 调用了该方法。 在前两个循环之后,语句 if 会失败,循环通常循环访问所有三个元素。

重要

这可能会导致无限循环。

$stopLoop = 0
foreach ($num in ("one","two", "three"))
{
    ("`t" * $stopLoop) + "Current: $($foreach.Current)"

    if ($num -eq "two" -and $stopLoop -lt 2)
    {
        $foreach.Reset() | Out-Null
        ("`t" * $stopLoop) + "Reset Loop: $stopLoop"
        $stopLoop++
    }
}
Current: one
Current: two
Reset Loop: 0
        Current: one
        Current: two
        Reset Loop: 1
                Current: one
                Current: two
                Current: three

示例 5:使用 $switch 变量

$switch 变量的规则与变量完全相同 $foreach 。 以下示例演示所有枚举器概念。

注意

请注意 NotEvaluated 事例永远不会执行,即使 MoveNext 方法之后没有break语句也是如此。

$values = "Start", "MoveNext", "NotEvaluated", "Reset", "End"
$stopInfinite = $false
switch ($values)
{
    "MoveNext" {
        "`tMoveNext"
        $switch.MoveNext() | Out-Null
        "`tAfter MoveNext: $($switch.Current)"
    }
    # This case is never evaluated.
    "NotEvaluated" {
        "`tAfterMoveNext: $($switch.Current)"
    }

    "Reset" {
        if (!$stopInfinite)
        {
            "`tReset"
            $switch.Reset()
            $stopInfinite = $true
        }
    }

    default {
        "Default (Current): $($switch.Current)"
    }
}
Default (Current): Start
    MoveNext
    After MoveNext: NotEvaluated
    Reset
Default (Current): Start
    MoveNext
    After MoveNext: NotEvaluated
Default (Current): End

请参阅