Windows Powershell Возможности переменных
Дон Джонс (Don Jones)
Дон Джонс (Don Jones)
Если вы работаете с языками сценариев на основе Windows, такими как VBScript или KiXtart, вы знаете, что переменная это просто удобное «приспособление» для хранения данных. В языке Windows PowerShell тоже есть переменные, но они, в отличие от переменных в более старых языках сценариев, предоставляют разработчикам куда больше возможностей.
Переменные PowerShell фактически сопоставимы с основными классами платформы Microsoft® .NET Framework. А в .NET Framework переменные являются объектами, а это значит, что с данными, хранящимися в переменных, можно производить различные операции. Именно благодаря огромным функциональным возможностям переменных, в языке сценариев Windows PowerShell™ отсутствуют встроенные функции обработки данных; в них не нужды — необходимая функциональность обеспечивается самими переменными.
Объявление переменных
Для объявления переменной и присвоения ей значения можно использовать командлет New-Variable, но можно поступить проще — создать переменную и присвоить ей значение:
$var = "Hello"
Имена переменных в 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:
$var | 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 имеет строковое значение, введите следующее:
$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 будет обрабатывать ее как переменную объявленного типа. Приведем пример:
[string]$var = 5
Переменная $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, например:
[System.Int32]$int = 5
Такой метод позволяет использовать типы .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 содержит универсальные и многофункциональные типы переменных, а также предлагает гибкую систему расширения их функций. Это позволяет с легкостью создавать сценарии с очень широкими возможностями. Переменные могут стать основными блоками в составных сценариях, выполняя работу гораздо более сложных по написанию функций.
Комментариев нет:
Отправить комментарий