共用方式為


關於範圍

簡短描述

說明 PowerShell 中的範圍概念,並示範如何設定和變更元素的範圍。

完整描述

PowerShell 藉由限制可讀取和變更的位置,來保護變數、別名、函式和 PowerShell 磁片磁碟機(PSDrives)的存取權。 PowerShell 會使用範圍規則,以確保您不會不慎變更不應變更的專案。

以下是範圍的基本規則:

  • 範圍可能會加以嵌套。 外部範圍稱為父範圍。 任何嵌套的範圍都是該父系的子範圍。

  • 除非您明確地將它設為私用,否則專案會在其建立所在的範圍和任何子範圍中顯示。 您可以將變數、別名、函式或 PowerShell 磁片磁碟機放在一或多個範圍中。

  • 您在範圍內建立的專案只能在其建立所在的範圍中變更,除非您明確指定不同的範圍。

如果您在範圍內建立專案,且該專案與不同範圍中的專案共用其名稱,則原始專案可能會隱藏在新專案底下,但不會遭到覆寫或變更。

PowerShell 範圍

PowerShell 支援下列範圍:

  • 全域: PowerShell 啟動時生效的範圍。 在全域範圍中建立 PowerShell 啟動時所出現的變數和函式,例如自動變數和喜好設定變數。 您 PowerShell 設定檔中的變數、別名和函式也會在全域範圍中建立。

  • 本機:目前的範圍。 本機範圍可以是全域範圍或任何其他範圍。

  • Script:執行腳本檔案時所建立的範圍。 只有腳本中的命令會在腳本範圍中執行。 對於腳本中的命令,腳本範圍是區域範圍。

注意

用不是範圍。 這是一個選項,可在定義專案的範圍外,變更專案的可見度。

父和子範圍

您可以藉由執行腳本或函式、建立會話,或啟動新的 PowerShell 實例,來建立新的範圍。 當您建立新的範圍時,其結果會是父範圍(原始範圍)和子範圍(您所建立的範圍)。

在 PowerShell 中,所有範圍都是全域範圍的子範圍,但您可以建立許多範圍和許多遞迴範圍。

除非您明確地將專案設為私用,否則父範圍中的專案可供子範圍使用。 不過,除非您在建立專案時明確指定範圍,否則在子範圍中建立和變更的專案不會影響父範圍。

繼承

子範圍不會繼承父範圍中的變數、別名和函式。 除非專案是私用的,否則子範圍可以查看父範圍中的專案。 而且,它可以藉由明確指定父範圍來變更專案,但這些專案不是子範圍的一部分。

不過,會使用一組專案來建立子範圍。 通常,它會包含所有具有AllScope選項的別名。 本文稍後將討論此選項。 它包含所有具有AllScope選項的變數,加上一些自動變數。

若要尋找特定範圍內的專案,請使用或的範圍 Get-Variable 參數 Get-Alias

例如,若要取得區域範圍中的所有變數,請輸入:

Get-Variable -Scope local

若要取得全域範圍中的所有變數,請輸入:

Get-Variable -Scope global

範圍修飾詞

變數、別名或函數名稱可以包含下列任何一個選擇性範圍修飾詞:

  • global:-指定名稱存在於全域範圍中。

  • local:-指定名稱存在於區域範圍中。 目前的範圍一律是區域範圍。

  • private:-指定此名稱是用的,而且只有在目前的範圍中才看得見。

  • script:-指定名稱存在於腳本範圍中。 如果沒有最接近的上階腳本檔案,腳本範圍就是最接近的上階腳本檔案範圍或全域

  • using:-用來存取在另一個範圍中定義的變數,同時透過和之類的 Cmdlet 執行腳本 Start-Job Invoke-Command

  • workflow:-指定名稱存在於工作流程中。 注意: PowerShell Core 不支援工作流程。

  • <variable-namespace>-PowerShell PSDrive 提供者所建立的修飾詞。 例如:

    命名空間 描述
    Alias: 在目前範圍中定義的別名
    Env: 在目前範圍中定義的環境變數
    Function: 在目前範圍中定義的函數
    Variable: 在目前範圍中定義的變數

