关于范围About Scopes

简短说明Short description

说明 PowerShell 中的作用域的概念,并演示如何设置和更改元素的作用域。Explains the concept of scope in PowerShell and shows how to set and change the scope of elements.

长说明Long description

PowerShell 通过限制可以读取和更改变量、别名、函数和 PowerShell 驱动器 (PSDrives) ,来保护这些驱动器的访问。PowerShell protects access to variables, aliases, functions, and PowerShell drives (PSDrives) by limiting where they can be read and changed. PowerShell 使用范围规则确保你不会无意中更改不应更改的项。PowerShell uses scope rules to ensure that you do not inadvertently change an item that should not be changed.

下面是范围的基本规则:The following are the basic rules of scope:

  • 范围可以嵌套。Scopes may nest. 外部作用域称为父作用域。An outer scope is referred to as a parent scope. 任何嵌套的作用域都是该父级的子作用域。Any nested scopes are child scopes of that parent.

  • 项目在创建它的作用域和任何子作用域中可见,除非你显式将其设为私有。An item is visible in the scope in which it was created and in any child scopes, unless you explicitly make it private. 可以在一个或多个作用域中放置变量、别名、函数或 PowerShell 驱动器。You can place variables, aliases, functions, or PowerShell drives in one or more scopes.

  • 在范围内创建的项只能在创建它的范围内更改,除非显式指定了不同的范围。An item that you created within a scope can be changed only in the scope in which it was created, unless you explicitly specify a different scope.

如果在作用域中创建一个项,并且该项与不同范围内的项共享其名称,则原始项可能会隐藏在新项下,但不会被覆盖或更改。If you create an item in a scope, and the item shares its name with an item in a different scope, the original item might be hidden under the new item, but it is not overridden or changed.

PowerShell 范围PowerShell Scopes

PowerShell 支持以下作用域:PowerShell supports the following scopes:

  • 全局: PowerShell 启动或创建新会话或运行空间时生效的作用域。Global: The scope that is in effect when PowerShell starts or when you create a new session or runspace. 在全局作用域(例如自动变量和首选项变量)中创建了 PowerShell 启动时出现的变量和函数。Variables and functions that are present when PowerShell starts have been created in the global scope, such as automatic variables and preference variables. PowerShell 配置文件中的变量、别名和函数也是在全局范围内创建的。The variables, aliases, and functions in your PowerShell profiles are also created in the global scope. 全局范围是会话中的根父范围。The global scope is the root parent scope in a session.

  • Local:当前范围。Local: The current scope. 本地作用域可以是全局作用域或任何其他作用域。The local scope can be the global scope or any other scope.

  • 脚本:运行脚本文件时创建的作用域。Script: The scope that is created while a script file runs. 只有脚本中的命令在脚本作用域中运行。Only the commands in the script run in the script scope. 对于脚本中的命令,脚本范围为本地范围。To the commands in a script, the script scope is the local scope.

备注

私有 不是范围。Private is not a scope. 它是一个 选项 ,它更改项的范围之外的项的可见性。It is an option that changes the visibility of an item outside of the scope where the item is defined.

父范围和子范围Parent and Child Scopes

可以通过调用脚本或函数来创建新的子作用域。You can create a new child scope by calling a script or function. 调用范围为父范围。The calling scope is the parent scope. 被调用的脚本或函数是子作用域。The called script or function is the child scope. 您调用的函数或脚本可以调用其他函数,从而创建子范围的层次结构,该层次结构的根作用域是全局作用域。The functions or scripts you call may call other functions, creating a hierarchy of child scopes whose root scope is the global scope.

除非显式将项设置为私有,否则父范围中的项可用于子范围。Unless you explicitly make the items private, the items in the parent scope are available to the child scope. 但是,在子范围内创建和更改的项不影响父范围,除非你在创建项时显式指定范围。However, items that you create and change in the child scope do not affect the parent scope, unless you explicitly specify the scope when you create the items.

