пятница, 21 июня 2013 г.

Windows Powershell Возможности переменных

Windows Powershell Возможности переменных
Дон Джонс (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.

Сокращенное имя Тип данных
[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.

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

Комментариев нет:

Отправить комментарий