Да, профили PowerShell дот-источников по дизайну, потому что это то, что позволяет определения, содержащиеся в них (псевдонимы, функции, ...), чтобы быть глобально доступно по умолчанию - что в конечном итоге является основной целью файлов профилей.
К сожалению, нет никакой возможности модификатора, который позволяет создавать временную область для переменных, которые вы только хотите, чтобы существовать в то время как профиль нагрузка - даже сфера local
эффективно глобальный профильный сценарий; аналогично, использование области private
также не является вариантом, поскольку область действия этого профиля - из-за того, что точка-источник - - это глобальный охват.
Вообще говоря, вы можете использовать &
(оператор вызова) с блоком сценария для создания переменных внутри этого блока, которые контекстные к этому блоку, но это, как правило, расходится с созданием доступных глобально определений в профиле, по крайней мере, по умолчанию.
Аналогичным образом, вызов другого сценария без использования точек доступа, как и в вашем собственном ответе, по умолчанию не будет определять его определения по всему миру.
You может, однако, создавать глобальные элементы из , не -dot-источников блоков скрипта/сценария, указав глобальный масштаб явно; например: & { $global:foo = 'Going global' }
, или & { function global:bar { 'global func' } }
.
Это говорит, Обоснование профилей дота-сорсинг, вероятно, что это легче сделать все определения глобального по умолчанию, что делает определение типичных элементов профиля - псевдонимы, функции привода отображений, загрузка модулей - проще (нет необходимости указывать явную область).
В отличие от этого, глобальные переменные менее типичны, и для определения типичных элементов, перечисленных выше, обычно вам не нужны переменные типа скрипта (и, следовательно, глобальные) в вашем профиле.
Если вам все еще нужно создать (концептуально) временные переменные в вашем профиле (который не требование для создания доступных глобально псевдонимы, функции, ...):
простой обходной путь - используйте префикс имени экзотической переменной, такой как __
внутри сценария профиля, чтобы уменьшить риск их обращения по ссылке (например, $__profileVar1 = ...
).
Другими словами: переменные все еще существуют глобально, но их экзотические имена обычно не вызывают проблем.
Однако вашего подход, даже если это требует немного дополнительной работы, звучит как прочные обходной, вот как это выглядит в полном объеме (с использованием PSv3 + синтаксис):
# Save a snapshot of current variables.
# * If there are variables that you DO want to exist globally,
# define them ABOVE this command.
# * Also, load MODULE and dot-source OTHER SCRIPTS ABOVE this command,
# because they may create variables that *should* be available globally.
$varsBefore = (Get-Variable).Name
# ... define and use temporary variables
# Remove all variables that were created since the
# snapshot was taken, including $varsBefore.
Remove-Variable (Compare-Object $varsBefore (Get-Variable).Name).InputObject
Обратите внимание, что Я полагаюсь на поведение Compare-Object
по умолчанию только для сообщения разницы между объектами и, если вы еще не пробовали удалить любые переменные, только переменные добавлены. сообщили.
Обратите внимание, что в то время как это может быть вывод из фактического поведения файлов профиля, что они на самом деле точка-источников - учитывая, что точка-источников является единственным способом для добавления элементов в текущей области (глобальный сфера охвата, в случае профилей) - этот факт не является явно документированным как таковым.
Вот фрагменты из различных разделов справки (по состоянию на PSv5), которые обеспечивают ключи (курсив мой):
От Get-Help about_Profiles
:
профиль
под управлением Windows PowerShell скрипт, который запускается при Windows PowerShell начинается. Вы можете использовать профиль в качестве сценария входа в систему, чтобы настроить среду . Вы можете добавлять команды, псевдонимы, функции, переменные, оснастки, модули и диски Windows PowerShell. Вы также можете добавить в свой профиль другие элементы, относящиеся к сеансу, чтобы они были доступны на каждом этапе без необходимости их импорта или воссоздания.
От Get-Help about_Variables
:
По умолчанию переменные доступны только в области, в которой они созданы.
Например, переменная, которую вы создаете в функции, - это , доступная только внутри функции. Переменная, которую вы создаете в скрипте, доступна только в скрипте (, если только вы не используете сценарий, который добавляет его в текущую область действия).
От Get-Help about_Operators
:
. Оператор Dot sourcing Запускает скрипт в текущей области действия, чтобы любые функции, псевдонимы и переменные, созданные сценарием, добавлены в текущий .
От Get-Help about_Scopes
Но вы можете добавить скрипт или функцию в текущей области с помощью дот источника обозначения. Затем, когда сценарий запускается в текущей области, любые функции, псевдонимы и переменные, которые создает скрипт, доступны в текущей области.
Чтобы добавить функцию в текущую область действия, введите точку (.) И пробел до путь и имя функции в вызове функции.
Я не уверен в вашей цели. Зачем устанавливать области видимости переменных в 'script'? –
@Bill_Stewart: Цель состоит в том, чтобы использовать временные переменные внутри профиля, которые не должны задерживаться после завершения загрузки профиля. – mklement0
Ах. Да, профили PowerShell являются точками. –