备注

模块中的函数不在调用作用域的子范围中运行。Functions from a module do not run in a child scope of the calling scope. 模块具有其自己的会话状态,该状态链接到全局范围。Modules have their own session state that is linked to the global scope. 所有模块代码都在具有自身根作用域的特定于模块的范围层次结构中运行。All module code runs in a module-specific hierarchy of scopes that has its own root scope.

继承Inheritance

子作用域不从父作用域继承变量、别名和函数。A child scope does not inherit the variables, aliases, and functions from the parent scope. 除非项是私有的,否则子范围可以查看父范围中的项。Unless an item is private, the child scope can view the items in the parent scope. 并且,它可以通过显式指定父范围来更改项,但项不是子范围的一部分。And, it can change the items by explicitly specifying the parent scope, but the items are not part of the child scope.

但是,使用一组项创建子范围。However, a child scope is created with a set of items. 通常,它包括具有 AllScope 选项的所有别名。Typically, it includes all the aliases that have the AllScope option. 本文稍后将对此进行讨论。This option is discussed later in this article. 它包括具有 AllScope 选项的所有变量,以及一些自动变量。It includes all the variables that have the AllScope option, plus some automatic variables.

若要查找特定范围中的项,请使用或的作用域参数 Get-Variable Get-AliasTo find the items in a particular scope, use the Scope parameter of Get-Variable or Get-Alias.

例如,若要获取本地范围内的所有变量,请键入:For example, to get all the variables in the local scope, type:

Get-Variable -Scope local

若要获取全局范围内的所有变量,请键入:To get all the variables in the global scope, type:

Get-Variable -Scope global

作用域修饰符Scope Modifiers

变量、别名或函数名可以包含以下任意一种可选的作用域修饰符:A variable, alias, or function name can include any one of the following optional scope modifiers:

  • global: -指定名称存在于 全局 范围内。global: - Specifies that the name exists in the Global scope.

  • local: -指定名称存在于 本地 作用域中。local: - Specifies that the name exists in the Local scope. 当前范围始终是 本地 范围。The current scope is always the Local scope.

  • private: -指定该名称是 私有 的,仅对当前作用域可见。private: - Specifies that the name is Private and only visible to the current scope.

  • script: -指定名称存在于 脚本 作用域中。script: - Specifies that the name exists in the Script scope. 如果没有最近的上级脚本文件,则 脚本 范围是最近的上级脚本文件的范围或 全局Script scope is the nearest ancestor script file's scope or Global if there is no nearest ancestor script file.

  • using: -用于在通过 cmdlet (如和)运行脚本时访问在其他作用域中定义的变量 Start-Job Invoke-Commandusing: - Used to access variables defined in another scope while running scripts via cmdlets like Start-Job and Invoke-Command.

  • workflow: -指定名称存在于工作流中。workflow: - Specifies that the name exists within a workflow. 注意: PowerShell Core 不支持工作流。Note: Workflows are not supported in PowerShell Core.

  • <variable-namespace> -PowerShell New-psdrive 提供程序创建的修饰符。<variable-namespace> - A modifier created by a PowerShell PSDrive provider. 例如:For example:

    命名空间Namespace 说明Description
    Alias: 当前作用域中定义的别名Aliases defined in the current scope
    Env: 在当前作用域中定义的环境变量Environment variables defined in the current scope
    Function: 当前作用域中定义的函数Functions defined in the current scope
    Variable: 当前作用域中定义的变量Variables defined in the current scope

脚本的默认作用域为脚本范围。The default scope for scripts is the script scope. 函数和别名的默认作用域为本地作用域,即使它们是在脚本中定义的也是如此。The default scope for functions and aliases is the local scope, even if they are defined in a script.

使用作用域修饰符Using scope modifiers

若要指定新变量、别名或函数的作用域,请使用作用域修饰符。To specify the scope of a new variable, alias, or function, use a scope modifier.

