Присвоение правильных типов переменных при чтении из файла конфигурации [PowerShell]. Powershell тип переменной


Переменные в PowerShell

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

Создание переменных

В самом простом варианте для создания новой переменной достаточно ввести в консоли ее допустимое имя. Имя переменной всегда начинается со знака $ и может содержать любые буквы и цифры, а также знак подчеркивания. К примеру, команда $var создаст переменную с именем $var. Однако созданная таким образом переменная не имеет значения. Создать переменную и присвоить ей какое-либо значение можно одним действием, например:

$var = 8

или

$var = ″Windows″

Учтите, что PowerShell создаст переменную только в том случае, если она не существует, иначе указанное значение присваивается существующей переменной.

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

[string]$var = Windows

логический:

[boolean]$b = $true

или одномерный массив:

[hashtable]$h = @{a=1;b=2;c=3}

И наоборот, можно посмотреть тип данных в переменной:

$h.GetType().FullName

 

Еще у переменных в PowerShell есть такое понятие как область действия (Scope). Область может быть глобальной (Global) или локальной (Local). Глобальная область распространяется на весь текущий сеанс, в эту область входят системные переменные и переменные, входящие в профили PowerShell. Локальные переменные ограничены той областью, в которой были определены (напр. функцией или скриптом) и за пределы этой области не распространяются. Есть еще область действия сценария (Script), но для команд в скрипте область действия скрипта также является локальной, так что по сути области всего две.

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

$Global:test = 10

Для лучшего понимания проведем небольшой эксперимент. Создадим переменную $test и зададим ей значение Global:

$test = ″Global″

Cоздадим скрипт test.ps1, содержащий следующий текст:

$test = ″Local″ ″Текущее значение переменной: $test″

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

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

А теперь немного изменим скрипт:

$Global:test = ″Local″ ″Текущее значение переменной: $test″

И снова запустим его. На первый взгляд ничего не изменилось, но если еще раз вывести переменную $test, то она будет иметь значение Local. Поскольку на этот раз в скрипте мы указали глобальную область действия, то значение переменной действительно и за пределами скрипта.

 

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

Управление переменными

Для создания и управления переменными можно пользоваться специальными командлетами. Их список в удобочитаемой форме можно вывести командой:

Get-Command -Noun Variable | ft -Property Name, Definition -AutoSize -Wrap

 

Например создать переменную можно с помощью командлета New-Variable :

New-Variable -Name var -Value 8

Изменить значение с помощью Set-Variable:

Set-Variable -Name var -Value 10

И посмотреть ее свойства с помощью Get-Variable:

Get-Variable -Name var | Format-List

 

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

 

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

Remove-Variable -Name * -Force -ErrorAction SilentlyContinue

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

New-Variable -Name var -Value 8 -Option Constant

Получается постоянная переменная :), при попытке изменить или удалить такую переменную будет выдана ошибка. Вместо Constant можно поставить значение ReadOnly, которое также не дает изменять значение переменной, но позволяет ее удалить.

Примечание. Изменить значение переменной только для чтения можно командой New-Variable с параметром -Force.

 

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

New-Variable -Name priv -Value 10 -Visibility Private

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

 Хранение данных в переменных

Одно из наиболее полезных свойств переменных в PowerShell — это возможность сохранять в них результаты выполнения команд. Для примера выберем системный процесс spoolsv и сохраним его в переменной $proc:

$proc = Get-Process -Name spoolsv

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

$proc.Description

Немного изменим его вывод, заменив все буквы ″p″ на ″s″ командой:

$proc.Description.Replace(″p″,″s″)

И завершим издевательства над процессом :), завершив его с помощью метода Kill, вот так:

$proc.Kill()

Системные переменные

Кроме переменных, созданных пользователем вручную, в PowerShell можно использовать системные переменные. Посмотреть список всех переменных можно, выведя содержимое переменного диска:

dir Variable:

либо командой:

Get-Variable

 

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

$env:windir

