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

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

И это еще не все

Смотрите наши веб-трансляции, которые проходят каждый второй вторник месяца, где вы сможете продолжить погружение в мир богатых возможностей сценариев Windows PowerShell. Посетите веб-узел microsoft.com/events/series/donjonesscripting.mspx (на английском языке), где вы можете зарегистрироваться прямо сейчас.

20-е февраля 2007г. Windows PowerShell: Интенсивный курс программирования

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

20-е марта 2007г. Windows PowerShell: Функции, фильтры и эффективность.

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

17-е апреля 2007г. Windows PowerShell и Инструментарий управления Windows (WMI)

Windows PowerShell дает возможность доступа ко всем мощным средствам WMI. Мы расскажем не только о том, как осуществляется доступ к средствам WMI посредством Windows PowerShell, но и о том, как передавать объекты и коллекции WMI по конвейеру Windows PowerShell. Мы продемонстрируем, как использовать методы и свойства WMI в сценариях Windows PowerShell, а также расскажем об основных функциях настройки и обеспечения безопасности WMI.

22-е мая 2007г. Windows PowerShell: Переход с VBScript на PowerShell

Хотите переписать ваши сценарии, или полностью перейти с VBScript на Windows PowerShell? В этой веб-трансляции мы расскажем, как это сделать. Мы покажем, что Windows PowerShell содержит все основные конструкции и возможности VBScript, благодаря чему вы с легкостью сможете применить ваши знания VBScript в новой среде управления. Мы продемонстрируем, как записать функции VBScript на языке сценариев Windows PowerShell. Мы познакомим вас с уникальной структурой Windows PowerShell и покажем, как язык Windows PowerShell может сделать вашу работу более продуктивной и эффективной.

June 19, 2007 Windows PowerShell: Расширенеие возможностей

Из этой трансляции вы узнаете, как с помощью Windows PowerShell воспользоваться мощными и универсальными средствами среды .NET Framework для управления данными — сотнями встроенных функций для обработки строк, дат и других типов данных. А знаете ли вы, что эти функции можно расширить с помощью сценариев Windows PowerShell? Мы расскажем, как создать строковую переменную, которая будет содержать данные не только об имени компьютера, но и о том, включен ли он в данный момент. Вы узнаете об автоматическом форматировании переменных времени и даты без применения внешних функций. Хотите узнать, как, встраивая самые различные новые функции в Windows PowerShell в течение нескольких минут, сделать администрирование Windows быстрее и проще? Смотрите нашу веб-трансляцию.

Дон Джонс (Don Jones) — директор по проектам и услугам компании SAPIEN Technologies и соавтор книги "Windows PowerShell: TFM" (изд. SAPIEN Press, 2006).trusted facility manual C ним можно связаться через веб-узел www.ScriptingAnswers.com.

© 2008 Корпорация Майкрософт и компания CMP Media, LLC. Все права защищены; полное или частичное воспроизведение без разрешения запрещено.