变量中的作用域修饰符的语法为:The syntax for a scope modifier in a variable is:

$[<scope-modifier>:]<name> = <value>

函数中的作用域修饰符的语法为:The syntax for a scope modifier in a function is:

function [<scope-modifier>:]<name> {<function-body>}

以下不使用范围修饰符的命令将在当前或 本地 范围内创建变量:The following command, which does not use a scope modifier, creates a variable in the current or local scope:

$a = "one"

若要在 全局 作用域中创建相同的变量,请使用作用域 global: 修饰符:To create the same variable in the global scope, use the scope global: modifier:

$global:a = "one"

若要在 脚本 作用域中创建相同的变量,请使用 script: 作用域修饰符:To create the same variable in the script scope, use the script: scope modifier:

$script:a = "one"

还可以将作用域修饰符用于函数。You can also use a scope modifier with functions. 以下函数定义将在 全局 范围内创建函数:The following function definition creates a function in the global scope:

function global:Hello {
  Write-Host "Hello, World"
}

你还可以使用作用域修饰符来引用不同范围中的变量。You can also use scope modifiers to refer to a variable in a different scope. 以下命令 $test 首先引用本地作用域中的变量,然后在全局范围内引用:The following command refers to the $test variable, first in the local scope and then in the global scope:

$test
$global:test

Using:作用域修饰符The Using: scope modifier

使用是一个特殊的作用域修饰符,用来标识远程命令中的局部变量。Using is a special scope modifier that identifies a local variable in a remote command. 如果不使用修饰符,则 PowerShell 应在远程会话中定义远程命令中的变量。Without a modifier, PowerShell expects variables in remote commands to be defined in the remote session.

UsingPowerShell 3.0 中引入了作用域修饰符。The Using scope modifier is introduced in PowerShell 3.0.

对于任何执行进程外的脚本或命令,都需要 Using 范围修饰符来嵌入调用会话范围内的变量值,以便使会话代码不能访问它们。For any script or command that executes out of session, you need the Using scope modifier to embed variable values from the calling session scope, so that out of session code can access them. Using以下上下文支持作用域修饰符:The Using scope modifier is supported in the following contexts:

  • 远程执行的命令,已开始 Invoke-Command 使用 ComputerNameHostNameSSHConnectionSession 参数 (远程会话) Remotely executed commands, started with Invoke-Command using the ComputerName , HostName , SSHConnection or Session parameters (remote session)
  • 后台作业, Start-Job (进程外会话开始) Background jobs, started with Start-Job (out-of-process session)
  • 通过 Start-ThreadJobForEach-Object -Parallel (单独的线程会话启动的线程作业) Thread jobs, started via Start-ThreadJob or ForEach-Object -Parallel (separate thread session)

根据上下文,嵌入变量值是调用方的作用域中的数据的独立副本或对其的引用。Depending on the context, embedded variable values are either independent copies of the data in the caller's scope or references to it. 在远程和进程外会话中,它们始终是独立的副本。In remote and out-of-process sessions, they are always independent copies.

有关详细信息,请参阅 about_Remote_VariablesFor more information, see about_Remote_Variables.

在线程会话中,它们是通过引用传递的。In thread sessions, they are passed by reference. 这意味着可以在不同的线程中修改调用范围变量。This means it is possible to modify call scope variables in a different thread. 安全修改变量需要线程同步。To safely modify variables requires thread synchronization.

有关详细信息,请参阅:For more information see:

变量值的序列化Serialization of variable values

远程执行的命令和后台作业在进程外运行。Remotely executed commands and background jobs run out-of-process. 进程外会话使用基于 XML 的序列化和反序列化来使变量的值可在进程边界内使用。Out-of-process sessions use XML-based serialization and deserialization to make the values of variables available across the process boundaries. 序列化进程将对象转换为包含原始对象属性但不包含其方法的 PSObjectThe serialization process converts objects to a PSObject that contains the original objects properties but not its methods.