Просмотреть их все можно командой:

dir Env:

 

Ну вот собственно и все, что я хотел рассказать о переменных в PowerShell. Надеюсь, получилось не очень скучно 🙂

windowsnotes.ru

Power Shell переменные

Давайте внимательно взглянем на переменные PowerShell, которые позволяют хранить, извлекать и работать с информацией. Windows PowerShell предназначен для того, чтобы делать повседневную работу IT-специалистов более эффективной. Синтаксис PowerShell интуитивен настолько, что даже администраторы начального или среднего уровня вполне могут совладать с ним. Это верно не только для подачи консольных команд, но и для написания простых сценариев – powershell приложения.

Сценарии и переменные PowerShell

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

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

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

Имя любой переменной в PowerShell начинается со знака доллара $, например:

Присваивание переменной значения происходит посредством оператора «=», например:

или

PowerShell поддерживает много типов переменных:

  • текстовые строки;
  • целые;
  • десятичные;
  • массивы;
  • номера версии;
  • IP-адреса.

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

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

Переменные и математические операторы

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

Численные значения также можно увеличить или уменьшить с помощью ++ или – без указания +1 или -1, например, эти две строки идентичны по полученному результату:

$MyVariable=$MyVariable+1 $MyVariable++

$MyVariable=$MyVariable+1

 

$MyVariable++

PowerShell  строки

Оператор сложения используется для конкатенации (объединения) строк PowerShell:

$var1 = “Алена ” $rez = $var1 + “любит яблоки” $rez = “$var1 + любит яблоки”

$var1 = “Алена ”

 

$rez = $var1 + “любит яблоки”

 

$rez = “$var1 + любит яблоки”

PowerShell вывод

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

sysadmin-arh.ru

Переменные в Windows PowerShell | вебисторий

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

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

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

$a=1

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

$a | Get-Member

В данном случае тип переменной System.Int32. Более лаконичную информацию мы можем получить при использовании метода GetType().

$a.GetType().FullName

Если мы изменим значение переменной на текстовое, то тип переменной автоматически изменится.

Мы можем указать тип вручную:

[System.Int32]$a=5

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

Как видим, мы определили тип переменной $a как System.Int32. Затем мы изменили её значение на текст, заключенный в кавычки. Но PowerShell преобразовал его к числу.

Как уже было сказано, Windows PowerShell преобразует значения переменных в заданный формат по возможности. Например, не каждый текст возможно свести к числу. Если это невозможно, Вы увидите вот такую ошибку:

Невозможность преобразования переменной к заданному типу

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

[int]$a=5

Ниже приведены псевдонимы основных типов переменных в PowerShell.

Псевдоним Тип переменных
[int] System.Int32
[int[]] System.Int32[] (массив элементов типа System.Int32)
[long] System.Int64
[long[]] System.Int64[] (массив элементов типа System.Int64)
[string] System.String
[string[]] System.String[] (массив элементов типа System.String)
[char] System.Char
[char[]] System.Char[] (массив элементов типа System.Char)
[bool] System.Boolean
[bool[]] System.Boolean[] (массив элементов типа System.Boolean)
[byte] System.Byte
[byte[]] System.Byte[] (массив элементов типа System.Byte)
[double] System.Double
[double[]] System.Double[] (массив элементов типа System.Double)
[decimal] System.Decimal
[decimal[]] System.Decimal[] (массив элементов типа System.Decimal)
[float] System.Float
[single] System.Single
[regex] System.Text.RegularExpressions.regex
[array] System.Array
[xml] System.Xml.XmlDocument
[scriptblock] System.Management.Automation.ScriptBlock
[switch] System.Management.Automation.SwitchParameter
[hashtable] System.Collections.Hashtable
[psobject] System.Management.Automation.PSObject
[type] System.Type

На этом пока всё, что нам нужно знать о пользовательских переменных. Далее поговорим о переменных среды Windows.

Продолжение следует…

webistore.ru

