Переменные — это своего рода виртуальные чемоданы, в которых можно хранить и транспортировать данные кода PowerShell. Иногда мы имеем дело с «заранее упакованными чемоданами». Так, встроенные переменные PowerShell, а также переменные среды Windows уже ассоциированы с назначенными им данными. В других случаях пользователям приходится «паковать чемоданы» своими руками. Работа с такими пользовательскими переменными требует несколько больших усилий, зато в них вкладывается именно та информация, которая нам нужна. Но перед тем как приступать к использованию встроенных переменных, переменных среды и пользовательских переменных, следует получить представление о базовых принципах.

Встроенные переменные

Оболочка PowerShell дает возможность работать со многими встроенными переменными, содержащими такие данные, как сведения о главной папке ($PSHOME) и о текущей рабочей папке ($PWD). Чтобы получить список встроенных переменных, а также пользовательских переменных, доступных в текущем сеансе, достаточно выполнить инструкцию

dir variable: | sort name

Используя псевдоним dir, эта инструкция обращается к команде Get-ChildItem, которая в качестве аргумента принимает строку variable. Данный аргумент ссылается на накопитель Variable, один из нескольких накопителей, поддерживаемых средой PowerShell. Как многие, вероятно, догадались, упомянутый накопитель позволяет обращаться к встроенным и пользовательским переменным PowerShell, а также к их значениям.

Когда команда Get-ChildItem получит переменные и их значения, они будут переданы по конвейеру команде Sort-Object (представленной псевдонимом sort), и последняя отсортирует выходные данные по именам переменных. Если же операция сортировки не будет проведена, переменные будут отображаться в том же порядке, в каком они были считаны.

На экране 1 показана часть отсортированного списка переменных. Такой список может быть поистине бесценным ресурсом, если только вы будете помнить об одном важном обстоятельстве: при ссылке на встроенные и пользовательские переменные в коде PowerShell следует, как правило, перед именем переменной вводить символ доллара ($). К сожалению, в списке эти знаки перед именами переменных не указываются. Символы доллара позволяют легко отличать переменные от других элементов кода. Так, именно символ доллара помогает без труда отличать псевдоним pwd от встроенной переменной $PWD. В ряде случаев ставить знак доллара перед именем переменной не следует, но об этом мы поговорим несколько позже.

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

$pshome

то получим путь к главной папке оболочки PowerShell.

Встроенные переменные (как и другие переменные PowerShell) можно использовать в инструкциях. Например, в следующей инструкции переменная $PSHOME применяется для получения списка файлов.dll, размещенных в главной папке PowerShell:

dir $pshome -filter *.dll

PowerShell поддерживает два типа встроенных переменных: приоритетные переменные (такие, как $MaximumErrorCount) и автоматические переменные (такие, как $PSHOME). Изменение значений приоритетных переменных допускается, тогда как значения автоматических переменных изменять нельзя. Если вы попытаетесь изменить значение автоматической переменной, то получите сообщение об ошибке. Список приоритетных переменных дан в справочном файле about_preference_variables. Если в вашей системе такого файла нет, его можно просмотреть в Internet по адресу technet.microsoft.com/en-us/library/bb978529.aspx. Список автоматических переменных дан в справочном файле about_automatic_variable. Дополнительные сведения о встроенных переменных можно найти в справочном файле about_shell_variable.

Чтобы изменить значение приоритетной переменной, достаточно указать ее новое значение с помощью оператора присваивания (=). Возьмем, к примеру, приоритетную переменную $MaximumErrorCount, которая определяет, сколько ошибок следует сохранять в журнале истории ошибок для текущего сеанса. По умолчанию эта переменная имеет значение 256. Чтобы заменить его на 260, выполните команду

$maximumerrorcount = 260

Это значение будет использоваться до тех пор, пока не будет указано новое значение или пока не закончится текущий сеанс работы.

Переменные среды

В оболочке PowerShell для обращения к переменным среды используется накопитель Env. К примеру, следующая инструкция предписывает задействовать этот накопитель для получения переменных среды Windows, а также их значений, а затем ввести команду Sort-Object для сортировки выходных данных по именам переменных:

dir env: | sort name

Как и в списке встроенных и пользовательских переменных, в перечне переменных среды не указывается префикс, который следует применять при обращении к переменным среды в коде PowerShell. Однако, в отличие от встроенных и пользовательских переменных, которые предваряются префиксом $, перед именем переменных среды при обращении к ним нужно указывать префикс $env:. Следующая инструкция считывает значение переменной среды windir, которое представляет собой путь к главной папке Windows:

$env: windir

Для получения списка файлов.dll в главной папке Windows нужно выполнить команду

dir $env: windir-filter *.dll