腳本的預設範圍是腳本範圍。 函式和別名的預設範圍是區域範圍,即使它們是在腳本中定義也一樣。

使用範圍修飾符

若要指定新變數、別名或函數的範圍,請使用範圍修飾詞。

變數中範圍修飾詞的語法為:

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

函數中範圍修飾詞的語法為:

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

下列不使用範圍修飾詞的命令會在目前或本機範圍中建立變數:

$a = "one"

若要在全域範圍中建立相同的變數,請使用範圍 global: 修飾詞:

$global:a = "one"

若要在腳本範圍中建立相同的變數,請使用 script: 範圍修飾詞:

$script:a = "one"

您也可以搭配函數使用範圍修飾詞。 下列函式定義會在全域範圍中建立函式:

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

您也可以使用範圍修飾詞來參考不同範圍中的變數。 下列命令會參考 $test 變數,先在本機範圍中,然後在全域範圍內:

$test
$global:test

Using:範圍修飾詞

使用是特殊的範圍修飾詞,可在遠端命令中識別本機變數。 如果沒有修飾詞,PowerShell 會預期遠端命令中的變數會在遠端會話中定義。

Using 範圍修飾符是在 PowerShell 3.0 中引進。

如需詳細資訊,請參閱about_Remote_Variables

AllScope 選項

變數和別名的Option屬性可以採用AllScope的值。 具有AllScope屬性的專案會成為您所建立之任何子範圍的一部分,雖然父範圍不會追溯繼承它們。

具有AllScope屬性的專案會顯示在子範圍中,而且它是該範圍的一部分。 對任何範圍中的專案所做的變更,都會影響定義該變數的所有範圍。

管理範圍

有數個 Cmdlet 具有範圍參數,可讓您取得或設定(建立和變更)特定範圍中的專案。 使用下列命令來尋找會話中具有範圍參數的所有 Cmdlet:

Get-Help * -Parameter scope

若要尋找在特定範圍中可見的變數,請使用的 Scope 參數 Get-Variable 。 可見的變數包含全域變數、父範圍中的變數,以及目前範圍中的變數。

例如,下列命令會取得在本機範圍中可見的變數:

Get-Variable -Scope local

若要在特定範圍內建立變數,請使用範圍修飾符或的範圍參數 Set-Variable 。 下列命令會在全域範圍內建立變數:

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

您也可以使用 New-Alias 、或 Cmdlet 的 scope 參數 Set-Alias Get-Alias 來指定範圍。 下列命令會在全域範圍中建立別名:

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

若要取得特定範圍中的函式,請 Get-Item 在範圍內使用 Cmdlet。 Get-ItemCmdlet 沒有範圍參數。

注意

針對使用範圍參數的 Cmdlet,您也可以依數位參考範圍。 數位會描述某個範圍與另一個領域的相對位置。 範圍0代表目前或區域的範圍。 範圍1表示直屬父系範圍。 [範圍 2] 表示父範圍的父系,依此類推。 如果您已建立許多遞迴範圍,編號範圍會很有用。

搭配範圍使用點來源標記法

腳本和函式會遵循範圍的所有規則。 您會在特定範圍內建立它們,而且只有在您使用 Cmdlet 參數或範圍修飾詞來變更該範圍時,才會影響該範圍。

但是,您可以使用點來源標記法,將腳本或函數加入至目前的範圍。 然後,當腳本在目前的範圍中執行時,腳本所建立的任何函式、別名和變數都會出現在目前的範圍中。

若要將函式加入至目前的範圍,請在函式呼叫中的函式路徑和名稱前面輸入點(.)和空格。

