Как области влияют на сценарии PowerShell
В пакетных сценариях изменения переменных среды оказывают глобальное влияние на текущий сеанс по умолчанию. Для PowerShell верно обратное, поскольку области используются для изоляции изменений скрипта. Здесь мы рассмотрим, как области влияют на сценарии PowerShell и как работать с ними и вокруг них..
Что такое сфера?
В PowerShell «область действия» относится к текущей среде, в которой работает сценарий или командная оболочка. Области используются для защиты определенных объектов в среде от непреднамеренного изменения скриптами или функциями. В частности, следующие вещи защищены от изменения командами, запускаемыми из другой области, если в параметрах этих команд не указано иное:
- переменные
- Псевдонимы
- функции
- Диски PowerShell (PSDrives)
Новые области создаются всякий раз, когда вы запускаете скрипт или функцию, или когда вы создаете новый сеанс или экземпляр PowerShell. Области, созданные с помощью сценариев и функций, имеют отношение «родитель / потомок» с областью, из которой они были созданы. Есть несколько областей, которые имеют особое значение и могут быть доступны по имени:
- Глобальный область действия - это область, которая создается при запуске PowerShell. Он включает в себя переменные, псевдонимы, функции и PSDrive, встроенные в PowerShell, а также любые переменные, созданные вашим профилем PowerShell..
- Местный область действия относится к тому, что является текущей областью действия. Когда вы запускаете PowerShell, он ссылается на глобальную область, в сценарии - на область сценария и т. Д..
- скрипт Область создается при запуске скрипта. Единственные команды, которые работают в этой области, это те, которые находятся в скрипте.
- Частный области действия могут быть определены в текущей области, чтобы команды других областей не могли читать или изменять элементы, к которым они могли бы иметь доступ в противном случае.
Области также могут упоминаться по номеру в определенных командах, где текущая область именуется нулем, а на его предков ссылаются увеличивающиеся целые числа. Например, в сценарии, выполняемом из глобальной области действия, область действия «Сценарий» будет равна 0, а область действия «Глобальная» будет иметь значение 1. Область, которая далее вложена в область действия «Сценарий», например функцию, будет относиться к глобальной области действия как 2 Отрицательные числа не будут работать, чтобы ссылаться на детские области, хотя - причина этого будет очевидна в ближайшее время.
Как области влияют на команды
Как упоминалось ранее, команды, выполняемые в одной области, не будут влиять на вещи в другой области, если не указано иное. Например, если $ MyVar существует в глобальной области действия, и сценарий запускает команду для установки $ MyVar в другое значение, глобальная версия $ MyVar останется неизменной, пока копия $ MyVar помещается в область действия сценария с новой значение. Если $ MyVar не существует, сценарий по умолчанию создаст его в области действия «Сценарий», а не в глобальной. Это важно помнить, когда вы узнаете о фактических отношениях родитель / ребенок между областями.
Родительско-дочерние отношения областей в PowerShell являются односторонними. Команды могут просматривать и, при необходимости, изменять текущую область видимости, ее родителя и любые области видимости выше этого. Однако они не могут видеть или изменять вещи ни в каких дочерних элементах текущей области. Это связано прежде всего с тем, что, как только вы перешли в родительскую область, дочерняя область уже была уничтожена, потому что она выполнила свою задачу. Например, зачем вам нужно видеть или изменять переменную в области «Сценарий», из глобальной области, после завершения сценария? Есть много случаев, когда вам нужно, чтобы изменения скрипта или функции сохранялись после его завершения, но не так много, когда вам нужно было вносить изменения в объекты в пределах действия скрипта или функции до или после его запуска. (Обычно такие вещи будут обрабатываться как часть скрипта или самой функции в любом случае.)
Конечно, каковы правила без исключений? Единственным исключением из вышеперечисленного являются частные области действия. Объекты в частных областях доступны только для команд, запущенных в области, из которой они были созданы. Другим важным исключением являются элементы, имеющие свойство AllScope. Это специальные переменные и псевдонимы, для которых изменение в любой области действия затронет все области. Следующие команды покажут, какие переменные и псевдонимы имеют свойство AllScope:
Get-Variable | Where-Object $ _. Options -match 'AllScope' Get-Alias | Where-Object $ _. Options -match 'AllScope')
Области в действии
Для нашего первого взгляда на области в действии мы начнем с сеанса PowerShell, где переменная $ MyVar была установлена в строку «Я глобальная переменная!» Из командной строки. Затем следующий скрипт будет запущен из файла с именем Scope-Demo.ps1:
Function FunctionScope 'Изменение $ MyVar с помощью функции.' $ MyVar = 'Меня установила функция!' «MyVar говорит $ MyVar» «Проверка текущего значения $ MyVar». «MyVar говорит: $ MyVar» «Изменение $ MyVar с помощью скрипта». $ MyVar = 'Меня установил скрипт!' «MyVar сообщает $ MyVar» «FunctionScope» Проверка окончательного значения MyVar перед завершением работы скрипта. ' "MyVar говорит, что $ MyVar" "
Если сценарии PowerShell работают так же, как пакетные сценарии, мы ожидаем, что значение переменной $ MyVar (или% MyVar% в пакетном синтаксисе) изменится с «Я глобальная переменная!» На «Меня установил сценарий!» и, наконец, «меня установили с помощью функции!» где он будет оставаться, пока он не будет явно изменен снова или сеанс не будет завершен. Тем не менее, посмотрите, что на самом деле происходит здесь, когда мы перемещаемся по каждой из областей, в частности, после того, как функция FunctionScope завершила свою работу, и мы снова проверили переменную из скрипта, а затем и из глобальной области видимости..
Как вы можете видеть, переменная, казалось, изменилась, когда мы продвигались по сценарию, потому что до тех пор, пока функция FunctionScope не была завершена, мы проверяли переменную из той же области, в которой она была изменена в последний раз. После того, как FunctionScope был сделан, мы вернулись в область действия Script, где функция $ MyVar осталась нетронутой. Затем, когда скрипт завершился, мы вернулись в глобальную область видимости, где он вообще не был изменен.
Выход за пределы локальной сферы
Итак, это все хорошо, чтобы помочь вам избежать случайного внесения изменений в среду помимо ваших сценариев и функций, но что, если вы действительно хотите внести такие изменения? Существует специальный и довольно простой синтаксис для создания и изменения объектов за пределами локальной области видимости. Вы просто помещаете имя области в начале имени переменной и ставите двоеточие между областью и именами переменных. Как это:
$ global: MyVar $ скрипт: MyVar $ local: MyVar
Вы можете использовать эти модификаторы как при просмотре, так и при настройке переменных. Давайте посмотрим, что происходит с этим демонстрационным скриптом:
Function FunctionScope "Изменение $ MyVar в локальной области действия функции… '$ local: MyVar =" Это MyVar в локальной области действия функции. "' Изменение $ MyVar в области действия сценария ... '$ script: MyVar =' MyVar раньше использовался как устанавливается с помощью скрипта. Теперь устанавливается с помощью функции. "Изменение $ MyVar в глобальной области видимости ..." $ global: MyVar = 'MyVar было установлено в глобальной области действия. Теперь устанавливается функцией. «Проверка $ MyVar в каждой области видимости…» «Локальный: $ local: MyVar» «Сценарий: $ script: MyVar» «Глобальный: $ global: MyVar» »« Получение текущего значения $ MyVar. ' «MyVar говорит: $ MyVar» «Изменение $ MyVar с помощью скрипта». $ MyVar = 'Меня установил скрипт!' «MyVar сообщает $ MyVar» FunctionScope «Проверка $ MyVar из области действия скрипта перед выходом». "MyVar говорит, что $ MyVar" "
Как и прежде, мы начнем с установки переменной в глобальной области действия и закончим проверкой окончательного результата глобальной области действия..
Здесь вы можете видеть, что FunctionScope смог изменить переменную в области Script и сохранить изменения после ее завершения. Кроме того, изменение переменной в глобальной области действия сохранялось даже после выхода из сценария. Это может быть особенно полезно, если вам приходится многократно изменять переменные в скрипте или в глобальной области, используя один и тот же код - вы просто определяете функцию или скрипт, которые написаны для изменения переменной, где и как вам это нужно, и призывать к этому всякий раз, когда эти изменения необходимы.
Как упоминалось ранее, номера областей также могут использоваться в определенных командах для изменения переменной на разных уровнях по отношению к локальной области. Вот тот же сценарий, который использовался во втором примере выше, но с функцией, модифицированной для использования команд Get-Variable и Set-Variable с номерами областей вместо прямой ссылки на переменную с именованными областями действия:
Function FunctionScope "Изменение $ MyVar в области 0 относительно FunctionScope… 'Set-Variable MyVar" Это MyVar в области действия функции 0. "-Scope 0' Изменение $ MyVar в области 1 относительно относительно FunctionScope… 'Set-Variable MyVar 'MyVar был изменен в области 1, из функции.' -Scope 1 'Изменение $ MyVar в области действия 2 относительно Functionscope…' Set-Variable MyVar 'MyVar было изменено в области действия 2 из функции.' -Scope 2 «Проверка $ MyVar в каждой области действия…» Область 0: «Get-Variable MyVar -Scope 0 -ValueOnly» Область 1: «Get-Variable MyVar -Scope 1 -ValueOnly» Область 2: «Get-Variable MyVar -Scope 2 -ValueOnly "" Получение текущего значения $ MyVar. ' «MyVar говорит: $ MyVar» «Изменение $ MyVar с помощью скрипта». $ MyVar = 'Меня установил скрипт!' «MyVar сообщает $ MyVar» FunctionScope «Проверка $ MyVar из области действия скрипта перед выходом». "MyVar говорит, что $ MyVar" "
Как и прежде, мы видим здесь, как команды в одной области видимости могут изменять объекты в родительской области видимости..
Дополнительная информация
С областями видимости можно сделать гораздо больше, чем можно описать в этой статье. Области действия влияют не только на переменные, и еще многое предстоит узнать о частных областях и переменных AllScope. Для получения более полезной информации вы можете запустить следующую команду из PowerShell:
Get-Help about_scopes
Этот же файл справки также доступен на TechNet..
Область изображения кредита: spadassin на openclipart