对于有限类型的类型,请将解除冻结对象反序列化为原始类型。For a limited set of types, deserialization rehydrates objects back to the original type. 解除冻结对象是原始对象实例的副本。The rehydrated object is a copy of the original object instance. 它具有类型属性和方法。It has the type properties and methods. 对于简单的类型(如 system.object ),副本是精确的。For simple types, such as System.Version , the copy is exact. 对于复杂类型,复制为完善。For complex types, the copy is imperfect. 例如,解除冻结证书对象不包含私钥。For example, rehydrated certificate objects do not include the private key.

所有其他类型的实例都是 PSObject 实例。Instances of all other types are PSObject instances. PSTypeNames 属性包含以 反序列化 的原始类型名称,例如 Deserialized.System。Data DataTableThe PSTypeNames property contains the original type name prefixed with Deserialized , for example, Deserialized.System.Data.DataTable

AllScope 选项The AllScope Option

变量和别名有一个 选项 属性,该属性的值为 AllScopeVariables and aliases have an Option property that can take a value of AllScope. 具有 AllScope 属性的项将成为你创建的任何子范围的一部分,尽管它们不会被父范围继承。Items that have the AllScope property become part of any child scopes that you create, although they are not retroactively inherited by parent scopes.

具有 AllScope 属性的项在子范围中是可见的,它是该范围的一部分。An item that has the AllScope property is visible in the child scope, and it is part of that scope. 对任何范围内的项所做的更改都会影响定义该变量的所有范围。Changes to the item in any scope affect all the scopes in which the variable is defined.

管理作用域Managing Scope

多个 cmdlet 具有 作用域 参数,可让你获取或设置 (创建和更改特定作用域中) 项的功能。Several cmdlets have a Scope parameter that lets you get or set (create and change) items in a particular scope. 使用以下命令查找会话中具有 作用域 参数的所有 cmdlet:Use the following command to find all the cmdlets in your session that have a Scope parameter:

Get-Help * -Parameter scope

若要查找在特定作用域中可见的变量,请使用的 Scope 参数 Get-VariableTo find the variables that are visible in a particular scope, use the Scope parameter of Get-Variable. 可见变量包括全局变量、父作用域中的变量以及当前作用域中的变量。The visible variables include global variables, variables in the parent scope, and variables in the current scope.

例如,以下命令将获取在本地作用域中可见的变量:For example, the following command gets the variables that are visible in the local scope:

Get-Variable -Scope local

若要在特定范围内创建变量,请使用的作用域修饰符或 作用域 参数 Set-VariableTo create a variable in a particular scope, use a scope modifier or the Scope parameter of Set-Variable. 以下命令在全局范围内创建变量:The following command creates a variable in the global scope:

New-Variable -Scope global -Name a -Value "One"

你还可以使用、或 cmdlet 的作用域参数 New-Alias Set-Alias Get-Alias 来指定作用域。You can also use the Scope parameter of the New-Alias, Set-Alias, or Get-Alias cmdlets to specify the scope. 以下命令在全局范围内创建一个别名:The following command creates an alias in the global scope:

New-Alias -Scope global -Name np -Value Notepad.exe

若要获取特定范围中的函数,请 Get-Item 在范围内使用 cmdlet。To get the functions in a particular scope, use the Get-Item cmdlet when you are in the scope. Get-ItemCmdlet 没有 Scope 参数。The Get-Item cmdlet does not have a Scope parameter.

备注

对于使用 Scope 参数的 cmdlet,还可以按编号引用范围。For the cmdlets that use the Scope parameter, you can also refer to scopes by number. 该数字描述一个作用域相对于另一个作用域的相对位置。The number describes the relative position of one scope to another. 范围0表示当前范围或本地范围。Scope 0 represents the current, or local, scope. 作用域1指示直接父作用域。Scope 1 indicates the immediate parent scope. 作用域2指示父作用域的父项,依此类推。Scope 2 indicates the parent of the parent scope, and so on. 如果已创建多个递归作用域,编号范围很有用。Numbered scopes are useful if you have created many recursive scopes.