例如,若要從腳本範圍中的 C:\Scripts 目錄執行 Sample.ps1 腳本(腳本的預設值),請使用下列命令:

c:\scripts\sample.ps1

若要在本機範圍中執行 Sample.ps1 腳本,請使用下列命令:

. c:\scripts.sample.ps1

當您使用呼叫運算子(&)來執行函式或腳本時,不會將它加入至目前的範圍。 下列範例會使用 call 運算子:

& c:\scripts.sample.ps1

您可以在about_operators中閱讀更多有關呼叫運算子的資訊。

目前的範圍中無法使用 Sample.ps1 腳本所建立的任何別名、函數或變數。

不含範圍的限制

少數 PowerShell 概念與範圍相似,或與範圍互動。 這些概念可能會與範圍或範圍的行為混淆。

會話、模組和嵌套提示是獨立的環境,但不是會話中全域範圍的子範圍。

工作階段

會話是 PowerShell 執行所在的環境。 當您在遠端電腦上建立會話時,PowerShell 會建立連到遠端電腦的持續連線。 持續性連接可讓您將會話用於多個相關的命令。

因為會話是包含的環境,所以它有自己的範圍,但會話不是建立它之會話的子系範圍。 會話會以自己的全域範圍開始。 此範圍與會話的全域範圍無關。 您可以在會話中建立子範圍。 例如,您可以在會話中執行腳本,以建立子範圍。

單元

您可以使用 PowerShell 模組來共用和提供 PowerShell 工具。 模組是一個可以包含 Cmdlet、腳本、函式、變數、別名和其他實用專案的單位。 除非明確定義,否則模組中的專案無法在模組外存取。 因此,您可以將模組新增至您的會話並使用公用專案,而不需擔心其他專案可能會覆寫您會話中的 Cmdlet、腳本、函式和其他專案。

模組的隱私權與範圍類似,但將模組新增至會話並不會變更範圍。 而且模組沒有自己的範圍,雖然模組中的腳本(如所有 PowerShell 腳本)確實有自己的範圍。

根據預設,模組會載入目前_會話狀態_的最上層,而不是目前的_範圍_。 這可能是模組會話狀態或全域會話狀態。 如果您在全域範圍內,則模組會載入至全域會話狀態。 任何匯出都會放入全域資料表中。 如果您從 module1_內部_載入 module2,module2 會載入 module1's 會話狀態,而不是全域會話狀態。 任何來自 module2 的匯出都會放在 module1's 會話狀態的頂端。 如果您使用 Import-Module -Scope local ,則匯出會放入目前的範圍物件中,而不是最上層。 如果您是_在模組中_,並使用 Import-Module -Scope global (或 Import-Module -Global )載入另一個模組,該模組和其匯出會載入至全域會話狀態,而不是模組的本機會話狀態。 這項功能是針對撰寫模組來管理操作模組所設計。 WindowsCompatibility 模組會執行此工作,將 proxy 模組匯入到全域範圍。

嵌套提示

同樣地,嵌套提示不會有自己的範圍。 當您輸入嵌套的提示字元時,嵌套的提示會是環境的子集。 但是,您仍在本機範圍內。

腳本有自己的範圍。 如果您正在對腳本進行調試,而且您到達腳本中的中斷點,請輸入腳本範圍。

私用選項

別名和變數的Option屬性可以接受用的值。 具有 [用] 選項的專案可以在建立它們的範圍中進行查看和變更,但無法在該範圍之外查看或變更。

例如,如果您在全域範圍中建立具有私用選項的變數,然後執行腳本, Get-Variable 則腳本中的命令不會顯示私用變數。 在此實例中使用全域範圍修飾詞,並不會顯示私用變數。

您可以使用 New-Variable 、、和 Cmdlet 的 option 參數, Set-Variable New-Alias Set-Alias 將 option 屬性的值設定為 Private。

可見性