Присвоение правильных типов переменных при чтении из файла конфигурации [PowerShell]

Я пытаюсь читать значения из текстового файла и хранить их как переменные для использования в моем скрипте.

Этот файл конфигурации содержит строки, ints, booleans и массив, который может содержать строки, ints и логические значения.

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

Это создает мой файл конфигурации в том формате, который я хотел бы.

Function Create-Config() { If (!(Test-Path config.txt)) { $currentlocation=Get-Location $parentfolder=(get-item $currentlocation).parent.FullName New-Item config.txt -ItemType "file" Add-Content config.txt "SERVER_NAME=MyServer" Add-Content config.txt "SERVER_LOCATION=$currentlocation" Add-Content config.txt "BACKUP_LOCATION=$parentfolder\backup" Add-Content config.txt "CRAFTBUKKIT=craftbukkit.jar" Add-Content config.txt "JAVA_FLAGS=-Xmx1G" Add-Content config.txt "CRAFTBUKKIT_OPTIONS=-o True -p 1337" Add-Content config.txt "TEST_DEPENDENCIES=True" Add-Content config.txt "DELETE_LOG=True" Add-Content config.txt "TAKE_BACKUP=True" Add-Content config.txt "RESTART_PAUSE=5" }

}

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

Function Load-Variables() { Get-Content config.txt | Foreach-Object { $var = $_.Split('=') New-Variable -Name $var[0] -Scope Script -Value $var[1] } }

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

Если я объявляю массив, используя следующую команду:

New-Variable -Name CRAFTBUKKIT_OPTIONS -Option Constant -Value ([array]@('-o',$true,'-p',25565))

я получаю именно то, что я хочу, но мне нужно, чтобы импортировать его из файла конфигурации вместо того, чтобы объявить переменную в моем сценарии. Программа java немного лаконична, поэтому я не могу просто импортировать это значение в виде строки, иначе она не будет передана правильно, и эти параметры будут проигнорированы. Я нашел единственный способ, которым это работает, - иметь его как массив (как определено выше). Я также хочу отметить, что может быть много других опций файла конфигурации, чем в моем примере.

Я не уверен, какой лучший подход - импортировать переменные, которые будут объявлены правильно (что бы я хотел сделать), или предполагая, что они не могут быть импортированы как что-либо иное, кроме строки, а затем разбирать эту строку в правильном переменные типы после.

Я попытался объявить переменные перед рукой и с помощью команды Set-Variable установить значения, но это не сработает. Очень похоже, что мои переменные импортируются с Get-Content как строки с самого начала, а не из правильных типов.

Полный сценарий здесь: https://gist.github.com/TnTBass/4692f2a00fade7887ce4

stackoverrun.com

PowerShell. Урок 5 | Windows IT Pro/RE

Переменные — это своего рода виртуальные чемоданы, в которых можно хранить и транспортировать данные кода 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. Поэкспериментируйте с ними. И когда вы будете работать с более сложным кодом, придется пользоваться переменными — а также их методами и свойствами — при составлении целого ряда сценарных решений.

Роберт Шелдон ([email protected]) — технический консультант и автор книг, статей и учебных материалов по Microsoft Windows, а также проблемам проектирования и реализации систем бизнес-аналитики

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

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

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

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

www.osp.ru

Заметки для себя: Windows Powershell Возможности переменных

Windows Powershell Возможности переменных Дон Джонс (Don Jones)

Если вы работаете с языками сценариев на основе Windows, такими как VBScript или KiXtart, вы знаете, что переменная это просто удобное «приспособление» для хранения данных. В языке Windows PowerShell тоже есть переменные, но они, в отличие от переменных в более старых языках сценариев, предоставляют разработчикам куда больше возможностей.

Переменные PowerShell фактически сопоставимы с основными классами платформы Microsoft® .NET Framework. А в .NET Framework переменные являются объектами, а это значит, что с данными, хранящимися в переменных, можно производить различные операции. Именно благодаря огромным функциональным возможностям переменных, в языке сценариев Windows PowerShell™ отсутствуют встроенные функции обработки данных; в них не нужды — необходимая функциональность обеспечивается самими переменными.

