about_Scopes

Краткое описание

Описание концепции область в PowerShell и настройка и изменение область элементов.

Подробное описание

PowerShell защищает доступ к переменным, псевдонимам, функциям и дискам PowerShell (PSDrive), ограничивая их чтение и изменение. PowerShell использует правила область, чтобы предотвратить непреднамеренное изменение элемента, который не следует изменять.

Ниже приведены основные правила область.

  • Области могут быть вложенными. Внешний область называется родительским область. Все вложенные области являются дочерними областями этого родительского элемента.

  • Элемент отображается в область, в котором он был создан, и в любых дочерних областях, если вы явно не сделаете его закрытым.

  • Вы можете объявлять переменные, псевдонимы, функции и диски PowerShell в область за пределами текущего область.

  • Элемент, созданный в область, можно изменить только в область, в котором он был создан, если явно не указан другой область.

Если вы создаете элемент в область, а его имя совместно с элементом в другом область, исходный элемент может быть скрыт под новым элементом, но не переопределен или изменен.

Области PowerShell

PowerShell поддерживает следующие области:

  • Глобальный: область, который действует при запуске PowerShell или при создании нового сеанса или пространства выполнения. Переменные и функции, присутствующие при запуске PowerShell, были созданы в глобальной область, например автоматические переменные и переменные предпочтения. Переменные, псевдонимы и функции в профилях PowerShell также создаются в глобальной область. Глобальный область является корневым родительским область в сеансе.

  • Local: текущий область. Локальным область может быть глобальный область или любой другой область.

  • Скрипт: область, который создается во время выполнения файла скрипта. Только команды в скрипте выполняются в скрипте область. Для команд в скрипте область скрипта является локальным область.

Примечание

Частный не является область. Это параметр, который изменяет видимость элемента за пределами область, где он определен.

Родительская и дочерняя области

Можно создать новый дочерний область, вызвав скрипт или функцию. Вызывающий область является родительским область. Вызываемая скрипт или функция является дочерним область. Вызываемые функции или скрипты могут вызывать другие функции, создавая иерархию дочерних областей, корневая область которых является глобальной область.

Если вы явно не сделаете элементы закрытыми, элементы в родительском область будут доступны дочернему область. Однако элементы, создаваемые и изменяемые в дочернем область, не влияют на родительские область, если при создании элементов явно не указан область.

Примечание

Функции из модуля не выполняются в дочернем область вызывающего область. Модули имеют собственное состояние сеанса, связанное с глобальным область. Весь код модуля выполняется в определенной для модуля иерархии областей, которая имеет собственные корневые область.

Наследование

Дочерний область не наследует переменные, псевдонимы и функции от родительского область. Если элемент не является частным, дочерний область может просматривать элементы в родительском область. Кроме того, он может изменять элементы, явно указывая родительские область, но они не являются частью дочернего область.

Однако создается дочерний область с набором элементов. Как правило, он включает все псевдонимы с параметром AllScope . Этот параметр рассматривается далее в этой статье. Он включает все переменные с параметром AllScope , а также некоторые автоматические переменные.

Чтобы найти элементы в определенной область, используйте параметр Scope для Get-Variable или Get-Alias.

Например, чтобы получить все переменные в локальном область, введите:

Get-Variable -Scope local

Чтобы получить все переменные в глобальном область, введите:

Get-Variable -Scope global

Модификаторы области

Переменная, псевдоним или имя функции могут включать любой из следующих необязательных модификаторов область:

  • global:— указывает, что имя существует в глобальном область.

  • local:— указывает, что имя существует в локальном область. Текущим область всегда является локальный область.

  • private:— указывает, что имя — Private и отображается только для текущего область.

  • script:— указывает, что имя существует в область скрипта. Область скрипта — это ближайший файл скрипта-предка область или глобальный, если ближайший файл скрипта-предка отсутствует.

  • using:— используется для доступа к переменным, определенным в другом область при выполнении скриптов с помощью командлетов, таких как Start-Job и Invoke-Command.

  • workflow: — указывает, что имя существует в рабочем процессе. Примечание. Рабочие процессы не поддерживаются в PowerShell версии 6 и более поздних версий.

  • <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:

Using — это специальный модификатор область, определяющий локальную переменную в удаленной команде. Без модификатора PowerShell ожидает, что переменные в удаленных командах будут определены в удаленном сеансе.

Модификатор Using область представлен в PowerShell 3.0.

Для любого скрипта или команды, выполняемых вне сеанса, вам потребуется Using модификатор область для внедрения значений переменных из область вызывающего сеанса, чтобы код вне сеанса смог получить к ним доступ. Модификатор Using область поддерживается в следующих контекстах:

  • Удаленно выполняемые команды, запущенные с Invoke-Command использованием параметров ComputerName, HostName, SSHConnection или Session (удаленный сеанс)
  • Фоновые задания, запущенные с Start-Job (внепроцессный сеанс)
  • Задания потоков, запущенные с помощью Start-ThreadJob или ForEach-Object -Parallel (отдельный сеанс потока)