Значения переменных среды можно изменять. Допустим, переменная среды имеет значениеDocuments and Settingsadministrator и нам нужно присвоить ей новое значениеDocuments and Settingsadministratorhome. Мы можем с помощью оператора +, рассмотренного на уроке 3 (см. Windows IT Pro/RE № 5 за 2008 г.), присоединить строкуhome к значению переменной среды HOMEPATH:

$env: homepath =
$env: homepath + "home"

Заданное значение сохраняет силу до указания нового значения или до завершения сеанса работы. Дополнительные сведения о переменных среды даны в справочном файле about_environment_variables.

Пользовательские переменные

В отличие от некоторых языков сценариев, в среде PowerShell переменные можно использовать, предварительно не объявляя их явным образом. Достаточно просто указать значение переменной. В следующей инструкции переменной $var1 присваивается значение one two:

$var1 = "one two"

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

New-Variable var1 "one two"

Стоит отметить: в этой инструкции имя переменной не предваряется знаком доллара. Дело в том, что когда имя переменной передается в качестве аргумента команде New-Variable либо команде Set-Variable, Clear-Variable либо Remove-Variable (о них я расскажу ниже), символ доллара не используется.

Одно из преимуществ использования команды New-Variable для создания переменной состоит в том, что при этом можно применять другие параметры команды. Например, если требуется определить переменную как доступную только для чтения, можно использовать параметр -option:

New-Variable var1 "one two" `
-option ReadOnly

В данном случае в качестве аргумента параметра -option я указал ReadOnly. В этом качестве можно использовать и другие значения. При указании нескольких аргументов нужно разделять их запятыми. Полный список применяемых аргументов приведен в справочном файле New-Variable.

Когда переменная определяется как доступная только для чтения, изменить ее значение можно лишь методом форсирования. Но перед тем как я приступлю к подробному изложению этого вопроса, давайте посмотрим, как обновляются переменные. Как правило, самый простой способ изменения значения переменной состоит в присвоении ей нового значения с помощью оператора =:

$var1 = "three"

Тот же результат можно получить с помощью команды Set-Variable:

Set-Variable var1 "three"

Обе инструкции задают переменной новое значение, но только если она не определена как доступная лишь для чтения. В противном случае выдается сообщение об ошибке, и пользователь не может обновить значение переменной. Обойти эту проблему можно с помощью параметра -force.

Set-Variable var1 "three" -force

Теперь переменная получит новое значение. Как это было в случае с командой New-Variable, преимущество использования команды Set-Variable состоит в возможности применения дополнительных параметров.

А теперь давайте посмотрим, как сбрасывается значение переменной. Один из способов — присвоить ей значение null с помощью встроенной переменной $null:

$var1 = $null

Второй способ предполагает использование команды Clear-Variable:

Clear-Variable var1

Однако, как и в случае с ранее рассмотренными командами, если переменная была определена как доступная только для чтения, обе команды не дадут результата. Выход из положения опять-таки состоит в том, чтобы задействовать параметр -force:

Clear-Variable var1 `
-force

Наконец, если вы хотите вообще удалить переменную, можете использовать команду Remove-Variable:

Remove-Variable var1

Неудивительно, что эта команда возвратит ошибку, если переменная доступна только для чтения. Но, к счастью, она тоже поддерживает параметр -force:

Remove-Variable var1-force

Пожалуй, в большинстве случаев создавать, изменять и сбрасывать переменные можно просто с помощью оператора =. Однако, если вы хотите применять команды New-Variable, Set-Variable, Clear-Variable и Remove-Variable, обратите внимание, что дополнительные сведения о них содержатся в соответствующих справочных файлах.

Различные типы данных

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

$var1 = "one two"

Воссоздать переменную необходимо потому, что мы только что удалили ее с помощью команды Remove-Variable. Значения пользовательских переменных (как и значения встроенных переменных) можно получать, вводя с клавиатуры имя соответствующей переменной:

$var1

Переменной $var1 было присвоено строковое значение, поэтому в среде PowerShell оно хранится в виде строкового объекта. Для установления типа объекта мы можем воспользоваться методом GetType ():

$var1.gettype ()

На экране 2 показаны результаты выполнения всех этих инструкций.

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

$var1 = 123; $var1.gettype ()

PowerShell автоматически сохраняет это значение с использованием корректного типа (в данном случае Int32), как показано на экране 3. Обратите внимание, что в этом фрагменте кода имеется несколько инструкций. Как я уже отмечал на уроке 2 (см. Windows IT Pro/RE № 4 за 2008 г.), для завершения инструкции вручную можно использовать точку с запятой. Так что если вы будете пользоваться символами точки с запятой, то сможете размещать на одной строке несколько инструкций. В данном случае я расположил на одной строке две инструкции: в первой переменной присваивается числовое значение, а во второй возвращается тип данных.

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