Объявление переменных

Для объявления переменной и присвоения ей значения можно использовать командлет New-Variable, но можно поступить проще — создать переменную и присвоить ей значение: Имена переменных в PowerShell всегда начинаются со знака доллара ($) и могут содержать цифры, буквы, символы и даже пробелы (при использовании пробелов необходимо заключить переменную в фигурные скобки таким образом: ${My Variable} = "Hello"). В этом примере мы создали переменную с именем $var и присвоили ей значение «Hello». Поскольку в данном случае значение переменной это строка, состоящая из символов, PowerShell присвоит переменной тип String (Строковый). В терминах .NET Framework это класс System.String, обладающий, возможно, из всех типов переменных наибольшим количеством встроенных функций. Допустим, мы хотим, чтобы значение переменной $var выводилось только символами в нижнем регистре. Это можно сделать следующим образом: PS C:\> $var.ToLower() hello PS C:\> Метод ToLower встроен в класс System.String class и результатом его применения будет представление значения строковой переменной символами в нижнем регистре. При этом значение переменной $var остается неизменным. Чтобы увидеть полный список возможностей класса System.String, передайте строковую переменную командлету Get-Member:

На рис. 1 показан результат этой операции — пара десятков методов для обработки строковых переменных. Практически все возможности функций обработки строковых данных VBScript присутствуют в методах строковых переменных Windows PowerShell.

Figure 1 A look at the System.String class output (Щелкните изображение, чтобы увеличить его)