В зависимости от контекста внедренные значения переменных представляют собой независимые копии данных в область вызывающей стороны или ссылки на них. В удаленных и внепроцессных сеансах они всегда являются независимыми копиями.

Дополнительные сведения см. в разделе about_Remote_Variables.

В сеансах потоков они передаются по ссылке. Это означает, что можно изменить переменные вызова область в другом потоке. Для безопасного изменения переменных требуется синхронизация потоков.

Дополнительные сведения см. в разделах:

Сериализация значений переменных

Удаленно выполняемые команды и фоновые задания выполняются вне процесса. Внепроцессные сеансы используют сериализацию на основе XML и десериализацию, чтобы сделать значения переменных доступными через границы процесса. Процесс сериализации преобразует объекты в PSObject , содержащий свойства исходных объектов, но не его методы.

Для ограниченного набора типов десериализация восстанавливает объекты обратно в исходный тип. Восстановленный объект является копией исходного экземпляра объекта. Он содержит свойства и методы типа. Для простых типов, таких как System.Version, копия является точной. Для сложных типов копия несовершенна. Например, восстановленные объекты сертификата не включают закрытый ключ.

Экземпляры всех остальных типов являются экземплярами PSObject . Свойство PSTypeNames содержит исходное имя типа с префиксом Deserialized, например Deserialized.System.Data.DataTable

Параметр AllScope

Переменные и псевдонимы имеют свойство Option , которое может принимать значение AllScope. Элементы со свойством AllScope становятся частью всех создаваемых дочерних областей, хотя они не наследуются задним числом родительских областей.

Элемент со свойством AllScope отображается в дочернем область и является частью этого область. Изменения элемента в любом область повлиять на все области, в которых определена переменная.

Управление областью

Несколько командлетов имеют параметр Scope, который позволяет получать или задавать (создавать и изменять) элементы в определенном область. Используйте следующую команду, чтобы найти все командлеты в сеансе с параметром Scope :

Get-Help * -Parameter scope

Чтобы найти переменные, видимые в определенном область, используйте Scope параметр .Get-Variable Видимые переменные включают глобальные переменные, переменные в родительском область и переменные в текущем область.

Например, следующая команда возвращает переменные, видимые в локальной область:

Get-Variable -Scope local

Чтобы создать переменную в определенном область, используйте модификатор область или параметр Scope .Set-Variable Следующая команда создает переменную в глобальном область:

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

Для указания область можно также использовать параметр New-AliasScope командлетов , Set-Aliasили Get-Alias . Следующая команда создает псевдоним в глобальном область:

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

Чтобы получить функции в определенном область, используйте Get-Item командлет , когда находитесь в область. Командлет Get-Item не имеет параметра Scope .

Примечание

Для командлетов, использующих параметр Scope , можно также ссылаться на области по числу. Число описывает относительное положение одного область к другому. Область 0 представляет текущий или локальный область. Область 1 указывает непосредственное родительское область. Область 2 указывает родительский элемент родительского область и т. д. Нумерованные области полезны, если вы создали много рекурсивных областей.

Использование точечной исходной нотации с областью

Скрипты и функции следуют всем правилам область. Они создаются в определенном область, и они влияют только на область, если для изменения область не используется параметр командлета или модификатор область.

Но вы можете добавить скрипт или функцию в текущий область с помощью точечной исходной нотации. Затем, когда скрипт выполняется в текущем область, все функции, псевдонимы и переменные, создаваемые скриптом, будут доступны в текущем область.

Чтобы добавить функцию в текущий область, в вызове функции введите точку (.) и пробел перед путем и именем функции.

Например, чтобы запустить скрипт Sample.ps1 из каталога C:\Scripts в область скрипта (по умолчанию для скриптов), используйте следующую команду:

c:\scripts\sample.ps1

Чтобы запустить скрипт Sample.ps1 в локальном область, используйте следующую команду:

. c:\scripts.sample.ps1

При использовании оператора вызова (&) для выполнения функции или скрипта он не добавляется в текущий область. В следующем примере используется оператор вызова:

& c:\scripts.sample.ps1

Дополнительные сведения об операторе вызова см. в about_operators.

Псевдонимы, функции или переменные, создаваемые скриптом Sample.ps1, недоступны в текущем область.

Ограничение без области

Некоторые понятия PowerShell похожи на область или взаимодействия с область. Эти понятия можно спутать с область или поведением область.

Сеансы, модули и вложенные запросы являются автономными средами, но не являются дочерними областями глобального область в сеансе.

Сеансы

Сеанс — это среда, в которой выполняется PowerShell. При создании сеанса на удаленном компьютере PowerShell устанавливает постоянное подключение к удаленному компьютеру. Постоянное подключение позволяет использовать сеанс для нескольких связанных команд.

