Опубликован: 12.01.2008 | Уровень: специалист | Доступ: платный | ВУЗ: Мордовский государственный университет имени Н.П. Огарева
Лекция 19:

Сценарии Windows PowerShell

< Лекция 18 || Лекция 19: 12
Цикл Foreach

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

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

Инструкция Foreach вне конвейера команд

В этом случае синтаксис цикла Foreach имеет следующий вид:

foreach ($элемент in $коллекция){блок_команд}

В круглых скобках указывается коллекция, в которой производится итерация. При выполнении цикла Foreach система автоматически создает переменную $элемент. Перед каждой итерацией в цикле этой переменной присваивается значение очередного элемента в коллекции. В разделе блок_команд содержатся команды, выполняемые на каждом элементе коллекции.

Например, цикл Foreach в следующем примере отображает значения в массиве с именем $letterArray:

PS C:\> $letterArray = "a","b","c","d"
PS C:\> foreach ($letter in $letterArray){Write-Host $letter}
a
b
c
d

В первой команде здесь создается массив $letterArray, в который записываются четыре элемента: символы "a", "b", "c" и "d". При первом выполнении инструкции Foreach переменной $letter присваивается значение, равное первому элементу в $letterArray ( "a" ), затем используется командлет Write-Host для отображения переменной $letter. При следующей итерации цикла переменной $letter присваивается значение "b" и т.д. После того, как будут перебраны все элементы массива $letterArray, произойдет выход из цикла.

Инструкция Foreach может также использоваться совместно с командлетами, возвращающими коллекции элементов. Например:

PS C:\> $l = 0; foreach ($f in dir *.txt) { $l += $f.length }
PS C:\> $l
2690555

Здесь сначала создается и обнуляется переменная $l, затем в цикле Foreach с помощью командлета dir формируется коллекция файлов с расширением txt, находящихся в текущем каталоге. В инструкции Foreach перебираются все элементы этой коллекции, на каждом шаге к текущему элементу (соответствующему файлу) можно обратиться с помощью переменной $f. В блоке команд цикла Foreach к текущему значению переменной $l добавляется значение поля length (размер файла) переменной $f. В результате выполнения данного цикла в переменной $l будет храниться суммарный размер файлов в текущем каталоге, которые имеют расширение txt.

Инструкция Foreach внутри конвейера команд

Если инструкция Foreach появляется внутри конвейера команд, то PowerShell использует псевдоним Foreach, соответсвующий командлету Foreach-Object. То есть в этом случае фактически выполняется командлет Foreach-Object и уже не нужно указывать часть инструкции ( $элемент in $коллекция ), так как элементы коллекции блоку команд предоставляет предыдущая команда в конвейере.

Синтаксис инструкции Foreach, применяемой внутри конвейера команд, в простейшем случае выглядит следующим образом:

команда | foreach {блок_команд}

Рассмотренный выше пример с подсчетом суммарного размера текстовых файлов из текущего каталога для данного варианта инструкции Foreach примет следующий вид:

PS C:\> $l = 0; dir *.txt | foreach { $l += $_.length }
PS C:\> $l
2690555

Замечание

Напомним, что специальная переменная $_ используется в командлетах, производящих обработку элементов конвейера, для обращения к текущему объекту конвейера и извлечения его свойств.

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

Синтаксис псевдонима Foreach, используемого в конвейере команд с начальным, средним и конечным блоками команд выглядит следующим образом:

команда | foreach {начальный_блок_команд}
  {средний_блок_команд}{конечный_блок_команд}

Для этого варианта инструкции Foreach наш пример можно записать следующим образом:

PS C:\> dir *.txt | foreach {$l = 0}{ $l += $_.length }{Write-Host $l}
2690555

Запуск сценариев PowerShell

Давайте запустим наш первый сценарий PowerShell. Для этого создадим с помощью Блокнота Windows текстовый файл test.ps1 и запишем в него одну строку:

Write-Host "Эта строка печатается из сценария PowerShell"

Сохраним этот файл в каталоге C:\Script. Как мы помним, сценарии WSH на языках VBScript или JScript можно было запускать из Проводника Windows, щелкая мышью на значках этих сценариев. Со сценариями PowerShell этот метод не работает – если дважды щелкнуть мышью на значке сценария PowerShell, то он не запустится, а откроется для редактирования в Блокноте (это позволяет предотвратить случайный запуск сценария).