在作用域中使用点源表示法Using Dot Source Notation with Scope

脚本和函数遵循作用域的所有规则。Scripts and functions follow all the rules of scope. 在特定的范围内创建它们,除非使用 cmdlet 参数或作用域修饰符来更改该作用域,否则它们只会影响该作用域。You create them in a particular scope, and they affect only that scope unless you use a cmdlet parameter or a scope modifier to change that scope.

但是,您可以使用点源表示法将脚本或函数添加到当前作用域。But, you can add a script or function to the current scope by using dot source notation. 然后,当脚本在当前作用域中运行时,该脚本创建的任何函数、别名和变量都在当前作用域中可用。Then, when a script runs in the current scope, any functions, aliases, and variables that the script creates are available in the current scope.

若要将函数添加到当前作用域,请在函数调用中键入一个句点 (. ) 和该函数的路径和名称之前的空格。To add a function to the current scope, type a dot (.) and a space before the path and name of the function in the function call.

例如,若要在脚本范围中的 C:\Scripts 目录中运行 Sample.ps1 脚本 (脚本) 的默认值,请使用以下命令:For example, to run the Sample.ps1 script from the C:\Scripts directory in the script scope (the default for scripts), use the following command:

c:\scripts\sample.ps1

若要在本地作用域中运行 Sample.ps1 脚本,请使用以下命令:To run the Sample.ps1 script in the local scope, use the following command:

. c:\scripts.sample.ps1