Поскольку сеанс является автономной средой, у него есть собственные область, но сеанс не является дочерним область сеанса, в котором он был создан. Сеанс начинается с собственного глобального область. Это область не зависит от глобального область сеанса. В сеансе можно создавать дочерние области. Например, можно запустить скрипт для создания дочернего область в сеансе.

Модули

Модуль PowerShell можно использовать для предоставления общего доступа к средствам PowerShell и их доставки. Модуль — это единица, которая может содержать командлеты, скрипты, функции, переменные, псевдонимы и другие полезные элементы. Если они не определены явным образом, элементы в модуле недоступны за пределами модуля. Таким образом, вы можете добавить модуль в сеанс и использовать общедоступные элементы, не беспокоясь о том, что другие элементы могут переопределить командлеты, скрипты, функции и другие элементы в сеансе.

По умолчанию модули загружаются на верхний уровень текущего состояния сеанса, а не на текущий область. Текущее состояние сеанса может быть состоянием сеанса модуля или состоянием глобального сеанса. Добавление модуля в сеанс не изменяет область. Если вы находитесь в глобальном область, модули загружаются в состояние глобального сеанса. Все экспорты помещаются в глобальные таблицы. При загрузке модуля module2 из модуля module1 модуль 2 загружается в состояние сеанса module1, а не в состояние глобального сеанса. Все экспорты из модуля 2 помещаются в начало состояния сеанса module1. Если вы используете Import-Module -Scope local, экспорты помещаются в текущий объект область, а не на верхнем уровне. Если вы находитесь в модуле и используете Import-Module -Scope global (или Import-Module -Global) для загрузки другого модуля, этот модуль и его экспорты загружаются в состояние глобального сеанса, а не локального сеанса модуля. Эта функция предназначена для написания модулей, которые управляют модулями. Модуль WindowsCompatibility делает это для импорта прокси-модулей в состояние глобального сеанса.

В состоянии сеанса модули имеют собственные область. Рассмотрим следующий модуль C:\temp\mod1.psm1:

$a = "Hello"

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

Теперь мы создадим глобальную переменную $a, присвоим ей значение и вызовем функцию foo.

$a = "Goodbye"
foo

Модуль объявляет переменную $a в модуле область затем функция foo выводит значение переменной в обеих областях.

$a = Hello
$global:a = Goodbye

Вложенные запросы

Вложенные запросы не имеют собственных область. При вводе вложенного запроса вложенный запрос является подмножеством среды. Но вы остаетесь в пределах местных область.

Скрипты имеют собственные область. Если выполняется отладка скрипта и достигается точка останова в скрипте, введите скрипт область.

Приватный параметр

Псевдонимы и переменные имеют свойство Option , которое может принимать значение Private. Элементы с параметром "Частные" можно просматривать и изменять в область, в котором они создаются, но их нельзя просматривать или изменять за пределами этого область.

Например, если вы создаете переменную с частным параметром в глобальном область, а затем запускаете скрипт, Get-Variable команды в скрипте не отображают частную переменную. При использовании модификатора глобального область в этом экземпляре частная переменная не отображается.

Можно использовать параметр New-VariableOption командлетов , Set-Variable, New-Aliasи Set-Alias , чтобы задать для свойства Option значение Private.

Видимость

Свойство Visibility переменной или псевдонима определяет, можно ли увидеть элемент за пределами контейнера, в котором он был создан. Контейнер может быть модулем, скриптом или оснасткой. Видимость предназначена для контейнеров так же, как частное значение свойства Option предназначено для областей.

Свойство Visibility принимает значения Public и Private . Элементы с закрытой видимостью можно просматривать и изменять только в контейнере, в котором они были созданы. При добавлении или импорте контейнера элементы, имеющие частную видимость, не могут быть просмотрены или изменены.

Так как видимость предназначена для контейнеров, она работает по-разному в область.

  • Если вы создаете элемент, который имеет частную видимость в глобальном область, вы не сможете просматривать или изменять элемент в область.
  • При попытке просмотреть или изменить значение переменной с закрытой видимостью PowerShell возвращает сообщение об ошибке.

Командлеты и Set-Variable можно использовать New-Variable для создания переменной с частной видимостью.

Примеры

Пример 1. Изменение значения переменной только в скрипте

Следующая команда изменяет значение переменной $ConfirmPreference в скрипте. Изменение не влияет на глобальные область.

Во-первых, чтобы отобразить значение переменной $ConfirmPreference в локальной область, используйте следующую команду:

PS>  $ConfirmPreference
High

Create скрипт 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. Изменение значения переменной в родительской области

Если вы не защищаете элемент с помощью параметра Private или другого метода, вы можете просматривать и изменять значение переменной в родительском область.

Сначала определите переменную $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

См. также раздел