Попробуем запустить созданный нами сценарий из оболочки PowerShell:

PS C:\> C:\script\test.ps1

Не удается загрузить файл C:\script\test.ps1, так как выполнение сценариев запрещено для данной системы. Введите "get-help about_signing" для получения дополнительных сведений.

В строка:1 знак:18
+ C:\script\test.ps1 <<<<

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

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

Политики выполнения сценариев

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

Возможные политики выполнения PowerShell описаны в табл. 19.1 (получить аналогичную информацию в PowerShell можно с помощью команды Get-Help about_signing ).

Таблица 19.1. Политики выполнения PowerShell
Название политики Описание
Restricted Данная политика выполнения используется по умолчанию, она запрещает выполнение сценариев и загрузку конфигурационных файлов (можно пользоваться только одиночными командами PowerShell в интерактивном режиме)
AllSigned Выполнение сценариев PowerShell разрешено, однако все сценарии (как загруженные из Интернета, так и локальные) должны иметь цифровую подпись надежного издателя. Перед выполнением сценариев надежных издателей запрашивается подтверждение
RemoteSigned Выполнение сценариев PowerShell разрешено, при этом все сценарии и файлы конфигураций, загруженные из Интернета (в том числе по электронной почте и с помощью программ мгновенного обмена сообщениями), должны иметь цифровую подпись надежного издателя, а локальные сценарии могут быть неподписанными. При запуске сценариев надежных издателей подтверждение не запрашивается
Unrestricted Разрешается выполнение любых сценариев PowerShell без проверки цифровой подписи. При запуске сценариев и файлов конфигураций, загруженных из Интернета, выдается предупреждение

Узнать, какая политика выполнения является активной, можно с помощью командлета Get-ExecutionPolicy:

PS C:\> Get-ExecutionPolicy
Restricted

Командлет Set-ExecutionPolicy позволяет сменить политику выполнения. Например, для установки политики выполнения RemoteSigned нужно выполнить следующую команду:

Set-ExecutionPolicy RemoteSigned

Проверим снова текущую политику:

PS C:\> Get-ExecutionPolicy
RemoteSigned

Теперь вновь попробуем запустить наш сценарий:

PS C:\> C:\script\test.ps1

Эта строка печатается из сценария PowerShell

Как мы видим, сценарий test1.ps1 успешно выполнен.

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

PS C:\> cd script
PS C:\script> dir

    Каталог: Microsoft.PowerShell.Core\FileSystem::C:\script

Mode                LastWriteTime     Length Name
----                -------------     ------ ----
-a---        09.12.2007     17:37         59 test.ps1

PS C:\script> test.ps1

Условие "test.ps1" не распознано как командлет, функция, выполняемая программа или файл сценария. Проверьте условие и повторите попытку.

В строка:1 знак:9
+ test.ps1 <<<<

Напомним, что для текущего каталога в системе зарезервировано имя . (точка). Сценарий в текущем каталоге запускается следующим образом:

PS C:\script> .\test.ps1

Эта строка печатается из сценария PowerShell

Для запуска сценария PowerShell непосредственно из командной строки интерпретатора Cmd.exe или с помощью пункта Выполнить (Run) меню Пуск (Start) нужно указать полный путь к этому сценарию после в качестве параметра программы powershell.exe, например:

C:\> powershell.exe C:\script\test.ps1
< Лекция 18 || Лекция 19: 12
Валентина Тюрина
Валентина Тюрина

Вопрос по лекции 7, где рассматривается взаимодействие со сторонними программами, в том числе эмуляция нажатия кнопок клавиатуры WshShell.SendKeys.

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

Можно вытащить информацию о объекте (кнопке) скажем с помощью AutoIt Info, или ориентироваться скажем на текст на кнопке..., но как на эту кнопку нажать? (без обхода по клавиатуре)

Александр Тагильцев
Александр Тагильцев

Где проводится профессиональная переподготовка "Системное администрирование Windows"? Что-то я не совсем понял как проводится обучение.