變數或別名的可見度屬性會決定您是否可以在建立的容器外看到該專案。 容器可以是模組、腳本或嵌入式管理單元。 可見度是針對容器所設計,其方式與Option屬性的用值是針對範圍所設計。

可見度屬性會採用公用用值。 具有私用可見度的專案只能在其建立所在的容器中查看和變更。 如果新增或匯入容器,就無法查看或變更具有私用可見度的專案。

因為可見度是針對容器所設計,所以在範圍中的運作方式不同。

  • 如果您在全域範圍中建立具有私用可見度的專案,就無法在任何範圍中查看或變更專案。
  • 如果您嘗試查看或變更具有私用可見度的變數值,PowerShell 會傳回錯誤訊息。

您可以使用 New-VariableSet-Variable Cmdlet 來建立具有私用可見度的變數。

範例

範例1:只變更腳本中的變數值

下列命令會變更 $ConfirmPreference 腳本中的變數值。 變更不會影響全域範圍。

首先,若要 $ConfirmPreference 在區域範圍中顯示變數的值,請使用下列命令:

PS>  $ConfirmPreference
High

建立包含下列命令的 Scope.ps1 腳本:

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

執行指令碼。 腳本會變更變數的值 $ConfirmPreference ,然後報告其在腳本範圍中的值。 輸出應該類似下列輸出:

The value of $ConfirmPreference is Low.

接下來, $ConfirmPreference 在目前的範圍中測試變數目前的值。

PS>  $ConfirmPreference
High

這個範例顯示腳本範圍中變數值的變更不會影響父範圍中的變數值。

範例2:在不同範圍中查看變數值

您可以使用範圍修飾詞,來查看本機範圍和父範圍中的變數值。

首先, $test 在全域範圍中定義變數。

$test = "Global"

接下來,建立定義變數的 Sample.ps1 腳本 $test 。 在腳本中,使用範圍修飾詞來參考變數的全域或本機版本 $test

在 Sample.ps1:

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

當您執行 Sample.ps1 時,輸出應該類似下列輸出:

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

當腳本完成時,只 $test 會在會話中定義的全域值。

PS>  $test
Global

範例3:變更父範圍中的變數值

除非您使用私用選項或其他方法來保護專案,否則您可以在父範圍中查看和變更變數的值。

首先, $test 在全域範圍中定義變數。

$test = "Global"

接下來,建立定義變數的 Sample.ps1 腳本 $test 。 在腳本中,使用範圍修飾詞來參考變數的全域或本機版本 $test

在 Sample.ps1:

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

當腳本完成時,的全域值 $test 就會變更。

PS>  $test
Local

範例4:建立私用變數

私用變數是具有Option屬性的變數,其值為private用變數是由子範圍繼承而來,但只能在其建立所在的範圍中進行查看或變更。

下列命令會 $ptest 在本機範圍中建立名為的私用變數。

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

您可以 $ptest 在本機範圍中顯示和變更的值。

PS>  $ptest
1

PS>  $ptest = 2
PS>  $ptest
2

接下來,建立包含下列命令的 Sample.ps1 腳本。 命令會嘗試顯示並變更的值 $ptest

在 Sample.ps1:

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

$ptest變數不會顯示在腳本範圍中,輸出是空的。

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

範例5:在遠端命令中使用本機變數

針對在本機會話中建立之遠端命令中的變數,請使用 Using 範圍修飾詞。 PowerShell 會假設遠端命令中的變數是在遠端會話中建立的。

語法為:

$Using:<VariableName>

例如,下列命令會 $Cred 在本機會話中建立變數,然後 $Cred 在遠端命令中使用該變數:

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

Using 範圍是在 PowerShell 3.0 中引進。 在 PowerShell 2.0 中,若要指示在本機會話中建立了變數,請使用下列命令格式。

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

另請參閱

about_Variables

about_Environment_Variables

about_Functions

about_Script_Blocks