Значения могут быть не только строковыми и целочисленными; переменным можно присваивать также значения других типов, например:

$var1 = 12.34; $var1.gettype ()
$var1 = get-date; $var1.gettype ()

Первая строка кода предписывает сохранить переменную типа Double, а вторая строка — типа Date-Time, как показано на экране 3.

Чтобы присоединить текст к существующему строковому значению в пользовательской переменной, можно использовать тот же метод, который я предложил для присоединения текста к существующему строковому значению в переменной среды. В следующем фрагменте кода переменной $var1 задается строковое значение, а затем к нему присоединяется строка four:

$var1 = "one two three"; $var1
$var1 = $var1 + "four"; $var1

Полученные результаты показаны на экране 4.

Теперь попытаемся проделать аналогичную операцию с числовыми значениями:

$var1 = 123; $var1
$var1 = $var1 + 4; $var1

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

$var1 = "123"; $var1
$var1 = $var1 + 4; $var1

Теперь число 4 присоединяется к исходному значению. Этот метод можно использовать применительно к любой строке:

$var1 = "one two three"; $var1
$var1 = $var1 + 4; $var1

В данном случае результаты, продемонстрированные на экране 4, могут показаться странными, но на самом деле все правильно: среда исполнения PowerShell сделала именно то, что было предписано.

Если к текстовому значению можно присоединять как текст, так и число, присоединение текста к числовому значению не допускается. К примеру, если мы попытаемся присоединить строку four к числу 123

$var1 = 123; $var1
$var1 = $var1 + "four"; $var1

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

Ссылки на переменные в строках

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

Обратимся к примеру. Присвоим строковой переменной с именем $svc значение eventlog:

$svc = "eventlog"

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

Write-Output "The service is $svc".

Когда оболочка PowerShell обнаруживает символ доллара, она интерпретирует слово как переменную, ибо строка заключена в двойные кавычки. Далее PowerShell вставляет на место имени переменной ее значение. При этом получается следующий результат: The service is eventlog.

Давайте теперь вместо двойных поставим одинарные кавычки:

Write-Output `
'The service is $svc.'

На этот раз PowerShell рассматривает переменную как литеральное значение и выдает ее имя. Результат получается такой: The service is $svc.

Если вы хотите включить в строку как имя переменной, так и ее значение, можете использовать двойные кавычки (а не одинарные) и экранировать переменную, которую хотите использовать как литеральное значение, с помощью обратной кавычки (`):

Write-Output `
"The value of `$svc is $svc".

Отмечу, что обратная кавычка в конце первой строки используется здесь не как экранирующий символ, а как символ продолжения. При этом получается результат: The value of $svc is eventlog.

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

Write-Output `
'The value of `$svc is $svc.'

PowerShell включит в выходные данные всю строку в том виде, в каком она была введена — с обратной кавычкой и всем прочим: The value of `$svc is $svc.

Использование в качестве параметра одного только имени переменной

В приведенных выше примерах было показано, как включать переменную в строковое значение, передаваемое в качестве аргумента команде Write-Output. Однако в некоторых случаях может возникнуть необходимость использования переменной в качестве аргумента команды таким образом, чтобы эта переменная не была частью строки. В этом случае переменную можно просто использовать как аргумент. Например, в следующей команде переменная $svc используется в качестве аргумента для имени службы:

Get-Service $svc

Если заключить этот аргумент в двойные кавычки — вот так:

Get-Service "$svc"

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

Get-Service ‘$svc’

завершится ошибкой, поскольку PowerShell будет интерпретировать имя службы как ‘$svc’.

На следующих уроках

При создании эффективных сценариев переменные (будь то встроенные переменные, переменные среды или пользовательские переменные) играют жизненно важную роль. Вы сможете в этом убедиться, когда будете работать в окне командной строки или составлять сценарии. Рекомендую обязательно просмотреть справочные файлы PowerShell, где вы найдете дополнительные сведения о переменных, и поупражняться в их создании, а также в применении. Получите методы и свойства с помощью команды Get-Member. Поэкспериментируйте с ними. И когда вы будете работать с более сложным кодом, придется пользоваться переменными — а также их методами и свойствами — при составлении целого ряда сценарных решений.

Роберт Шелдон (contact@rhsheldon.com) — технический консультант и автор книг, статей и учебных материалов по Microsoft Windows, а также проблемам проектирования и реализации систем бизнес-аналитики


Экран 1. Считывание списка встроенных и пользовательских переменных

Экран 2. Создание строковой переменной

Экран 3. Присваивание переменной различных типов значений

Экран 4. Присоединение значений к переменной