При администрировании многие возможности строковых переменных оказываются более полезными, нежели функции обработки строк в языках типа VBScript. Предположим, вы написали сценарий, считывающий из файла пути с универсальными именами (UNC) и производящий над ними какие-либо действия. Прежде чем использовать считанный путь для своих целей, необходимо убедиться, что каждый он действительно имеет универсальное имя. Метод StartsWith позволяет убедиться, что строка начинается с двойной обратной косой черты, являющейся необходимым атрибутом стандарта UNC: PS C:\> $path = "\\Server\Share" PS C:\> $path.StartsWith("\\") True PS C:\> Поскольку метод StartsWith возвращает значения True («Истина») или False («Ложь»), он применяется в логических построениях: if ($path.StartsWith("\\")) { # code goes here } В Windows PowerShell имеется функция автозаполнения в методах переменных, что позволяет сэкономить время, затрачиваемое на ввод с клавиатуры. Если переменная $var имеет строковое значение, введите следующее:

и затем нажмите клавишу Tab. Появится первое имя метода переменной $var. При повторном нажатии клавиши Tab появится следующий метод, а при нажатии клавиш Shift+Tab — предыдущий. Таким образом можно просмотреть все доступные методы и выбрать нужный.

Путаница

В примерах, приведенных выше, тип переменных определялся автоматически. Присваивание переменной строкового значения приводит к тому, что переменная будет принадлежать к классу System.String. Присваивание переменной численного значения, как правило, приводит к тому, что переменная будет принадлежать к классу Integer (Цело число), а точнее — Int32, классу с определенным диапазоном значений. Рассмотрим следующий пример: PS C:\> $int = 5 PS C:\> $int | get-member TypeName: System.Int32

Одинокая строка на выходе — результат того, что Windows PowerShell воспринимает переменную $int как переменную класса Int32, который имеет собственный набор методов и свойств, которых, кстати, значительно меньше, чем у типа String.

Переменной $int стала переменной класса Int32, поскольку ее значение не было заключено в кавычки и состояло только из цифр. Если бы значение было заключено в кавычки, переменная была бы воспринята как переменная класса System.String.

Автоматическое определение типа переменных не всегда приводит к желаемым результатам. Допустим, вы при считывании значений из файла необходимо, чтобы они обрабатывались как строковые данные. Но некоторые значения могут состоять только из цифр, а это значит, что Windows PowerShell может обрабатывать их как переменные типа Int32 или другого численного типа. Это может привести к нежелательным последствиям, а именно: если PowerShell не распознает значение переменной как строковое, методы класса System.String недоступны (соответственно в сценарии будет использоваться один из недоступных методов).

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

Переменная $var была бы переменной типа Int32, если бы мы не объявили ее переменной типа String, что позволяет применять к ней все методы класса System.String. Кроме того, объявление типа переменной придает сценарию большую наглядность, поскольку теперь у нас не возникает сомнений относительно типа данных, хранящихся в переменной $var. Я вообще взял за правило самостоятельно объявлять тип каждой переменной, отобрав право выбора у Windows PowerShell. Благодаря этому поведение моих сценариев более предсказуемо. Кроме того, я несколько раз сэкономил время при отладке

Как вы догадываетесь, принудительное объявление переменных влечет за собой различные последствия, причем не всегда плачевные. Рассмотрим пример, в котором тип переменной не объявляется: PS C:\> $me = 5 PS C:\> $me = "Don"

Сначала переменная $me была переменной типа Int32, но Windows PowerShell изменил ее тип на String, когда было присвоено значение "Don". Windows PowerShell может изменять тип переменной по мере необходимости, в случае если тип переменной не был предварительно объявлен.

В следующем примере мы объявляем переменную $me переменной типа Int32 с помощью имени типа [int]: PS C:\> [int]$me = 5 PS C:\> $me = "Don" Cannot convert value "Don" to type "System.Int32". Error: "Input string was not in a correct format." At line:1 char:4 + $me <<<< = "Don"

Затем мы присваиваем ей строковое значение, в результате чего появляется сообщение об ошибке. Поскольку тип переменной $me был принудительно задан (Int32), Windows PowerShell попытался преобразовать строку "Don" в целое число. Это не удалось; также не удалось поменять тип переменной $me на String.

Типы переменных

В Windows PowerShell существует множество типов переменных. Более того, допустимо использование всех типов .NET Framework (количество таких типов исчисляется сотнями). Тем не менее, в Windows PowerShell имеются сокращенные имена для наиболее распространенных типов данных. На Рис. 2 приведен неполный список из 10-ти наиболее часто используемых сокращенных имен типов переменных. Полный список приведен в документации Windows PowerShell.

 Figure 2 Сокращенные имена типов переменных
Сокращенное имя Тип данных
[datetime] Время или дата
[string] Строка символов
[char] Один символ
[double] Число с плавающей запятой двойной точности
[single] Число с плавающей запятой одинарной точности
[int] Целое число, 32 бита
[wmi] Экземпляр или коллекция WMI
[adsi] объект служб Active Directory
[wmiclass] класс WMI
[Boolean] значения «Истина» или «Ложь»
Кроме того, вы можете объявлять тип переменных, используя полное имя класса .NET Framework, например:

Такой метод позволяет использовать типы .NET Framework, не имеющие сокращенных имен в Windows PowerShell.

Расширение типов

Расширение функций типов переменных — возможно, самая потрясающая особенность Windows PowerShell. В папке установки Windows PowerShell (как правило, расположенной в %systemroot\system32\windowspowershell\v1.0, но 64-битных системах ее расположение будет несколько иным) находится файл types.ps1xml. Этот файл можно редактировать в Блокноте или в XML-редакторе, например в PrimalScript. По умолчанию класса System.String в файле нет, несмотря на присутствие множества других типов переменных. Тем не менее, мы можем добавить новую функцию типу System.String, внеся его в файл types.ps1xml.

Чтобы изменения вступили в силу, необходимо закрыть и заново открыть Windows PowerShell. Также необходимо убедиться, что локальная политика выполнения сценариев допускает выполнение сценариев без подписи, поскольку мы не подписали файл types.ps1xml: Set-executionpolicy remotesigned Теперь, перезапустив Windows PowerShell, мы можем воспользоваться новыми функциями, например: PS C:\> [string]$comp = "localhost" PS C:\> $comp.canping True PS C:\>

Как видите, мы добавили свойство CanPing в класс System.String. На выходе мы получим True («Истина») или False («Ложь»), т.е. может ли локальный компьютер установить связь по адресу, содержащемуся в строке. На Рис. 3 мы видим, что в запросе WMI используется специальная переменная $this. В этой переменной содержится текущее значение строки и способ передачи содержимого строки в запрос WMI.

 Figure 3 Расширение типа System.String <Type> <Name>System.String</Name> <Members> <ScriptProperty> <Name>CanPing</Name> <GetScriptBlock> $wmi = get-wmiobject -query "SELECT * FROM Win32_PingStatus WHERE Address = '$this'" if ($wmi.StatusCode -eq 0) { $true } else { $false } </GetScriptBlock> </ScriptProperty> </Members> </Type>

Заключение

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

ystepanov.blogspot.com

powershell - Присвоение правильных типов переменных при чтении из файла конфигурации [PowerShell]

Я пытаюсь читать значения из текстового файла и хранить их в качестве переменных для использования в моем скрипте.

Этот файл конфигурации содержит строки, ints, booleans и массив, который может содержать строки, int и логические значения.

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

Это создает мой файл конфигурации в формате, который я хотел бы.

Function Create-Config() { If (!(Test-Path config.txt)) { $currentlocation=Get-Location $parentfolder=(get-item $currentlocation).parent.FullName New-Item config.txt -ItemType "file" Add-Content config.txt "SERVER_NAME=MyServer" Add-Content config.txt "SERVER_LOCATION=$currentlocation" Add-Content config.txt "BACKUP_LOCATION=$parentfolder\backup" Add-Content config.txt "CRAFTBUKKIT=craftbukkit.jar" Add-Content config.txt "JAVA_FLAGS=-Xmx1G" Add-Content config.txt "CRAFTBUKKIT_OPTIONS=-o True -p 1337" Add-Content config.txt "TEST_DEPENDENCIES=True" Add-Content config.txt "DELETE_LOG=True" Add-Content config.txt "TAKE_BACKUP=True" Add-Content config.txt "RESTART_PAUSE=5" }

}

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

Function Load-Variables() { Get-Content config.txt | Foreach-Object { $var = $_.Split('=') New-Variable -Name $var[0] -Scope Script -Value $var[1] } }

Как вы можете видеть, я не устанавливаю явно переменную, так как переменные из config имеют разные типы (booleans, int, array, string). Однако PowerShell импортирует все это как строки. Я могу импортировать все переменные отдельно (что, возможно, мне придется делать), но я все еще чувствую, что я буду застрять в массиве.

Если я объявляю массив, используя эту команду:

New-Variable -Name CRAFTBUKKIT_OPTIONS -Option Constant -Value ([array]@('-o',$true,'-p',25565))

Я получаю именно то, что хочу, но мне нужно импортировать его из файла конфигурации вместо объявления переменной в моем скрипте. Программа java немного лаконична, поэтому я не могу просто импортировать это значение в виде строки, иначе она не будет передана правильно, и эти параметры будут проигнорированы. Я нашел единственный способ, которым это работает, - иметь его как массив (как определено выше). Я также хочу отметить, что может быть много других опций файла конфигурации, чем в моем примере.

Я не уверен, какой лучший подход - импортировать переменные, которые будут объявлены правильно (что я хотел бы сделать), или предполагая, что они не могут быть импортированы как что-либо иное, кроме строки, а затем после этого разбора этой строки в соответствующие типы переменных.

Я попытался объявить переменные перед началом работы и с помощью команды Set-Variable установить значения, но это не сработает. Очень похоже, что мои переменные импортируются с Get-Content как строки с самого начала, а не из правильных типов.

Полный скрипт находится здесь: https://gist.github.com/TnTBass/4692f2a00fade7887ce4

qaru.site