使用 call 运算符 ( # A0) 运行函数或脚本时,不会将其添加到当前作用域。When you use the call operator (&) to run a function or script, it is not added to the current scope. 下面的示例使用调用运算符:The following example uses the call operator:

& c:\scripts.sample.ps1

可以在 about_operators中详细了解 call 运算符。You can read more about the call operator in about_operators.

Sample.ps1 脚本创建的任何别名、函数或变量在当前作用域中都不可用。Any aliases, functions, or variables that the Sample.ps1 script creates are not available in the current scope.

不带作用域的限制Restricting Without Scope

一些 PowerShell 概念类似于作用域或与作用域交互。A few PowerShell concepts are similar to scope or interact with scope. 这些概念可能会与范围或范围的行为混淆。These concepts may be confused with scope or the behavior of scope.

会话、模块和嵌套的提示是独立的环境,但是它们不是会话中全局作用域的子作用域。Sessions, modules, and nested prompts are self-contained environments, but they are not child scopes of the global scope in the session.

会话Sessions

会话是 PowerShell 运行的环境。A session is an environment in which PowerShell runs. 在远程计算机上创建会话时,PowerShell 会建立与远程计算机的持久连接。When you create a session on a remote computer, PowerShell establishes a persistent connection to the remote computer. 使用持久性连接可以将会话用于多个相关命令。The persistent connection lets you use the session for multiple related commands.

由于会话是包含的环境,因此它具有其自己的作用域,但会话不是在其中创建它的会话的子作用域。Because a session is a contained environment, it has its own scope, but a session is not a child scope of the session in which it was created. 该会话从其自己的全局作用域开始。The session starts with its own global scope. 此作用域独立于会话的全局作用域。This scope is independent of the global scope of the session. 你可以在会话中创建子作用域。You can create child scopes in the session. 例如,你可以运行一个脚本以在会话中创建子作用域。For example, you can run a script to create a child scope in a session.

模块Modules

你可以使用 PowerShell 模块来共享和传递 PowerShell 工具。You can use a PowerShell module to share and deliver PowerShell tools. 模块是一个可包含 cmdlet、脚本、函数、变量、别名和其他有用项的单位。A module is a unit that can contain cmdlets, scripts, functions, variables, aliases, and other useful items. 除非显式定义,否则模块中的项在模块外部不可访问。Unless explicitly defined, the items in a module are not accessible outside the module. 因此,可以将该模块添加到会话中,并使用这些公共项,而不必担心其他项可能会覆盖会话中的 cmdlet、脚本、函数和其他项。Therefore, you can add the module to your session and use the public items without worrying that the other items might override the cmdlets, scripts, functions, and other items in your session.

默认情况下,模块将加载到当前 会话状态 的顶层,而不是当前 作用域By default, modules are loaded into the top-level of the current session state not the current scope. 当前会话状态可以是模块会话状态或全局会话状态。The current session state could be a module session state or the global session state. 向会话添加模块不会更改范围。Adding a module to a session does not change the scope. 如果在全局范围内,则将模块加载到全局会话状态。If you are in the global scope, then modules are loaded into the global session state. 所有导出都放置在全局表中。Any exports are placed into the global tables. 如果从 module1 加载 module2,则 module2 将加载到 module1 的会话状态,而不是全局会话状态。If you load module2 from within module1, module2 is loaded into the session state of module1 not the global session state. Module2 中的任何导出都置于 module1 会话状态的顶部。Any exports from module2 are placed at the top of the module1 session state. 如果使用 Import-Module -Scope local ,则会将导出置于当前范围对象而不是顶级。If you use Import-Module -Scope local, then the exports are placed into the current scope object rather than at the top level. 如果你 在模块中 ,并使用 Import-Module -Scope global (或 Import-Module -Global) 加载另一个模块,则该模块及其导出将加载到全局会话状态,而不是模块的本地会话状态。If you are in a module and use Import-Module -Scope global (or Import-Module -Global) to load another module, that module and it's exports are loaded into the global session state instead of the module's local session state. 此功能设计用于编写操作模块的模块。This feature was designed for writing module that manipulate modules. WindowsCompatibility 模块执行此将代理模块导入全局会话状态。The WindowsCompatibility module does this to import proxy modules into the global session state.

在会话状态中,模块具有其自己的作用域。Within the session state, modules have their own scope. 请考虑以下模块 C:\temp\mod1.psm1Consider the following module C:\temp\mod1.psm1:

$a = "Hello"

function foo {
    "`$a = $a"
    "`$global:a = $global:a"
}

现在,我们创建一个全局变量 $a ,为其指定一个值,并调用函数 fooNow we create a global variable $a, give it a value and call the function foo.

$a = "Goodbye"
foo

模块 $a 在模块范围内声明变量,而函数 foo 则在这两个作用域中输出该变量的值。The module declares the variable $a in the module scope then the function foo outputs the value of the variable in both scopes.

$a = Hello
$global:a = Goodbye

嵌套提示Nested Prompts

嵌套式提示不具有其自己的作用域。Nested prompts do not have their own scope. 当您输入嵌套提示符时,嵌套提示符将是环境的子集。When you enter a nested prompt, the nested prompt is a subset of the environment. 但仍在本地范围内。But, you remain within the local scope.

脚本具有自己的作用域。Scripts do have their own scope. 如果要调试脚本,并在脚本中找到断点,则输入脚本范围。If you are debugging a script, and you reach a breakpoint in the script, you enter the script scope.

Private 选项Private Option

别名和变量具有 选项 属性,该属性的值可以是 PrivateAliases and variables have an Option property that can take a value of Private. 具有 Private 选项的项可以在创建它们的范围内查看和更改,但无法在该范围外查看或更改它们。Items that have the Private option can be viewed and changed in the scope in which they are created, but they cannot be viewed or changed outside that scope.

例如,如果在全局作用域中创建一个具有 private 选项的变量,然后运行脚本,则 Get-Variable 该脚本中的命令不显示专用变量。For example, if you create a variable that has a private option in the global scope and then run a script, Get-Variable commands in the script do not display the private variable. 在此实例中使用全局作用域修饰符不显示私有变量。Using the global scope modifier in this instance does not display the private variable.

可以使用 New-Variable 、、和 cmdlet 的选项参数 Set-Variable New-Alias Set-Alias 将选项属性的值设置为私有。You can use the Option parameter of the New-Variable, Set-Variable, New-Alias, and Set-Alias cmdlets to set the value of the Option property to Private.

能见度Visibility

变量或别名的 " 可见性 " 属性决定了是否可以在创建容器的容器外查看项。The Visibility property of a variable or alias determines whether you can see the item outside the container, in which it was created. 容器可以是模块、脚本或管理单元。A container could be a module, script, or snap-in. 可见性适用于容器的设计方式与 选项 属性的 私有 值为作用域设计的方式相同。Visibility is designed for containers in the same way that the Private value of the Option property is designed for scopes.

Visibility 属性采用 公共 值和 私有 值。The Visibility property takes the Public and Private values. 只有在创建了私有可见性的项的容器中才能查看和更改这些项。Items that have private visibility can be viewed and changed only in the container in which they were created. 如果已添加或导入容器,则无法查看或更改具有私有可见性的项。If the container is added or imported, the items that have private visibility cannot be viewed or changed.

由于可见性是为容器设计的,因此它在作用域中的工作方式有所不同。Because visibility is designed for containers, it works differently in a scope.

  • 如果创建的项在全局范围内具有私有可见性,则无法查看或更改任何范围中的项。If you create an item that has private visibility in the global scope, you cannot view or change the item in any scope.
  • 如果尝试查看或更改具有私有可见性的变量的值,则 PowerShell 将返回错误消息。If you try to view or change the value of a variable that has private visibility, PowerShell returns an error message.

您可以使用 New-VariableSet-Variable cmdlet 来创建具有私有可见性的变量。You can use the New-Variable and Set-Variable cmdlets to create a variable that has private visibility.

示例Examples

示例1:仅在脚本中更改变量值Example 1: Change a Variable Value Only in a Script

以下命令更改 $ConfirmPreference 脚本中变量的值。The following command changes the value of the $ConfirmPreference variable in a script. 此更改不会影响全局范围。The change does not affect the global scope.

首先,若要 $ConfirmPreference 在本地范围中显示变量的值,请使用以下命令:First, to display the value of the $ConfirmPreference variable in the local scope, use the following command:

PS>  $ConfirmPreference
High

创建包含以下命令的 Scope.ps1 脚本:Create a Scope.ps1 script that contains the following commands:

$ConfirmPreference = "Low"
"The value of `$ConfirmPreference is $ConfirmPreference."

运行该脚本。Run the script. 此脚本将更改变量的值 $ConfirmPreference ,然后在脚本作用域中报告其值。The script changes the value of the $ConfirmPreference variable and then reports its value in the script scope. 输出应类似于以下输出:The output should resemble the following output:

The value of $ConfirmPreference is Low.

接下来,测试 $ConfirmPreference 当前作用域中的变量的当前值。Next, test the current value of the $ConfirmPreference variable in the current scope.

PS>  $ConfirmPreference
High

此示例说明对脚本作用域中变量的值所做的更改不会影响父作用域中的变量值。This example shows that changes to the value of a variable in the script scope does not affect the variable`s value in the parent scope.

示例2:查看不同范围中的变量值Example 2: View a Variable Value in Different Scopes

您可以使用作用域修饰符来查看本地范围和父范围中的变量的值。You can use scope modifiers to view the value of a variable in the local scope and in a parent scope.

首先, $test 在全局范围内定义变量。First, define a $test variable in the global scope.

$test = "Global"

接下来,创建一个定义变量的 Sample.ps1 脚本 $testNext, create a Sample.ps1 script that defines the $test variable. 在脚本中,使用范围修饰符来引用变量的全局或局部版本 $testIn the script, use a scope modifier to refer to either the global or local versions of the $test variable.

在 Sample.ps1 中:In Sample.ps1:

$test = "Local"
"The local value of `$test is $test."
"The global value of `$test is $global:test."

运行 Sample.ps1 时,输出应类似于以下输出:When you run Sample.ps1, the output should resemble the following output:

The local value of $test is Local.
The global value of $test is Global.

当脚本完成时,只有的全局值 $test 在会话中定义。When the script is complete, only the global value of $test is defined in the session.

PS>  $test
Global

示例3:更改父作用域中的变量的值Example 3: Change the Value of a Variable in a Parent Scope

除非使用 Private 选项或其他方法保护项,否则可以在父范围中查看和更改变量的值。Unless you protect an item by using the Private option or another method, you can view and change the value of a variable in a parent scope.

首先, $test 在全局范围内定义变量。First, define a $test variable in the global scope.

$test = "Global"

接下来,创建一个定义变量的 Sample.ps1 脚本 $testNext, create a Sample.ps1 script that defines the $test variable. 在脚本中,使用范围修饰符来引用变量的全局或局部版本 $testIn the script, use a scope modifier to refer to either the global or local versions of the $test variable.

在 Sample.ps1 中:In Sample.ps1:

$global:test = "Local"
"The global value of `$test is $global:test."

脚本完成后,的全局值 $test 将更改。When the script is complete, the global value of $test is changed.

PS>  $test
Local

示例4:创建私有变量Example 4: Creating a Private Variable

私有变量是具有值为 private选项 属性的变量。A private variable is a variable that has an Option property that has a value of Private. 私有 变量由子作用域继承,但只能在创建它们的作用域中查看或更改它们。Private variables are inherited by the child scope, but they can only be viewed or changed in the scope in which they were created.

下面的命令创建一个 $ptest 在本地范围中调用的私有变量。The following command creates a private variable called $ptest in the local scope.

New-Variable -Name ptest -Value 1 -Option private

您可以 $ptest 在本地范围中显示和更改的值。You can display and change the value of $ptest in the local scope.

PS>  $ptest
1

PS>  $ptest = 2
PS>  $ptest
2

接下来,创建一个包含以下命令的 Sample.ps1 脚本。Next, create a Sample.ps1 script that contains the following commands. 命令尝试显示并更改的值 $ptestThe command tries to display and change the value of $ptest.

在 Sample.ps1 中:In Sample.ps1:

"The value of `$Ptest is $Ptest."
"The value of `$Ptest is $global:Ptest."

$ptest变量在脚本作用域中不可见,输出为空。The $ptest variable is not visible in the script scope, the output is empty.

"The value of $Ptest is ."
"The value of $Ptest is ."

示例5:使用远程命令中的局部变量Example 5: Using a Local Variable in a Remote Command

对于在本地会话中创建的远程命令中的变量,请使用 Using 作用域修饰符。For variables in a remote command created in the local session, use the Using scope modifier. PowerShell 假设远程会话中创建了远程命令中的变量。PowerShell assumes that the variables in remote commands were created in the remote session.

语法为:The syntax is:

$Using:<VariableName>

例如,以下命令在 $Cred 本地会话中创建一个变量,然后 $Cred 在远程命令中使用该变量:For example, the following commands create a $Cred variable in the local session and then use the $Cred variable in a remote command:

$Cred = Get-Credential
Invoke-Command $s {Remove-Item .\Test*.ps1 -Credential $Using:Cred}

使用范围是在 PowerShell 3.0 中引入的。The Using scope was introduced in PowerShell 3.0. 在 PowerShell 2.0 中,若要指示在本地会话中创建了变量,请使用以下命令格式。In PowerShell 2.0, to indicate that a variable was created in the local session, use the following command format.

$Cred = Get-Credential
Invoke-Command $s {
  param($c)
  Remove-Item .\Test*.ps1 -Credential $c
} -ArgumentList $Cred

另请参阅See also

about_Variablesabout_Variables

about_Environment_Variablesabout_Environment_Variables

about_Functionsabout_Functions

about_Script_Blocksabout_Script_Blocks

Start-ThreadJobStart-ThreadJob