Ivan Sampovsky
10 янв
Автор
Т.е. в powershell я смогу собрать этот скрипт в отдельный файл? Пойду щас загуглю
Ответить
Развернуть ветку
Мудрый фитиль
10 янв
Интересует сортировка файлов по имени из имеющийся бд(обычный текстовик)
А можно не париться, импортнуть в xlsx и получить сортировки внутри экселя
Ответить
Развернуть ветку
Ivan Sampovsky
10 янв
Автор
ну мне именно файлы нужно отсортировать и по местам раскидать, хз как в таком сценарии excel юзать
Ответить
Развернуть ветку
Мудрый фитиль
10 янв
А, тогда да, просто выглядело как работа со списком файлов просто
Ответить
Развернуть ветку
Фабиус Байл
10 янв
Да, в винду даже встроена ide для powershell
Ответить
Развернуть ветку
Йожег-тян
10 янв
Мб я упрлс, но на го можно еще именно в силу того, что он в один экзешник компилируется.
Ответить
Развернуть ветку
Никто и никогда
10 янв
Бесполезный коммент. Можно и на JAVA, и на C++, и на Python… Вопрос был про скрипт, а не отдельную софтину писать.
Ответить
Развернуть ветку
Pick Up
10 янв
Именно твой коммент и является бесполезным. Иди читай, что такое скрипт, а потом что то пиши.
Ответить
Развернуть ветку
Никто и никогда
10 янв
Лол, ты щас разрабу будешь пояснять за скрипты и софт? Ну давай, нагугли мне чего я ещё не знаю. Или нагугли как на ГО написать скрипт чисто виндовыми средствами, чтоб запускать его из скедулера без компиляции.
Ответить
Развернуть ветку
Йожег-тян
10 янв
Ответ на этот, а так же на вопросы «как похудеть, поедая тортики на ночь?», «как выучить хаскель за 5 минут» в нашей новой книге «Никак!». Я всего лишь предположил, что если задача «написать на чем угодно, засунуть это в один файл, желательно экзешник, и запускать его на других машинах без лишних манипуляций», то это помимо всего прочего отличная задача для го.
Ответить
Развернуть ветку
Pick Up
10 янв
Мне то зачем гуглить? Если ты написал херню какую то, почему я должен гуглить?
Если ты считаешь что ты не можешь написать скрипт на любом языке, о чем с тобой разговаривать?
Ты явно не понимаешь, что такое скрипт, поэтому я и отправил тебя гуглить, в чем твоя проблема?
Ответить
Развернуть ветку
Никто и никогда
10 янв
Я знаю что такое скрипт и что можно его писать на чем угодно. Только вот проблема в том что в винде нет интерпретатора ГО, Джавы и т.д. чтобы сходу его запустить. Так что скриптом в голой винде это назвать — хуета.
Ответить
Развернуть ветку
Kristaller
10 янв
Го — компилируемый язык программирования. Ему не нужен внешний рантайим для запуска, но имхо, писать на нем скрипты для себя — гиблая идея, он для этого не предназначен.
Ответить
Развернуть ветку
Йожег-тян
10 янв
Смотря какие: залезть в БД, что-то оттуда вытащить, записать в файлы и т.п. — самое то.
Ответить
Развернуть ветку
Никто и никогда
10 янв
Ок, спасибо за ссылку, видимо я отстал немного, признаю, почитаю на досуге.
Ответить
Развернуть ветку
Мудрый фитиль
10 янв
Не стоит. WSL тащить для скриптинга под винду — совет из разряда «установите MySQL для ведения простого TODO-листа»
А конкретно с golang — там есть вещи, которые не работают нормально в винде, т.к. не под нее он делался
Тащить компилируемые языки для скриптинга — там уже ниже отписали, что идея тоже такое себе
Ответить
Развернуть ветку
Никто и никогда
10 янв
Ну вот я к тому же и вел, просто уже мозг плывет и пишу как даун. Начало года же, все по пизде пошло и сам щас весь скриптами обложился на работе.
Ответить
Развернуть ветку
Никто и никогда
10 янв
Чтобы норм работал там как минимум нужен вижуал, что уже костыль
Ответить
Развернуть ветку
Pick Up
10 янв
Ну, это уже другой вопрос, главное , что можно. Вопрос Нахера остаётся открытым
Я б ваще на повершелле написал, + vbs чтоб не палиться
Ответить
Развернуть ветку
Никто и никогда
10 янв
Ну да, это самый правильный вариант будет, согласен. Вот в споре и родили истину для ТСа.
Ответить
Развернуть ветку
Deckard
10 янв
Всл когда я последний раз проверял всё ещё требовал скачать дистрибутив.
Ответить
Развернуть ветку
Йожег-тян
10 янв
Да, хоть горшком назови, только в печку не ставь. Мне норм простенькие штуки иногда и в го пописать, благо там разувесистая стандартная библиотека и сторонних полно. Назвать эти поделки «отдельными софтинами» можно конечно, но см. выше.
Ответить
Развернуть ветку
Kristaller
10 янв
Питончик наше всё. Проще и мощнее, чем powershell, куча библиотек для всего и вся
Ответить
Развернуть ветку
Ivan Sampovsky
10 янв
Автор
Ну на питончике кншн прикольно, но я хз как на нём писать скрипты именно для работы в винде
Ответить
Развернуть ветку
Kristaller
10 янв
Ну, так же как и в любом другом месте. Файлы читать-писать можно, любую информацию у системы просить можно, даже биндинг для win32api есть, что ещё надо то?
Ответить
Развернуть ветку
Pick Up
10 янв
Пофиг на чем, главное выполнить цель, затем собрать в NSIS
Ответить
Развернуть ветку
Читать все 35 комментариев
С этой статьей вы не научитесь программировать и даже не напишите как таковую программу, но найдете здесь отличные VBS скрипты и BAT файлы, которые без проблем напишете в обычном блокноте Windows, сможете усовершенствовать по своему, потом похвастаться перед друзьями и близкими. Возможно это поднимет вам настроение и вы отлично проведете время.
Большинство похожих скриптов пишутся для удобства и автоматизации каких-либо действий на компьютере с ОС Windows. Представленные же ниже скрипты мало окажутся полезными (может мне так кажется), но они отлично подойдут для первоначального знакомства с «кодингом». Вы отлично проведете время, удивив как себя, так и знакомых чайников (не программистов), плюс это еще один хороший вариант убить время за компьютером.
Немного терминологии:
- VBS — язык программирования для создания скриптов в ОС Windows, создается/редактируется в Блокноте Windows, имеет разрешение «.vbs». Думаю, продолжать не имеет смысла, ибо это мало о чем скажет, особенно новичкам. Интересующимся — статья в Википедии.
- BAT — пакетный файл, в народе просто «батник». Расширение файла «.bat». Дальше аналогично — статья в Википедии.
Данных расширений (vbs, bat) файлы создаются во всеми известном Блокноте Windows (Notepad). Для большего удобства создания скриптов рекомендуется использовать усовершенствованный (скажем так) блокнот — Notepad++. Он удобен подсветкой синтаксиса большого количества языков программирования, если вам это мало о чем говорит, то скачайте и пишите в нем — ошибок сделаете меньше в коде, ну или будет их проще найти, чем в том же мало функциональном Блокноте Windows.
Скачать Notepad++ можно на официальном сайте.
Для наглядности пример (слева — Блокнот Windows, справа — Notepad++):
Приступим
Если вы уже знакомы с VBS скриптами и батниками, то скорее всего нижеследующие примеры вам будут неинтересны, если же вы новичок, то для первоначального ознакомления — то, что нужно.
Научим компьютер здороваться
- Открываем Блокнот (или Notepad Plus Plus).
- Копируем в вставляем код:
Set sapi=CreateObject(«sapi.spvoice»)
sapi.Speak «Hello!» - Обязательное условие: кавычки должны быть “такими”, «ёлочки» не подойдут, скрипт не будет обрабатываться и выйдет ошибка. Вместо слова «Hello» можете написать что угодно, даже по русски, при наличии русского голосового движка.
- Дальше выбираем Файл — Сохранить как — Тип файла — Все файлы — название.vbs
- Называйте файл как хотите, но не забудьте в конце прописать расширение — .vbs (пример — Privet.vbs).
- Теперь пробуйте проверить свой скрипт — запустите файл двойным щелчок мыши.
Один нюанс: если вы прописали в кавычках слова русскими буквами, а при запуске произносится непонятно что, то у вас просто не установлен русский голосовой движок. Подробная установка и настройка голосового движка выходит за рамки нашей статьи, поэтому более подробно ознакомьтесь здесь и вновь возвращайтесь сюда.
Теперь, сделаем следующее: пропишем данный скрипт в автозагрузку, а это означает то, что при запуске компьютера вам будет произнесено написанное в программе слово (слова), если как в примере, то будет говорить — «Hello» при каждом включении компьютера. Как это сделать?
Все просто, программу (скрипт) добавить в автозагрузку можно таким же образом, то есть через такой же VBS скрипт. Создаем файл в блокноте, копируем/вставляем (Ctrl+C/Ctrl+V) следующий код:
Dim vOrg, objArgs, root, key, WshShell
root = «HKEY_CURRENT_USERSoftwareMicrosoftWindowsCurrentVersionRun»
KeyHP = «Program»
Set WshShell = WScript.CreateObject(«WScript.Shell»)
WshShell.RegWrite root+keyHP,»C:Privet.vbs /autorun»
Изменяем путь до скрипта «говорилки», вот эту строчку — C:Privet.vbs на свою. Прописываем где у вас лежит этот скрипт и как называется. Дальше сохраняем только что созданную мини программу в блокноте и запускаем. Все, теперь компьютер будет с вами здороваться пр каждом включении.
Открыть дисковод
- Открыть блокнот. Скопировать/Вставить следующий код:
Set a = CreateObject(«WMPlayer.OCX.7»)
Set b = a.CdromCollection
Set c = b.Item(0)
Set d = c.Eject
- Сохранить с расширением .vbs
- Запустить скрипт и откроется дисковод.
Есть более интересная модификация данного скрипта:
Set WMPlayer = CreateObject(«WMPlayer.OCX.7»)
do
WMPlayer.CdRomCollection.Item(0).Eject()
loop
В данном случае будет все время открываться-закрываться CD/DVD-привод, на ноутбуках в этом случае будет открываться после каждого его закрытия.
Внимание! Второй код (открытие-закрытие дисковода), некоторые антивирусы видят как вредоносную программу. Антивирус Касперского (в т.ч. и Kaspersky Free) его видит именно так и уничтожает сразу же. В первом же случае (просто открытие дисковода) для антивирусных программ не является вредоносным скриптом.
Чтобы прекратить автоматически открывать-закрывать дисковод необходимо:
- Запустить диспетчер задач (комбинация клавиш Windows — Ctrl+Alt+Del).
- Перейти на вкладку «Процессы».
- Найти процесс wscript.exe — правая кнопка мыши — завершить процесс.
Игра
Интересная находка из Сети — игра на VBS. Необходимо угадать число от 0 до 100. Скрипт автоматически при запуске задает (разгадывает) число, которое вам необходимо угадать и ввести в специальном окошке, при неправильном ответе даются подсказки, например меньше или больше.
Ниже тот самый код который необходимо скопировать и вставить в блокнот, далее сохранить (расширение .vbs).
Вы также можете изменять сообщения по своему, все что написано кириллицей без проблем редактируется. Не бойтесь сломать код. Поэкспериментируйте. В случае чего заново скопируйте рабочий код отсюда.
Set y = CreateObject(«Scripting.FileSystemObject»)
Set y = Nothing
Do
a = 0
u = 0
Randomize
Number = Int((RND*99)+1)
MsgBox «Я загадал число от 1 до 100, попробуй отгадать»,64,»Угадайка»
Do
a = a + 1
c = InputBox(«Угадай число» & vbCrLf & vbCrLf & «Попытка: » & a & vbCrLf & vbCrLf & «Чтобы посмотреть результаты введите число !» & vbCrLf & vbCrLf & «Для выхода оставьте поле пустым» & vbCrLf & vbCrLf,»Угадайка»)
If c = «!» Then CreateObject(«WScript.Shell»).Run «notepad C:WindowsResult.dll»,3,True : Exit Do
If c <> «» Then
If IsNumeric(c) = True Then
If CInt(c) < Number Then MsgBox «Нет,это не » & c & «. Я загадал число больше»,64,»Угадайка»
If CInt(c) > Number Then MsgBox «Нет,это не » & c & «. Я загадал число меньше»,64,»Угадайка»
If CInt(c) = Number Then
Set y = CreateObject(«Scripting.FileSystemObject»)
MsgBox («Количество попыток: » & a)
If MsgBox («Правильно, это было число » & c & «. Начать заного?»,36,»Угадайка») = 6 Then Exit Do Else WScript.Quit
End If
Else
MsgBox «Это не число!»,16,»Угадайка»
a = a — 1
End If
Else
a = a — 1
l = MsgBox («Ты ничего не ввел. Выйти из программы?»,36,»Угадайка»)
If l = 6 Then WScript.Quit
End If
Loop
loop
Ну и перед тем как переходить к батникам (.BAT) воспользуемся самым полезным VBS скриптом из всех перечисленных в этой статье.
Скрипт закрывающий wscript.exe
Сам скрипт:
Set TaskKill = CreateObject(«WScript.Shell»)
TaskKill.Run «TaskKill /f /im wscript.exe»
По сути он делает тоже самое, что чуть выше объяснялось в диспетчере задач, как например нельзя просто взять и закрыть надоедливый скрипт открывающий-закрывающий дисковод, а запустив данный скрипт все запущенные будут закрыты. Это как клин клином вышибают.
Немного познакомились с VBS скриптами и о том как их писать в блокноте, теперь рассмотрим несколько примеров использования BAT файлов (далее — батник).
Завершение работы /Перезагрузка компьютера
Совсем простой батник состоящий всего из одной строки.
- Открываем Блокнот.
- Пишем следующий код:
shutdown -s -t 1 -c -f
- Далее Файл — Сохранить как — нзвание.bat
- Обратите внимание на расширение файла, это уже не VBS скрипт, а батник, по этому в конце названия прописываем .bat (Пример compoff.bat).
- Запускаем только что созданный батник двойным щелчком мыши и компьютер выключится (Завершение работы).
Есть такой вариант кода:
shutdown -r -t 1 -c -f
Все также, прописываем в блокноте, сохраняем с расширением .bat и после запуска компьютер перезагрузится (обычная перезагрузка компьютера).
Удаление обновлений
Данный батник пригодится в том случае, если вы уже обновились до Windows 10. В чем суть? В этом батнике перечислены команды по удалению нескольких обновлений, как видно из названия — обновления телеметрии, или как раз одна из шпионских штучек системы, мы однажды уже говорили как отключить функции слежки Windows 10, в данном же случае вы просто создаете батник, в содержимое копируете код ниже и запускаете, после чего будут удалены перечисленные обновления.
@echo
echo
echo Step 1: Delete Updates Telemetry
wusa /uninstall /kb:3068708 /quiet /norestart
wusa /uninstall /kb:3022345 /quiet /norestart
wusa /uninstall /kb:3075249 /quiet /norestart
wusa /uninstall /kb:3080149 /quiet /norestart
Таким образом можно удалить абсолютно любое обновление, даже назойливое KB971033 которое проверяет копию Windows 7 на подлинность.
В Интернете встречается много различных скриптов, якобы безвредных, но будьте осторожны, прежде чем пробовать непонятно какой скрипт, некоторые из них могут навредить, например — вносить изменения в реестр, а в случае каких ошибок система будет выдавать ошибки, в таком случае придется или восстанавливать реестр Windows или сделать восстановление системы.
Сегодня поговорим об очень полезном компоненте операционной системы Windows — это Windows Script Host, если быть конкретней, то о языке Jscript, на котором можно писать эти самые WSH скрипты.
Начнем мы с небольшой теории, так как мы еще не затрагивали Windows Script Host.
Содержание
- Что такое Windows Script Host?
- Возможности Windows Script Host
- Примеры написания WSH скриптов
- Выводим сообщение на JScript
- Работа с Excel на JScript
- Работа с текстовым файлом и Excel на JScript
Что такое Windows Script Host?
Windows Script Host – сервер выполнения сценариев (скриптов) на таких языках как VBScript и JScript. WSH разработан компанией Microsoft и он является компонентом операционной системы Windows начиная с Windows 98.
Первоначально для администрирования использовались только bat-файлы, но их возможности ограничены (хотя также очень полезны!), поэтому компания Microsoft предложила такой вариант WSH. Возможности WSH-скриптов уже гораздо больше, ведь данные скрипты уже создаются на полноценных языках, таких как VBScript и JScript.
Именно о JScript мы сегодня и поговорим.
Но о VBScript мы тоже скажем пару слов.
VBScript – это скриптовой язык программирования, созданный компанией Microsoft для разработки скриптов в операционной системе Windows. Другими словами, это один из языков, которые может интерпретировать Windows Script Host. И из названия ясно, что VBScript основан на языке Visual Basic, поэтому тем, кто знаком с Visual Basic будет просто писать WSH-скрипты на этом языке программирования.
JScript – скриптовой язык программирования, с помощью которого можно создавать (писать) скрипты, которые будут интерпретироваться компонентом Windows Script Host.
С первого взгляда JScript во многом похож на JavaScript (ECMAScript), это и естественно, так как синтаксис, некоторый объекты, методы, свойства аналогичны JavaScript. Но это все же не JavaScript, а именно JScript. JavaScript (ECMAScript) ориентирован на объекты браузера, а JScript уже на компоненты операционной системы Windows. Но как мы сказали, они похожи, поэтому те, кто владеют языком программирования JavaScript с легкостью перейдут на JScript.
Возможности Windows Script Host
А теперь давайте поговорим о том, зачем нам нужно писать эти самые WSH-скрипты, т.е. об их возможностях и преимуществах:
- Возможность взаимодействия с файловой системой (файлы, каталоги), системным реестром, ресурсами локальной сети;
- Взаимодействие с такими продуктами как Microsoft Word, Excel и другими программами. Т.е. например, мы можем создавать excel файлы или конвертировать другие форматы в excel файлы;
- Взаимодействие с ActiveX-технологиями, например: ActiveX Data Object (ADO) — доступ к базам данных разных форматов, Active Directory Service Interface (ADSI) — работа со службами каталогов Active Directory;
- Наличие полноценного языка программирования, с помощью которого можно реализовывать сложные алгоритмы, которые например нельзя реализовать с помощью bat файлов.
Скрипты на JScript имеют расширение .js такое же, как и на JavaScript за исключением того, что эти скрипты обрабатывает не браузер, а Windows Script Host.
На JScript возможно даже реализация графического интерфейса через объект браузера (internet explorer), согласитесь это уже полноценная программа.
Перейдем к практике, так как у нас сегодня статья по основам, мы рассмотрим простые примеры написание скриптов на JScript.
Примечание! Для того чтобы попробовать примеры ниже скопируйте код любого примера в текстовый файл и сохраните с расширением .js, например, test.js.
Выводим сообщение на JScript
В WSH имеется специальный объект, на основе которого мы уже можем в дальнейшем создавать другие объекты, настраивать взаимодействие с программами, файлами и другими компонентами операционной системы.
Этим объектом является WScript. Пример его использования на Jscript:
var WshShell = WScript.CreateObject("WScript.Shell");
Тем самым мы создали объект, с помощью которого мы можем получить доступ к компонентам Windows.
Например, вывести сообщение:
//Выводим сообщение WshShell.Popup( "Моя первая программа на JScript"); //Завершаем работу с объектом WScript.Quit();
Работа с Excel на JScript
Теперь давайте создадим другой объект, например, Excel файл:
// создаем объект для работы с Excel var Excel = WScript.CreateObject("Excel.Application"); // добавляем книгу в Excel Excel.WorkBooks.Add; //добавляем в первую ячейку нужный текст Excel.Cells(1,1).Value ="Мой текст для вставки в Excel"; // делаем активным наш Excel документ Excel.Visible = true;
Как Вы понимаете, мы имеем доступ ко всем свойствам в Excel, другими словами, мы можем изменить внешний вид, задать формат ячеек и многое другое. Для примера давайте поэкспериментируем с некоторыми свойствами:
//создаем объект для работы с Excel var Excel = WScript.CreateObject("Excel.Application"); //добавляем книгу в Excel Excel.WorkBooks.Add; //выделяем нужный нам диапазон Excel.Range("A1:C1").Select; //объединяем ячейки в нашем диапазоне Excel.Selection.MergeCells = true; //добавляем нужный текст Excel.Selection.Value ="Мой текст для вставки в Excel"; //делаем наш текст жирным Excel.Selection.Font.Bold = true; //изменяем в 4 ячейке формат данных на числовой с двумя знаками после запятой Excel.Cells(1, 4).NumberFormat = "00.00" //вставляем в 4 ячейку нашу цифру Excel.Cells(1, 4).Value = 1234; //выровняем по центру наше значение Excel.Cells(1, 4).HorizontalAlignment = 3; //делаем активным наш Excel документ Excel.Visible = true;
Работа с текстовым файлом и Excel на JScript
Я думаю с Excel все понятно, теперь давайте прочитаем какие-нибудь данные из текстового файла и запишем их в нашу Excel таблицу, для закрепления наших знаний.
Для того чтобы настроить взаимодействие с файловой системой, необходимо создать объект FileSystemObject, который работает с файлами и каталогами. Вот пример небольшого скрипта, который считывает данные из текстового файла построчно и записывает их в Excel документ, причем мы все строки пронумеруем и зададим ширину столба для данных в Excel:
Пример текстового файла:
Первая строка Вторая строка Третья строка
Пример скрипта:
//создаем объект FileSystemObject var FileSysObj = WScript.CreateObject("Scripting.FileSystemObject"); //объявляем нужные нам переменные var nRow = 1, num=1; var txt = ''; //открываем файл my.txt в той же папке, параметр 1 для чтения файла var myText = FileSysObj.OpenTextFile('my.txt', 1 ); //как и раньше создаем объект для работы с Excel var Excel = WScript.CreateObject("Excel.Application"); //добавляем книгу в Excel Excel.WorkBooks.Add; //циклом считываем строки из файла, пока они не закончатся // и записываем их в наш Excel документ while (!myText.AtEndOfStream) { //считываем строку txt = myText.ReadLine(); //нумеруем наши строки в Excel Excel.Cells(nRow, 1).Value = num; //выставляем ширину вторго столбца Excel.Columns(2).ColumnWidth = 15; //записываем данные в ячейку Excel.Cells(nRow, 2).Value = txt; //увеличиваем переменные на 1 nRow++; num++; } //закрываем файл myText.Close(); //делаем активным наш Excel документ Excel.Visible = true; //выходим из скрипта WScript.Quit();
Как всегда весь код я прокомментировал, поэтому неясностей возникнуть не должно.
Я думаю для начала этого вполне достаточно, в дальнейшем мы будем разбирать задачи посложней, ведь при помощи Jscript в WSH можно очень много чего сделать, гораздо больше, чем с помощью простых bat файлов. До встречи!
Написание скриптов Windows Power Shell
(обзор языка)
Вы уже знаете, что в простейшем смысле сценарий Windows PowerShell представляет собой цепочку последовательных команд, которые выполняются в порядке строгой очередности. Сценарий такого типа во многом схож с командными файлами или пакетными скриптами, которые используются в большинстве других оболочек, включая Cmd.exe в Windows. На более сложном уровне сценарии Windows PowerShell могут напоминать программы, написанные на таких языках как Microsoft Visual Basic Scripting Edition (VBScript), JavaScript, JScript, Perl и так далее. При необходимости можно создавать такие сценарии, которые будут предугадывать и исправлять конкретные ошибки – в этом случае вам потребуется потратить немало времени на настройку ваших скриптов, чтобы добиться их безупречной работы. Также сценарии можно моделировать, составляя их из отдельных блоков, чтобы использовать тот или иной блок в конкретной ситуации. В данном модуле вы узнаете, как использовать эти более сложные скриптовые элементы.
Поскольку большая часть функций в оболочке выполняется с помощью проблемно-ориентированных командлетов, ее скриптовый язык в действительности является очень простым и состоит из относительно небольшого количества (менее двух десятков) ключевых слов и конструкций.
Хранение данных
Вы уже сталкивались с переменными, которые используются в Windows PowerShell, в предыдущих модулях. В рамках данного занятия вы узнаете больше о том, что они собой представляют, как работают и для чего используются. Также вы ознакомитесь с родственными тематиками, такими как «массивы» и «дополнительные операции».
Переменные
Задумайтесь на минуту о ярлыках в Windows Explorer. Вам, несомненно, приходилось создавать ярлыки для файлов и папок, а меню «Пуск» представляет собой нечто большее, нежели просто набор папок и ярлыков. Ярлыки обладают несколькими важными признаками:
• У них есть свойства, такие как текущий каталог, который устанавливается, когда ярлык открыт и путь файла, на который ярлык указывает.
• Ими можно манипулировать: перемещать, удалять, копировать, и.т.д.
• Сами по себе ярлыки не представляют интереса – они лишь указывают на что-либо, представляющее интерес (приложение или документ).
• Они указывают на то, что физически хранится в определенном месте.
В Windows PowerShell переменная выполняет функцию, схожую с функцией ярлыков. Несмотря на то, что переменная сама по себе является объектом, наибольший интерес представляет то, на что она указывает. Переменные выступают в роли ярлыка чего-либо, что хранится в памяти оболочки – строки, числа, объекта или даже группы объектов.
Как и большинство динамически создаваемых элементов в оболочке, переменная существует только до тех пор, пока текущая сессия оболочки не завершена. Windows PowerShell создает диск variable:, на котором хранятся все переменные, которые были определены в оболочке. Этот диск содержит не только переменные, которые вы создаете, но и огромное количество переменных, которые определяются оболочкой и используются для хранения параметров конфигурации, влияющих на поведение оболочки. Оболочка предоставляет множество командлетов для управления переменными: увидеть их все можно, запустив команду:
Get-Command –noun variable
Однако во многих случаях вам не придется использовать эти командлеты. Помимо них, оболочка предлагает специальный синтаксис, который позволяет определять и модифицировать переменные без использования командлетов. Также для управления переменными можно использовать диск variable:, например, вы можете удалить элемент с диска, чтобы удалить соответствующую переменную из памяти.
Имена переменных обычно состоят из букв, цифр и символа нижнего подчеркивания. Имя переменной не включает символ $. Этот символ выполняет функцию ключа, который указывает оболочке, что то, что идет вслед за ним, является именем переменной. Когда вы передаете имя переменной параметру командлета, который ожидает получить имя переменной, символ $ указывать не нужно:
Remove-Variable –name var
Если вы поставите символ $ перед именем переменной, оболочка передаст параметру содержимое этой переменной:
$var = ‘computername’
Remove-Variable –name $var
Данная команда удалит переменную $computername, а не переменную $var.
Имена переменных могут содержать пробелы и другие символы, но для этого имя следует заключить в фигурные скобки:
${My Variable} = 5
Использование пробелов считается не самым лучшим решением, так как использование фигурных скобок увеличивает объем работы при наборе команды и затрудняет чтение скрипта в дальнейшем.
Windows PowerShell использует знак равенства (=) в качестве оператора присваивания. Это означает, что все, что находится справа от этого знака, является значением того, что находится справа:
$var = 5
Оболочка позволяет создавать новые переменные путем придания того или иного значения переменной, как в примере выше. При этом нет необходимости объявлять переменную заранее, до присвоения ей значения.
На заметку: Если вы знакомы с VBScrip, у вас может возникнуть вопрос, есть ли здесь эквивалент Option Explicit. Об этом мы поговорим чуть позже.
К переменной можно привязать любой объект или группу объектов:
$services = Get-Service
Переменная будет хранить свое содержимое до тех пор, пока вы не замените его, не закроете оболочку, либо не удалите переменную.
Вы можете создавать и использовать переменные в оболочке, ссылаясь на переменную:
$var = 100
$var
$var = «Hello»
Обратите внимание, что очистка переменной – это не то же самое, что ее удаление. В следующем примере переменная $var существует, но имеет нулевое значение:
$var = 100
$var = »
$var = $null
Также вы можете создавать, устанавливать и удалять переменные с помощью командлетов:
New-Variable –name var –value (Get-Process)
Set-Variable –name var –value $null
Clear-Variable –name var
Remove-Variable –name var
Последняя команда в данном примере в действительности удаляет переменную. Вы можете убедиться в этом, запустив команду:
Get-Variable
Или изучив содержимое диска variable:
Dir variable
Переменные могут передаваться по конвейеру другим командлетам; при этом в действительности передаются не сами переменные, а их содержимое:
$services | Sort Status | Select –first 10
И, наконец, переменная обеспечивает доступ к элементам объекта – свойствам и методам. Для этого необходимо обращаться с переменной, как с объектом: после ее имени ставить точку, а далее указывать имя элемента, к которому вы хотите получить доступ:
$wmi = Get-WmiObject Win32_OperatingSystem
$wmi.Caption
$wmi.Reboot()
Строки
Оболочка позволяет использовать как одинарные, так и двойные кавычки для определения границ строки. В большинстве ситуаций можно использовать любой тип кавычек. В следующем примере обе команды будут идентичными с функциональной точки зрения:
$var = «Hello»
$var = ‘World’
Ключевым различием здесь будет то, что при использовании двойных кавычек оболочка начинает искать символ $. Когда она находит этот символ, она решает, что все последующие символы, вплоть до пробела, являются именем переменной и заменяет всю переменную ее содержимым. Следующий пример иллюстрирует это различие:
PS C:> $var = ‘Hello’
PS C:> $var2 = «$var World»
PS C:> $var3 = ‘$var World’
PS C:> $var2
Hello World
PS C:> $var3
$var World
Как правило, двойные кавычки используются только в тех случаях, когда вам действительно необходима функция замещения переменной. Во всех остальных случаях принято использовать одинарные кавычки.
Как и во многих других оболочках, в Windows PowerShell есть символ перехода (экранирующий символ). Под символом перехода подразумевают обратный апостроф или `. На английской клавиатуре этот символ обычно расположен вверху слева под или рядом с клавишей Esc или Escape, как правило, на одной клавише со знаком тильды (~), но на других клавиатурах его расположение может варьироваться. По ссылке, указанной ниже, можно посмотреть раскладку клавиатуры в разных странах.
На заметку: при использовании некоторых шрифтов бывает сложно отличить обратный апостроф ` от обычного ‘. Старайтесь не путать их. Обратный апостроф может отменять особенное значение символов, которые идут вслед за ним. Например, в Windows PowerShell символ пробела имеет особое значение и используется в качестве разделителя. Однако при использовании обратного апострофа пробел теряет это значение и превращается в обычный буквенный символ:
Cd c:program` files
Вы уже знаете, что символ $ имеет особое значение, и что оболочка ищет его внутри двойных кавычек для выполнения функции замещения переменной. Попробуйте отменить это особое значение – и вы получите просто знак доллара:
PS C:> $var = ‘Hello’
PS C:> $var2 = «$var World»
PS C:> $var3 = «`$var contains $var»
PS C:> $var2
Hello World
PS C:> $var3
$var contains Hello
Символ перехода может даже отменить особенное значение перехода каретки в исходное положение, которое обычно используется для определения логических границ строки:
$var = «This `
is a `
singe line»
Однако, как правило, этот метод не нужен, так как оболочка автоматически определяет, как правильно проанализировать такую многострочную команду.
И, наконец, символ перехода может придавать особенные значения отдельным символам, которые обычно не имеют никакого значения. Например, `t может обозначать табуляцию, `n – новую строку, `r – возврат каретки в исходное положение, и.т.д. Более подробную информацию обо всех возможных значениях можно найти в соответствующем разделе справочника.
Ссылка: Windows International Keyboard Layouts, http://go.microsoft.com/fwlink/?LinkId=200517.
Массивы
Массив – это переменная, которая содержит более одного объекта. Например:
$var = 5
В данном примере $var не является массивом, так как она содержит всего один объект – число 5. Однако данная команда помещает массив объектов в переменную.
$var = Get-Service
В области разработки программного обеспечения существует отчетливое различие между массивом значений и набором объектов. Windows PowerShell абстрагируется от этих отличий, поэтому, во многих случаях термины «массив» и «набор» будут означать одно и то же. Оболочка автоматически воспринимает любой список, элементы которого разделены запятой, как массив:
$myarray = 1,2,3,4,5,6,7,8,9,0
Существует и более формальный способ обозначения новой переменной: использование символа @ и заключение списка значений в круглые скобки:
$myarray = @(1,2,3,4,5,6,7,8,9,0)
Функциональной разницы между этими двумя способами создания массива нет.
Работая с массивом, можно использовать порядковые номера для того, чтобы ссылаться на отдельные элементы. Первый объект в массиве имеет порядковый номер (индекс) 0. Использование индексов с отрицательным значением обеспечивает доступ к объектам с конца: -1 будет обозначать последний объект, -2 – предпоследний, и.т.д:
$services = Get-Service
$services[0]
$services[1]
$services[-1]
Массивы также обладают свойством Count, которое показывает количество объектов в массиве:
$services.count
Хеш-таблица
Вы уже знаете, как использовать хеш-таблицы с такими командлетами, как Select-Object и Format-Table. Хеш-таблица представляет собой разновидность массива. Каждый элемент в этом массиве состоит из ключа и значения, формируя пару ключ-значение. Например, когда вы использовали хеш-таблицу с командлетом Select-Object, вы имели два элемента: Lable (ключ) и Expression (значение):
Get-Process | Select @{Label=’TotalMem’;Expression={$_.VM + $_.PM}}
Символ @ в сочетании с фигурными скобками используется для создания хеш-таблицы. Когда вы создаете свою хеш-таблицу, вы можете использовать любые ключи и значения – ваш выбор не ограничивается только Label и Expression. После того, как вы создали хеш-таблицу, вы можете использовать ключи для извлечения значений:
PS C:> $hash = @{«Server1″=»192.168.15.4″;»Server2″=»192.168.15.11»;
«Server3″=»192.168.15.26»}
PS C:> $hash.Server1
192.168.15.4
Символ @ используется в качестве оператора для создания как массивов, так и хеш-таблиц (которые, также, называются ассоциативными массивами); в простых массивах перечень значений указывается в скобках, тогда как в хеш-таблицах используются пары ключ-значение в фигурных скобках. Обращайте внимание на это различие. Хеш-таблица, как и любой массив, имеет свойство Count:
$hash.count
Вы можете передать объекты хеш-таблицы по конвейеру командлету Get-Member, чтобы увидеть другие свойства и методы.
Сплаттинг
Сплаттинг (Splatting) – это способ перемещения параметров и значений в хеш-таблицу и дальнейшей передачи всей хеш-таблицы командлету. Данная техника может быть полезной для передачи динамически создаваемых параметров командлетам. Для начала создаем обычную хеш-таблицу, где в качестве ключей выступают имена параметров, а в качестве значений – значения этих параметров:
$parms = @{«ComputerName»=»Server-R2»;
«Class»=»Win32_BIOS»;
«Namespace»=»rootcimv2»
}
Затем используем символ @ в качестве сплат-оператора (оператора подстановки) и имя переменной без символа $ для передачи этой хеш-таблицы командлету:
Get-WmiObject @parms
Командлет работает как обычно, принимая имена параметров и значения из хеш-таблицы.
На заметку: Различные примеры использования символа @ могут сбить с толку. Его конкретное предназначение зависит от контекста, в котором он используется, но в любом случае, его использование так или иначе связано с массивами или хеш-таблицами (ассоциативными массивами).
Арифметические операторы
Арифметические символы используются для осуществления подсчетов в оболочке. Они оцениваются оболочкой в соответствии со стандартными правилами в порядке старшинства:
• Умножение (*) и деление (/) слева направо
• Сложение (+) и вычитание (-) слева направо
• Выражения в скобках рассчитываются слева направо и изнутри наружу.
Оболочка распознает такие величины как Кб, Мб, Гб и Тб. Кб равен 1,024, Мб — 1,048,576 и.т.д. Обратите внимание, что эти значения являются двоичными, а не десятичными (это означает, что 1 Кб не равняется ровно 1000). Символ + также является оператором для сцепления строк:
$var1 = «One »
$var2 = «Two»
$var3 = $var1 + $var2
$var3
One Two
Типы переменных
Обычно оболочка позволяет помещать в переменную объекты любого типа. Если вы выполняете операцию, которая требует особого типа объектов, оболочка пытается временно конвертировать или принудительно преобразовать объекты в необходимый вид. Например:
PS C:> $a = 5
PS C:> $b = «5»
PS C:> $a + $b
10
PS C:> $b + $a
55
Переменная $ — это целое число, однако, переменная $b – это строка, так как ее значение было ограничено кавычками. В данном примере конструкция $a + $b дает в результате 10. Объект в $b был временно конвертирован в целое число, чтобы арифметическая операция была успешно завершена. Оболочка самостоятельно решила сделать это, так как первая переменная содержала целое число, а вторая содержала объект, который не мог быть воспринят как целое число.
В примере $b + $a можно наблюдать обратную ситуацию. Оболочка сначала «увидела» строку, после чего скорректировала вторую переменную, превратив ее в подходящую для сцепления строк форму.
Такое поведение оболочки может иногда сбить с толку и привести к неожиданным результатам. Решением проблемы может стать детальное информирование оболочки о том, какой тип объекта вы планируете использовать в переменной. Это делается путем уточнения имени типа .NET Framework в квадратных скобках:
PS C:> [int]$a = «5»
PS C:> $a | gm
TypeName: System.Int32
В данном примере, несмотря на то, что «5» – это строка, оболочка в принудительном порядке конвертировала ее в целое число, чтобы поместить в переменную $a. Если бы конвертация была невозможна, вы увидели бы ошибку:
PS C:> $a = «Hello»
Cannot convert value «Hello» to type «System.Int32». Error: «Input string was not in a correct format.»
После того, как вы указали тип объектов для переменной, оболочка будет учитывать это до тех пор, пока вы не измените указания:
PS C:> [string]$a = «Hello»
Наиболее распространенными видами объектов являются:
• String (строка)
• Int (integer) (целое число)
• Single и Double (плавающие числа)
• Boolean (Булев или логический тип данных)
• Array (Массив)
• Hashtable (хеш-таблица)
• XML
• Char (одинарный символ).
При написании сценариев считается оптимальным указывать тип объектов вручную. Это позволяет избежать ошибок и неожиданных результатов и упрощает настройку скрипта.
Сложные операторы сравнения
Вы уже знаете о базовых сравнительных операторах, таких как –eq и –gt. Но помимо них, оболочка предлагает ряд дополнительных операторов:
Оператор –contains позволяет узнать, содержится ли тот или иной объект в массиве. При этом он не просто сравнивает строки, например, он не скажет, содержит ли строка “Server1” подстроку “ver”. Вместо этого, происходит проверка всего объекта целиком:
$collection = «One»,»Two»,»Three»
$collection –contains «One»
Оператор –contains сравнивает более сложные объекты, изучая все свойства этих объектов. Чтобы использовать обратную логику и проверить, действительно ли массив не содержит тот или иной объект, используется оператор –notcontains.
Оператор –like производит сравнение с использованием подстановочного знака и обычно нечувствителен к регистру.
$var = «Server1»
$var –like «server*»
Чувствительной к регистру является версия –clike. Опять же, для использования обратной логики применяются операторы –notlike и –cnotlike. Все четыре оператора в качестве подстановочного знака используют *.
Оператор –is определяет, относится ли объект к определенному типу:
$var = «CONTOSO»
$var –is [string]
Тесно связан с ним оператор –as, который пытается конвертировать данный объект в объект другого типа. Если конвертация невозможна, он обычно выдает пустое значение, такое как пустая строка или ноль:
PS C:> $var = «CONTOSO»
PS C:> $var2 = $var -as [int]
PS C:> $var2
PS C:>
Области действия
Как и многие другие языки программирования и скриптовые языки, Windows PowerShell поддерживает иерархию областей действия. Эта иерархия контролирует то, когда и где те или иные элементы будут видимы и пригодны, а также как к этим элементам можно обратиться или изменить их. Поскольку правила области действия функционируют всегда, даже когда вы не догадываетесь об этом, использование оболочки без понимания, что такое область действия может привести к путанице и неожиданным ошибкам.
Область действия разработана для того, чтобы обозначать границы вокруг выполняемых элементов в оболочке. При правильном использовании она предотвращает нежелательное взаимодействие элементов и обеспечивает большую независимость элементов.
Область действия верхнего уровня в оболочке называется глобальной. Когда вы работаете непосредственно в командной строке, а не в сценарии, вы работаете в глобальной области действий. Эта область действий содержит определенные псевдонимы, отображения PSDrive, переменные и даже определенные функции. Все остальные области являются «детьми» или «внуками» (или даже «правнуками») глобальной области действий. Новая область действий появляется каждый раз, когда вы запускаете сценарий или выполняете функцию. Это может привести к образованию огромного количества вложенных областей и разветвленной иерархии. Например, представьте, что вы:
• Запустили сценарий;
• Сценарий содержит функцию;
• Функция выполняет другой сценарий
Этот последний сценарий будет уже областью действий четвертого поколения: глобальная область действия – область действия для первого сценария, область действия для функции – область действия для второго сценария.
Области действия «живут» столько, сколько необходимо – когда выполнение сценария заканчивается, его область действия разрушается или удаляется из памяти. Области действия создаются для следующих элементов оболочки:
• Переменные
• Функции
• Псевдонимы
• PSDrives
Оболочка устанавливает по умолчанию ряд правил, касающихся областей действия.
• Как только доступ к элементу получен, оболочка проверяет, существует ли этот элемент в рамках текущей области действия. Если да – оболочка использует этот элемент.
• Если элемент не существует в текущей области действия, оболочка обращается к «родительской» области действия и ищет элемент уже там.
• Таким образом, оболочка проверяет все области действия по восходящей до тех пор, пока элемент не будет найден. Если элемент не обнаружен в глобальной области действий, значит он не существует.
Например, представьте, что вы запустили сценарий, содержащий всего одну команду:
Gwmi win32_service
Каждая область действия начинает работу в виде пустой, «свежей» сессии. Вы не указали псевдоним Gwmi в этой области действия, поэтому, когда вы используете его, оболочка обращается к «родительской», глобальной области действия, чтобы проверить, существует ли этот псевдоним там. По умолчанию он существует, и оболочка использует псевдоним Gwmi, который указывает на Get-WmiObject. Такое поведение области действия является причиной того, что все псевдонимы, PSDrive диски и переменные, присутствующие в оболочке по умолчанию, работают в вашем сценарии: они обнаруживаются в глобальной области действия.
Поведение меняется, когда вы изменяете элемент. Обычно оболочка не позволяет изменять элементы в «родительской» области действия из «дочерней» области действия. Вместо этого элементы создаются в текущей области действия. Например, вы запускаете следующую команду из командной строки, то есть, из глобальной области действия:
$var = 100
Вы получаете переменную $var внутри глобальной области действия, и эта переменная содержит целое число 100. Иерархия области действия будет выглядеть так:
• Global: $var = 100
Далее вы запускаете сценарий, который содержит следующее:
Write $var
Эта область действия не содержит переменную $var, поэтому, оболочка обращается к «родительской» области действия – глобальной. Переменная $var обнаруживается там, поэтому, целое число 100 возвращается в сценарий и сценарий выдает 100 в качестве выходных данных. Предположим, далее вы запустили сценарий, который содержит следующее:
$var = 200
write $var
Переменная $var сейчас создается в области действия сценария, и целое число 200 помещается в нее. Иерархия области действия сейчас выглядит так:
• Global: $var = 100
• Script: $var = 200
Новая переменная с именем $var сейчас была создана в области действия сценария, но переменная в глобальной области действия осталась неизменной. Сценарий выдает в качестве выходных данных 200, так как $var содержит именно это число. Это не влияет на глобальную область действия. Если, после того как сценарий будет выполнен, вы запустите из командной строки команду:
Write $var
Выходными данными будет являться число 100, так как переменная $var в глобальной области действия содержит именно его. Такая модель поведения относится ко всему, что создается в «дочерней» области действия. Здесь необходимо запомнить два базовых правила:
• Если вы читаете что-либо, не существующее в текущей области действия, оболочка пытается извлечь это из «родительской» области действия.
• Если вы пишете что-либо, то это всегда создается в текущей области действия, даже если в «родительской» области действия есть элемент с аналогичным именем.
Запомните следующие общие правила:
• «Дочерняя» область действия может ЧИТАТЬ элементы, находящиеся в «родительской» области действия.
• «Родительская» область действия никогда не сможет прочитать или написать что-либо в «дочерней».
• Вы можете ПИСАТЬ только в текущей области действия.
• Если вы пытаетесь поменять что-либо в родительской области действия, результатом будет появления нового элемента с таким же именем в текущей области действия.
Windows PowerShell не запрещает изменять элементы в «родительской» области действия. Однако обычно это считается не очень удачным методом работы. Если сценарий изменяет что-либо в глобальной области действия, бывает сложно предугадать, как эти изменения скажутся на работе других элементов оболочки. Все командлеты, имеющие отношение к элементам областей действия, имеют параметр –scope. К таким командлетам относятся:
• New-Alias
• New-PSDrive
• New-Variable
• Set-Variable
• Remove-Variable
• Clear-Variable
• Get-Variable
Параметр –scope может принимать несколько значений:
• Global – означает, что командлет относится к глобальной области действия.
• Script – означает, что командлет относится к области действия сценария. Если командлет запущен внутри скрипта, он влияет на область действия этого скрипта. Если он запущен в дочерней по отношению к скрипту области действия, он будет влиять на этот скрипт.
• Local – означает, что командлет относится к текущей области действия, которая запущена в данный момент.
• Также значением может быть целое число, где 0 обозначает текущую область действия, 1 – область действия, являющуюся родительской по отношению к текущей, и.т.д.
Если бы следующая команда выполнялась в сценарии, запущенном из командной строки, переменная была бы создана в глобальной области действия (на один уровень выше текущей области действия):
New-Variable –name var –value 100 –scope 1
Также вы можете использовать специальный синтаксис:
• $global:var относится к переменной $var в глобальной области действия.
• $script:var относится к переменной $var в текущей области действия (если текущая область действия — сценарий), или к ближайшей родительской области действия, являющейся сценарием.
• $local:var относится к переменной $var в текущей области действия.
Здесь, опять же, не рекомендуется модифицировать элементы за пределами текущей области действия, поскольку сложно сказать, как эти изменения могут отразиться на других задачах и процессах.
Чтобы предотвратить возникновение сложных, запутанных ситуаций, требующих тщательной настройки сценария, старайтесь следовать нескольким основным рекомендациям:
• Никогда не ссылайтесь на переменную до тех пор, пока вы не прикрепили к ней объект в текущей области действия. Это позволит ограничить доступ к переменным «родительской» области действия, которые могут содержать объекты, о которых вы не знали.
• Никогда не пытайтесь модифицировать псевдонимы, PSDrive элементы, функции или переменные в «родительской» области действия. Изменения можно производить только в текущей области действия.
Эти правила, в частности, относятся к областям действия, которые находятся за пределами вашей видимости, например, глобальной области действия. Старайтесь никогда не менять то, что может различаться в зависимости от ситуации, времени, используемого компьютера и.т.д.
Объявление переменных и Strict Mode
Нет необходимости объявлять переменные заранее. Этот вопрос часто интересует администраторов, имеющих опыт работы с VBScript, так как в этом языке предусмотрена команда Option Explicit, которая требует заблаговременного объявления переменных. В Windows PowerShell нет точного аналога Option Explicit, однако, здесь есть командлет Set-StrictMode. Set-StrictMode позволяет задавать строгий режим, а версия 2.0 выполняет функции, сходные с Option Explicit. Сама команда выглядит так:
Set-StrictMode –version 2
В этом режиме оболочка запрещает использование неинициализированных переменных. Например, при выключенном строгом режиме или при использовании версии 1.0 командлета, следующая команда будет разрешена:
Function MyFunction {
Write $var
$var = 1
Write $var
}
MyFunction
Write $var
Однако при выполнении следующей команды оболочка выдаст ошибку:
Set-StrictMode -version 2.0
Function MyFunction {
Write $var
$var = 1
Write $var
}
MyFunction
Write $var
Ошибка возникает из-за того, что переменная $var упоминается дважды до того, как ей было присвоено значение в данной области действий (вы узнаете больше об областях действия на следующем занятии). Целью отображения ошибки является предупреждение простых синтаксических ошибок. Например, рассмотрим команду:
Function MyFunction {
$computer = ‘Server2’
gwi Win32_ComputerSystem -comp $compter
}
MyFunction
В этом примере переменная $computer во второй раз была напечатана с ошибкой. Данный скрипт будет выполняться, но скорее всего появится сообщение об ошибке, указывающее на то, что WMI не мог установить соединение, так как пытался связаться с пустым значением имени компьютера. Это сообщение об ошибке может ввести в заблуждение, так как корректное имя сервера присутствует в скрипте, а команда Get-WmiObject была напечатана правильно, отдельно от переменной. Решить проблему поможет следующее изменение:
Set-StrictMode -version 2.0
Function MyFunction {
$computer = ‘Server2’
gwi Win32_ComputerSystem -comp $compter
}
MyFunction
Сейчас оболочка выдает ошибку об использовании неинициализированной переменной $compter. Эта ошибка заставит вас обратить более пристальное внимание на настоящую проблему – опечатку в имени переменной.
Установка строгого режима версии 2.0 крайне рекомендуется. Это позволяет быстрее и с большей точностью выявить существующие ошибки и устранить их. Обратите внимание, что строгий режим версии 2.0 не требует объявления переменной заранее; он запрещает ссылаться не переменную до тех пор, пока ей не присвоено значение. Например, следующий пример работает при выключенном строгом режиме:
Set-StrictMode -off
Function MyFunction {
Write $var
$var = 1
Write $var
}
$var = 3
MyFunction
Write $var
Он работает потому, что в первой выполняемой строчке кода переменной $var присваивается значение 3. Когда функция запущена, она может извлечь это значение из родительской области действия. Другими словами, переменной $var было присвоено значение в области действия скрипта и всех дочерних областях, поэтому, ошибки не возникает.
Управляющие операторы языка
Windows PowerShell предлагает языковые конструкции, которые являются идентичными многим другим скриптовым языкам. В основе ее синтаксиса лежит язык C#, хотя имеются сходства и со многими другими языками на основе C, такими как Java, JavaScript или PHP. У многих администраторов получается использовать Windows PowerShell для выполнения сложных задач даже без использования этих скриптовых конструкций. Данные конструкции необходимы, в первую очередь, для написания скриптов, предназначенных для выполнения сложного, многоэтапного процесса, где требуется принятие решений или выполнение повторяющихся мелких подзадач. Также они могут быть полезны для переходящих скриптов, основанных на более старых технологиях, таких как VBScript.
Около полдюжины конструкций, которые будут рассмотрены на этом уроке, составляют формальный скриптовый язык Windows PowerShell. Они дают возможность сценариям предпринимать различные действия, основываясь на динамических критериях и выполнять повторяющиеся задачи. Большинство этих конструкций основано на сравнительных критериях, а сравнение обычно производится с помощью одной или нескольких сравнительных операций оболочки.
Следует помнить, что Windows PowerShell предназначена для широкой аудитории. Например, не все администраторы свободно владеют языками программирования, поэтому, использование конструкций при знакомстве с Windows PowerShell может вызвать у них определенные затруднения. Но оболочка позволяет выполнять достаточно сложные задачи и без использования скриптовых элементов. В то же время, другие администраторы имеют некоторый опыт программирования – у них использование этих конструкций не вызовет сложностей. Но главное здесь то, что оболочка позволяет выполнять множество сложных задач без знания того, что мы привыкли относить к программированию. Конструкции доступны для всех, кто хочет и может пользоваться ими, но они не являются обязательными для работы с оболочкой. Тем не менее, они позволяют создавать скрипты для выполнения еще более сложных задач, а изучив их, вы сможете автоматизировать многие административные действия.
If….ElseIf…..Else
Рассмотрим конструкцию, используемую для принятия решений. Она предназначена для того, чтобы производить одно или несколько логических сравнений и выполнять одну или несколько команд в отношении первого сравнения, которое окажется верным:
$octet = Read-Host ‘Enter the third octet of an IP address’
if ($octet –lt 15 –and $octet –gt 1) {
$office = ‘New York’
} elseif ($octet –ge 15 –and $octet –lt 20) {
$office = ‘London’
} elseif ($octet –ge 21 –and $octet –lt 34) {
$office = ‘Sydney’
} else {
throw ‘Unknown octet specified’
}
Несколько замечаний, касающихся этой конструкции:
• Конструкция должна начинаться с блока if.
• Она может не включать блока elseif, а может включать несколько.
• Блоком else можно заканчивать конструкцию.
• Выполняется только первый блок со значением True, получившимся в результате сравнения.
• Блок else выполняется только в том случае, если этого не сделал ни один из предыдущих блоков.
Условие или сравнительная часть скриптовой конструкции помещается в скобки. Условие может быть любой сложности и может содержать подвыражения в скобках. Однако целая конструкция должна в обязательном порядке иметь одно из двух решений: True (верное) или False (ложное). Обратите внимание, что Windows PowerShell отображает значение False в виде нуля, а значение True любым другим числом. Поэтому, если результатом сравнения будет ноль, утверждение будет признано ложным (False). Например, следующая конструкция будет иметь результат True:
if (5+5) {
write ‘True’
} elseif (5-5) {
write ‘False’
}
Код условия, он же код команды, которая выполняется, когда результатом сравнения будет значение True, заключен в фигурные скобки. При этом оболочка не устанавливает жестких правил форматирования – например, следующее оформление конструкции будет вполне приемлемым:
if (5+5) { write ‘True’ } elseif (5-5) { write ‘False’ }
Однако такую конструкцию не очень удобно читать. Поэтому, чаще всего рекомендуется структурировать код и располагать скобки в соответствии с общепринятыми стандартами. Например, распространенным стандартом форматирования является расположение открывающей фигурной скобки в новой строке после условия, а закрывающей – в новой строке после последнего условного утверждения или команды. Именно такой формат мы чаще всего использовали в данном курсе ранее и будем использовать в дальнейшем. Еще один часто используемый формат выглядит так:
if (5+5)
{
write ‘True’
}
elseif (5-5)
{
write ‘False’
}
Не имеет значения, какой формат вы выберете, если вы правильно структурируете условный код и уверены в корректном размещении фигурных скобок.
Вложенные конструкции
Все конструкции могут быть вложенными в другие. Единственное правило здесь заключается в том, что они должны быть полностью вложенными. Это означает, что внутренняя конструкция должна быть закрыта раньше внешней. Написание каждого условного уровня с новой строки поможет вам убедиться, что вы все сделали правильно; многие сторонние редакторы предлагают дополнительные визуальные ключи, которые помогают контролировать правильность вложения конструкций. Вот пример вложенной конструкции If:
If ($ping.pingstatus –eq 0) {
$wmi = gwmi win32_operatingsystem –computer $computer
if ($wmi.buildnumber –ne 7600) {
write ‘Incorrect build – ignoring computer’
}
}
Обратите внимание, как структурирование текста помогает выделить вложенную конструкцию. Windows PowerShell не принуждает производить именно такое форматирование, тогда как в Windows PowerShell ISE оно является обязательным. Например, следующая конструкция разрешена, но является неудобной для чтения и для работы:
If ($ping.pingstatus –eq 0) {
$wmi = gwmi win32_operatingsystem –computer $computer
if ($wmi.buildnumber –ne 7600) {write ‘Incorrect build – ignoring computer’}}
Набор операторов
Когда Windows PowerShell запускает сценарий, это происходит точь-в-точь так же, как если бы вы вручную набирали каждую строчку сценария в диалоговом окне. Таким образом, нет никакой разницы между запуском сценария и запуском отдельных команд вручную, за исключением того, что сценарий запускается только в том случае, если политика выполнения оболочки позволяет это. Но даже если включен режим Restricted политики выполнения, вы можете открыть сценарий, скопировать его содержимое в буфер обмена и вставить в интерактивную оболочку.
На заметку: Возможность копирования и вставки скрипта в оболочке не считается проблемой, связанной с безопасностью, так как для того, чтобы сделать это, вы должны предпринять ряд целенаправленных действий. Вероятность того, что вы случайно скопируете и вставите нужные команды, практически исключена.
Вы можете использовать любую скриптовую конструкцию напрямую из командной строки, даже из окна консоли вместо ISE. Когда вы открываете конструкцию путем набора { и нажатия клавиши Return, подсказка в оболочке меняется и указывает на то, что вы находитесь внутри конструкции, и что оболочка ждет от вас ее завершения:
PS C:> if ($var -eq 5) {
>>
Когда вы закончили ввод конструкции и закрыли ее, снова нажмите Return, чтобы запустить выполнение кода:
PS C:> if ($var -eq 5) {
>> write ‘is 5’
>> } else {
>> write ‘is not 5’
>> }
>>
is not 5
PS C:>
Включая конструкцию такого типа в скриптовый блок командлета, вы можете отказаться от рекомендуемого форматирования и расположить всю команду в одну строку, например:
gwmi win32_logicaldisk | select deviceid, @{Label=’DriveType’;Expression={ if ($_.drivetype -eq 3) { write ‘LocalFixed’ } else { write ‘NonFixed’ }}}, Size
Эта однострочная команда включает командлет Select-Object, который использует пользовательские колонки. Выражение для этих колонок включает конструкцию If, но она не отформатирована в соответствии с рекомендациями. Выходные данные этой команды будут выглядеть примерно так:
deviceid DriveType Size
——— ——— —-
A: NonFixed
C: LocalFixed 64317550592
D: NonFixed
Z: NonFixed 413256384512
Как вы видите, скриптовая конструкция может использоваться напрямую из командной строки, а не только в сценарии.
Switch
Эта конструкция также предназначена для принятия логических решений. Она сравнивает один входящий объект с рядом возможных объектов или сравнений. По умолчанию она выполняет все удовлетворяющие критерию предложения, а не только первое. Примером такой конструкции может быть:
$computer = ‘LON-DC1’
switch ($computer) {
‘LON-DC1’ {
write ‘London Domain Controller 1’
}
‘SEA-DC1’ {
write ‘Seattle Domain Controller 1’
}
‘LON-DC1’ {
write ‘London Domain Controller 1’
}
default {
write ‘Unknown’
}
}
Несколько замечаний по поводу этой конструкции:
• Обратите внимание, что в выходных данных London Domain Controller 1 присутствует дважды, так как здесь есть два удовлетворяющих критерию предложения.
• Блок default является опционным и выполняется только в том случае, если в предыдущих блоках не было найдено удовлетворяющих критерию предложения.
• Каждое возможное совпадение представляет собой отдельную подконструкцию, код которой должен заключаться в фигурные скобки.
Break
Ключевое слово Break прерывает выполнение любой конструкции кроме If…ElseIf…Else. Break можно использовать в сочетании с Switch для того, чтобы убедиться, что выполняется только первое удовлетворяющее критерию предложение.
$computer = ‘LON-DC1’
switch ($computer) {
‘LON-DC1’ {
write ‘London Domain Controller 1’
break
}
‘SEA-DC1’ {
write ‘Seattle Domain Controller 1’
break
}
‘LON-DC1’ {
write ‘London Domain Controller 1’
break
}
default {
write ‘Unknown’
}
}
Выходными данными в этом примере является один London Domain Controller 1, так как ключевое слово Break немедленно прервало конструкцию после первого удовлетворяющего критерию предложения.
Опции Switch
Конструкция Switch включает несколько опций, влияющих на ее поведение. Одной из них является использование параметра –wildcard switch, который позволяет удовлетворяющему критерию предложению, являющемуся строкой, обрабатываться как строке с подстановочным символом. В следующем примере выходными данными будут “London” и “Domain Controller.” Обратите внимание, что ключевое слово Break не используется, а значит возможно несколько вариантов предложений, удовлетворяющих критериям:
$computer = ‘LON-DC1’
switch -wildcard ($computer) {
‘LON*’ {
write ‘London’
}
‘SEA*’ {
write ‘Seattle Domain Controller 1’
}
‘*DC*’ {
write ‘Domain Controller’
}
‘*SRV*’ {
write ‘Member Server’
}
default {
write ‘Unknown’
}
}
О других возможностях конструкции Switch можно узнать в соответствующем разделе справочника.
For
Эта конструкция обычно используется для повторения одной и той же команды указанное количество раз:
For ($i=0; $i –lt 10; $i++) {
Write $i
}
Несколько замечаний по поводу конструкции:
• Условия или критерии сравнения конструкции в действительности состоят из трех частей, разделенных точкой с запятой.
• В первой части задается стартовое условие, в данном случае $i=0.
• Вторая часть представляет собой условие, при котором цикл должен повторяться, в данном случае он будет повторяться до тех пор, пока $i меньше 10.
• Третья часть – это операция, которая будет выполняться каждый раз при завершении цикла, в данном случае это увеличение $i на один.
Разрешается менять переменную counter внутри самого цикла:
For ($i=0; $i –lt 10; $i++) {
Write $i
$i = 10
}
В данном примере цикл будет выполняться только один раз, так как в процессе выполнения $i выйдет за пределы обозначенного диапазона (меньше 10).
Не забывайте о правилах, касающихся областей действия. Например, следующее делать не рекомендуется:
For ($i; $i –lt 10; $i++) {
Write $i
}
В данном примере $i идентифицирована как переменная цикла, но ей не присвоено стартовое значение. Оболочка вынуждена передвигаться по областям действия вверх и проверять, определена ли переменная $i в какой-либо из родительских областей. Если нет – переменной $i присваивается значение по умолчанию, ноль. Однако если $i была создана в одной из родительских областей действия, она может получить ненулевое значение или даже значение, не являющееся числом. Это может привести к неожиданным результатам и к длительным поискам ошибки. Поэтому, всегда рекомендуется задавать стартовое значение числовой переменной.
While-Do-Until
Эти ключевые слова могут использоваться в разных комбинациях для создания немного разных эффектов. Вот три варианта:
$var = 1
while ($var -lt 10) {
write $var
$var++
}
$var = 1
do {
write $var
$var++
} while ($var -lt 10)
$var = 20
do {
write $var
$var—
} until ($var -lt 10)
Несколько заметок об этих конструкциях:
• Когда критерии сравнения или условие находятся в конце конструкции, условный код внутри конструкции всегда выполняется как минимум один раз.
• Когда критерии сравнения или условие находятся в начале конструкции, Условный код внутри конструкции выполнятся только в том случае, если сравнение начинается с True. Это означает, что в некоторых ситуациях код не выполняется вообще.
• While может использоваться как в начале, так и в конце конструкции, а Until – только в конце.
• While и Until в конце конструкции выполняют одну и ту же функцию, но имеют противоположную логику.
ForEach
Данная конструкция выполняет ту же самую базовую задачу, что и командлет ForEach-Object: перечисляет ряд объектов. Условный код конструкции выполняется один раз для каждого входящего объекта. Во время каждого выполнения цикла следующий объект извлекается из набора и помещается в обозначенную вами переменную. Например:
$services = Get-Service
ForEach ($service in $services) {
Write $service.name
}
Обратите внимание, что синтаксис здесь слегка отличается от командлета ForEach-Object. Эта конструкция не содержит переменной $_, а ее условие содержит ключевое слово in. Это различие иногда вызывает путаницу, так как оболочка предусматривает псевдоним ForEach для командлета ForEach- Object. Это означает, что “foreach” является одновременно скриптовой конструкцией и псевдонимом для командлета. Оболочка может различить их, исходя из того, где они используются. Псевдоним используется только в цепочке команд, и обычно обладает объектами, которые передаются ему по конвейеру.
Get-Service | ForEach { Write $_.name }
Важно не путать эти две формы синтаксиса. Но действительно ли вам так нужен ForEach? Во многих случаях администраторы, имеющие некоторый опыт в программировании, в частности, в VBScript, используют ForEach- Object или конструкцию ForEach даже тогда, когда в этом нет острой необходимости. Конечно, в этом нет ничего страшного, кроме того, что они делают лишнюю работу. Например, рассмотрим отрывок кода, который удаляет все объекты в папке, если их размер превышает указанный:
$folder = ‘c:demo’
$files = dir $folder
foreach ($file in $files) {
if ($file.length –gt 100MB) {
del $file
}
}
Это очень «скриптовый» подход к созданию кода, который часто можно встретить в таких языках как VBScript. Однако Windows PowerShell позволяет создать куда более простую модель, так как большинство командлетов могут обрабатывать наборы объектов, не требуя их перечисления:
Dir c:demo | where { $_.Length –gt 100MB } | Del
Каждый раз, когда вы собираетесь использовать ForEach или ForEach-Object, не забывайте подумать – а действительно ли это так необходимо? В некоторых случаях, например в тех, которые были рассмотрены в модуле, посвященном Windows Management Instrumentation, это необходимо. Однако во многих других ситуациях можно обойтись и другими средствами.
Стиль работы
При наборе конструкции в командной строке, например, для создания части скриптового блока, который будет передаваться командлету, вы можете отказаться от рекомендуемого форматирования в пользу краткости. В этом случае вам придется печатать множественные команды в одной строке. Windows PowerShell позволяет действовать таким образом, при условии, что команды будут разделены точкой с запятой:
gwmi win32_logicaldisk | select deviceid, @{Label=’DriveType’;Expression={ switch ($_.drivetype) { 2 { Write ‘Floppy’; break } 3 { Write ‘Fixed’; break } 4 { Write ‘Optical’; break } 5 { Write ‘Network’; break }}}}, Size, FreeSpace
Обратите внимание, что точка с запятой используется для разделения команд Write и Break внутри каждого блока, содержащего условие. Несмотря на то, что это все можно напечатать так, как показано в примере, при использовании форматирования блок будет легче читаться:
gwmi win32_logicaldisk |
select deviceid, @{Label=’DriveType’;Expression={
switch ($_.drivetype) {
2 { Write ‘Floppy’; break }
3 { Write ‘Fixed’; break }
4 { Write ‘Optical’; break }
5 { Write ‘Network’; break }
}
}
}, Size, FreeSpace
Второй пример тоже будет верным, поскольку оболочка знает, как проанализировать такой тип входящих данных. Набор данной команды в оболочке будет выглядеть примерно так:
PS C:> gwmi win32_logicaldisk |
>> select deviceid, @{Label=’DriveType’;Expression={
>> switch ($_.drivetype) {
>> 2 { Write ‘Floppy’; break }
>> 3 { Write ‘Fixed’; break }
>> 4 { Write ‘Optical’; break }
>> 5 { Write ‘Network’; break }
>> }
>> }
>> }, Size, FreeSpace
>>
Если вы ранее работали со скриптовыми языками, то, возможно, при изучении Windows PowerShell вы будете использовать те же подходы, которые применяются в этих языках. В этом нет ничего страшного – скриптовые конструкции Windows PowerShell созданы специально для того, чтобы вы могли перенести свои старые знания в новые условия. Однако не забывайте, что зачастую Windows PowerShell предлагает более простые способы выполнения тех же самых задач. Изучение этих способов позволить сделать работу с Windows PowerShell более эффективной, а также узнать о новых возможностях, предлагаемых оболочкой. В целом можно порекомендовать стараться чаще использовать цепочки команд вместо формальных скриптов. Для очень сложных задач написание сценария может стать верным решением, но во многих случаях можно обойтись более простыми и короткими командами.
Обработка ошибочных ситуаций
Несмотря на то, что вам придется фиксировать и устранять некоторые ошибки, например, опечатки, во время написания сценария, некоторые ошибки можно предусмотреть заранее. Например, ошибка, возникающая из-за того, что файл или сервер недоступен, относится к тем ошибкам, о возможности возникновения которых можно догадаться заранее, но которые нельзя зафиксировать или предотвратить. Решением в данном случае станет написание сценария, который позволит выявить и исправить такие ошибки.
В сценарии a Windows PowerShell выделяют три большие категории ошибок:
• Синтаксические ошибки, которые, как правило, являются результатом опечаток или неправильного написания.
• Логические ошибки, которые означают, что сценарий выполняется верно, но результаты получаются не те, которые были запланированы.
• Ошибки выполнения, которые можно предусмотреть заранее, но нельзя исправить заранее (например, недоступность удаленного компьютера).
Синтаксические ошибки проще всего выявить и предупредить. Сообщения об ошибках обычно направляют вас в нужное место – вам остается лишь пристально взглянуть на неправильно набранное слово, определить ошибку и устранить ее. Логические ошибки являются более сложными и требуют настройки сценария – об этом вы узнаете чуть позже. Логические ошибки обычно возникают, когда переменная или свойство имеет значение, несущее не ту информацию, которую вы ожидаете. Например, вы предполагаете, что свойство DriveType содержит строку Removable, а в действительности оно содержит числовое значение «5». И, наконец, ошибки выполнения по степени сложности решения находятся примерно посередине между синтаксическими и логическими. Ошибки выполнения не всегда можно предсказать заранее. Например, вы можете написать скрипт для подключения к удаленному компьютеру, но при попытке подключения выяснится, что у вас нет на это разрешения. На этом уроке мы остановимся на ошибках выполнения, которые не всегда можно предупредить, но можно предугадать возможность их возникновения во время написания скрипта.
$ErrorActionPreference
Многие командлеты способны продолжать выполняться даже при возникновении ошибок. Например, рассмотрим такую команду:
Get-WmiObject Win32_Service –computer Server1,Server2,Server3
Предположим, что во время запуска команды Server2 оказался в режиме оффлайн. Командлет успешно установил соединение с Сервером 1, но попытка подключения к Серверу 2 оказалась неудачной. Это непрерывающая ошибка. Командлет не может выполнить действие для Сервера 2, но он не прекращает работу и переходит к Серверу 3. Когда командлет сталкивается с ошибкой такого типа, он проверяет, что можно предпринять для ее решения. Информация о действиях, предпринимаемых для решения бесконечных ошибок, хранится во встроенной в оболочку переменной $ErrorActionPreference. Эта переменная может принимать одно из четырех значений:
• Continue является значением по умолчанию и дает командлету инструкцию: выдать сообщение об ошибке и продолжить работу.
• Stop принуждает командлет превратить непрерывающую ошибку в прерывающее исключение, в результате чего выполнение командлета полностью прекращается.
• SilentlyContinue дает командлету инструкцию продолжать работу без отображения сообщения об ошибке.
• Inquire – дает командлету инструкцию обратиться к пользователю с запросом, чтобы пользователь мог самостоятельно выбрать, что следует сделать – остановить работу или продолжить.
Не забывайте, что все это относится только к непрерывающим ошибкам, с которыми может столкнуться командлет. Но если командлет столкнулся с прерывающим исключением, его работа незамедлительно прекращается, вне зависимости от того, как настроена переменная $ErrorActionPreference.
Порочная практика
В целом сообщения об ошибках – полезная вещь. Оболочка обычно выдает четкие, информативные сообщения об ошибках, и если вы прочитаете внимательно такое сообщение, вы поймете, где именно произошла ошибка, и что можно предпринять для ее решения. Поэтому, отказываться от сообщений об ошибках нецелесообразно. Однако многие администраторы часто добавляют в начало сценария команду:
$ErrorActionPreference = «SilentlyContinue»
Обычно они делают это потому, что используют такой командлет, как Get-WmiObject, с помощью которого они могут предусмотреть возникновение ошибок, поэтому, сообщения об ошибках им не нужны. Однако добавление вышеуказанной команды в начало сценария отменяет появление сообщений об ошибках для всего скрипта. Зачастую при выполнении скрипта возникают ошибки совсем другого рода, о которых администратор не узнает, так как сообщения об ошибках отключены. В результате скрипт работает не так, как планировалось, и а его настройку уходит масса времени, так как без сообщения об ошибках весьма сложно определить, в каком месте необходимо внести изменения в сценарий. Существует очень мало ситуаций, в которых сообщения об ошибках не нужны вообще. Поэтому, если вы решили отключить уведомления, лучше сделать это для одного, конкретного командлета.
–ErrorAction
Все командлеты Windows PowerShell поддерживают ряд общих параметров, которые обрабатываются непосредственно самой оболочкой, и которые разработчик командлетов не должен прописывать вручную. Эти параметры не перечисляются в справочнике для каждого командлета, их список можно увидеть в разделе Common Parameters. Прочитать информацию о них можно, набрав команду:
Help about_commonparameters
Один из общих параметров — это –ErrorAction, имеющий псевдоним EA. Этот параметр может принимать те же четыре значения, что и переменная $ErrorActionPreference. Однако, в отличие от этой переменной, данный параметр осуществляет выявление и отображение ошибок только для одного командлета. Поэтому, если вы используете командлет, например, Get-WmiObject, вы можете отключить уведомления об ошибках именно для этого командлета с использованием параметра –ErrorAction или –EA:
Gwmi Win32_Service –computer Server1,Server2,Server3
–EA SilentlyContinue
Перехват ошибок
Вы можете дать оболочке указание уведомлять о прерывающих исключениях и запускать команды в ответ на эти ошибки. Это называется «перехват ошибок» и означает, что вы самостоятельно определяете, какое действие предпринять в ответ на возникшую ошибку, а не доверяете оболочке произвести действие по умолчанию.
Вы можете перехватывать только прерывающие исключения. Непрерывающие ошибки вы перехватывать не можете, даже тогда, когда видите уведомление об ошибке.
Если вы предусмотрели заранее, что командлет может столкнуться с ошибкой, которую вы хотите перехватить, вы должны указать параметр – ErrorAction со значением Stop. Ни одно другое действие не гарантирует возможность перехвата.
Если вы используете –ErrorAction Inquire, перехватываемое исключение генерируется только в том случае, если пользователь выбирает опцию «остановить командлет». После того, как вы дали командлету инструкцию превращать непрерывающие ошибки в прерывающие перехватываемые исключения посредством –EA Stop, у вас есть два варианта перехвата ошибки: с помощью конструкции Trap или конструкции Try…Catch
Прежде, чем мы перейдем к конструкциям Trap и Try…Catch, вспомните, что вы знаете об областях действия в Windows PowerShell.
Сама оболочка – это глобальная область действия. Каждый скрипт, который вы запускаете, создает свою собственную область действия. Функции (которые мы рассмотрим чуть позже) тоже содержатся в своих областях действия. Поэтому, если вы выполняете сценарий, который содержит функцию, вы имеете дело с деревом областей действия, которое выглядит примерно так:
• Глобальная область действия
• Область действия скрипта
• Область действия функции
Область действия функции является дочерней по отношению к скриптовой, а скриптовая, в свою очередь, является дочерней по отношению к глобальной. Если прерывающее исключение происходит внутри функции, оболочка сначала проверяет, собираетесь ли вы перехватить это исключение внутри этой же области, т.е. внутри функции. Если у вас нет способа сделать это, оболочка покидает область действия функции и переносит прерывающее исключение в родительскую область действия, в данном случае в скриптовую. С точки зрения скрипта, функция сама сгенерировала это исключение, поэтому, оболочка проверяет, есть ли внутри скрипта инструменты для того, чтобы перехватить и исправить исключение. Если таких инструментов не обнаружено, оболочка покидает область действия скрипта и обращается к глобальной области действия. С точки зрения глобальной области действия, исключение было сгенерировано всем скриптом, и оболочка начинает искать инструменты для перехвата и исправления ошибки в глобальной области действия. Это может показаться довольно сложным, но очень важно решить, какие действия предпринять в отношении ошибки. Говоря в общем, вы должны стараться перехватить и исправить ошибку в той области действия, в которой она возникла. Например, если функция содержит командлет Get-WmiObject, и вы хотите перехватить и исправить ошибки для этого командлета, конструкция перехвата ошибок должна быть включена в функцию. Таким образом, оболочке не придется выходить за пределы области действия функции для исправления ошибки.
Trap
Конструкция для перехвата ошибок обычно указывается в скрипте перед исключением, возникновение которого вы предусматриваете. Простая конструкция может выглядеть примерно так:
trap {
write-host «Exception trapped!» -fore yellow -back black
continue
}
get-wmiobject win32_process -comp NotOnline -ea stop
В конце конструкции вы можете указать одно или два ключевых слова:
• Continue – продолжает выполнение команды, которая указана в скрипте после исключения, не выходя за пределы текущей области действия.
• Break – выходит за пределы текущей области действия и ищет средства для перехвата ошибки и ее исправления в родительской области действия.
Например, рассмотрим короткий скрипт:
trap {
write-host «Exception trapped in the script»
-fore green -back black
continue
}
function test {
trap {
write-host «Exception trapped in the function»
-fore yellow -back black
break
}
write-host «I am inside the function»
get-wmiobject win32_process -comp NotOnline -ea stop
write-host «I am still inside the function»
}
write-host «Running the function»
test
write-host «Finished running the function»
Ошибка возникает в командлете Get-WmiObject. Так как перехват ошибки указан в области действия функции, этот перехват выполняется. Перехват заканчивается ключевым словом break, поэтому оболочка выходит за пределы области действия функции и передает ошибку в родительскую область. Перехват определен и здесь, поэтому он выполняется. Перехват заканчивается ключевым словом continue, поэтому оболочка переходит к выполнению команды, указанной после перехвата. С точки зрения скрипта, ошибка произошла в функции test, поэтому выполнение команды продолжается в этой же области действий. Выходные данные скрипта будут выглядеть так:
Running the function
I am inside the function
Exception trapped in the function
Exception trapped in the script
Finished running the function
Попробуйте запустить скрипт, указанный в примере, и убедитесь, что вы поняли, почему выходные данные будут выглядеть именно так.
Ниже вы видите тот же самый скрипт с одной небольшой разницей: Перехват внутри функции сейчас заканчивается ключевым словом continue, а не break:
trap {
write-host «Exception trapped in the script»
-fore green -back black
continue
}
function test {
trap {
write-host «Exception trapped in the function»
-fore yellow -back black
continue
}
write-host «I am inside the function»
get-wmiobject win32_process -comp NotOnline -ea stop
write-host «I am still inside the function»
}
write-host «Running the function»
test
write-host «Finished running the function»
Выходные данные сейчас выглядят так:
Running the function
I am inside the function
Exception trapped in the function
I am still inside the function
Finished running the function
Вы поняли, почему? Когда произошла ошибка, был выполнен перехват внутри функции. Однако эта команда заканчивалась ключевым словом continue, поэтому, оболочка не вышла за пределы области действия функции и продолжила выполнений следующей команды. Поэтому, на этот раз отобразилась строчка I am still inside the function. Функция была выполнена до конца, а ошибка не была передана в скрипт. Поэтому, перехват в скрипте не был выполнен.
При выполнении перехвата ошибок крайне важно помнить о дереве областей действия. Это может показаться сложным, но, потратив некоторое время на изучение поведения оболочки в вышеописанных ситуациях, вы сможете избежать лишней путаницы и ошибок.
Конструкция перехвата, с которой вы только что познакомились, была общей, то есть, она подходит для любого типа прерывающих исключений. Windows PowerShell также позволяет определять перехват особых видов исключений, но для этого вы должны знать определенные типы классов исключений .NET Framework. Например:
trap [System.Management.Automation.CommandNotFoundException]
{«Command error trapped»}
Этот перехват выполняется только для исключений типа System.Management.Automation.CommandNotFoundException. Оболочка позволяет указывать несколько конструкций для перехвата, каждая из которых предназначена для конкретного типа исключений. Это один из способов выбирать разные инструменты для решения разных проблем. Однако определить нужное имя класса .NET Framework может оказаться сложно.
Также обратите внимание, что перехват – это отдельная область действия, как и функция. Перехват может получать доступ к переменным за пределами своей области действия, по общим правилам. Однако любые переменные, которые создаются или устанавливаются перехватом, относятся только к нему. Если вы используете перехват, чтобы изменить переменную, расположенную в родительской для него области действия, используйте командлет Set- Variable с параметром –scope.
Try…. Catch
Конструкция Try…Catch является более простой в использовании, чем конструкция Trap. Типичная конструкция такого типа выглядит так:
try {
gwmi win32_service -comp notonline -ea stop
} catch {
write-host «Error!»
}
Блок Try определяет команду, при выполнении которой, как вы предполагаете, может произойти ошибка, и для которой вы задали ErrorAction команды Stop. Если ошибка произошла, начинает выполняться код, указанный внутри блока Catch.
Так же, как и в случае с конструкцией Trap, вы можете указать несколько блоков Catch, каждый из которых будет выявлять определенный тип ошибок. Чтобы узнать больше об этой технике, запустите Help about_try_catch_finally.
После того, как выполнение кода внутри блока Catch закончилось, начинается выполнение команды, указанной после блока Try…Catch. Также вы можете задать блок Finally:
try {
gwmi win32_service -comp notonline -ea stop
} catch {
write-host «Error!»
} finally {
write-host «This executes either way»
}
Код внутри блока Finally выполняется независимо от того, произошла ошибка или нет. Например, вы можете использовать этот блок для завершения соединения с базой данных, вне зависимости от того, произойдет ожидаемая ошибка или нет.
Извлечение ошибок
При использовании конструкций Trap и Try вам, возможно, понадобится доступ к тому исключению, которое стало причиной запуска этой конструкции. Существует два способа добиться этого. Встроенная переменная $error содержит ошибки, встречающиеся в оболочке. $Error[0] – это последняя ошибка, $Error[1] – предпоследняя и.т.д. Также вы можете использовать параметр -ErrorVariable (или –EV) для того чтобы выявить ошибку, сгенерированную этим командлетов в переменную. Например:
Get-Content does-not-exist.txt –EA Stop –EV myerr
Обратите внимание, что перед именем переменной myerr в данном контексте не используется символ $. Если происходит ошибка, командлет помещает информацию о ней в указанную переменную. Вы можете использовать ее следующим образом:
try {
gwmi win32_service -comp notonline -ea stop -ev myerr
} catch {
$myerr | out-file c:errors.txt -append
}
Обратите внимание, что myerr не включает значок доллара, когда указывается в сочетании с параметром –EV, потому что на этом этапе вы лишь указываете имя переменной, а $ технически не является частью ее имени. Позже, когда вы действительно будете использовать саму переменную, знак доллара будет ставиться перед ее названием, чтобы указать оболочке, что это именно переменная, а не что-то другое.
Отладка
Логические ошибки, возможно, являются самыми сложными в исправлении. Обычно их нельзя предусмотреть заранее, и они не всегда влекут за собой уведомление об ошибке. Просто в результате логической ошибки скрипт работает не так, как было запланировано. Цель отладки скрипта – выявить причину возникновения логических ошибок, исправить их и протестировать результат.
Как уже упоминалось на предыдущем занятии, цель отладки – решение логических ошибок. Самая распространенная причина их возникновения – это свойство переменной или объекта, имеющее не то значение, которое вы предполагали. Таким образом, отладка предназначена для того, чтобы помочь вам увидеть, что в действительности содержат переменные и свойства и сравнить ваши ожидания с действительностью. Однако, прежде чем начать отладку, вам необходимо понять, что должна делать каждая строчка вашего сценария. Вы не сможете определить, были ли ваши ошибочными, пока не определитесь с этими ожиданиями.
Прежде чем приступить к отладке, сядьте с вашим сценарием и листом бумаги. Запишите, какие входящие значения используются в вашем сценарии. Пройдитесь по всему сценарию, строчка за строчкой. Запишите, каких результатов вы ожидаете от каждой строчки, и как вы можете проверить правильность выполнения каждой операции. Запишите значения, которые содержит каждая переменная и каждое свойство.
На заметку: Когда вы приобретете определенный опыт, лист бумаги, возможно, уже не понадобится. Тем не менее, первое время рекомендуется записывать каждое действие, чтобы облегчить себе работу.
Отладочный вывод
Одна из технологий отладки заключается в изучении трассировочных сообщений выходных данных вашего скрипта. Это поможет определить, какие значения в действительности имеют свойства и переменные. При сравнении трассировочных сообщений с вашими ожиданиями, которые вы записали на листе бумаги, несовпадений быть не должно. Если что-то не совпадает, возможно, именно это и послужило причиной ошибки.
Оболочка не создает трассировочные сообщения автоматически. Чтобы получить их, необходимо использовать в сценарии командлет Write-Debug. Например, каждый раз, когда вы меняете значение переменной, вы должны прописывать новое значение таким образом:
$var = Read-Host «Enter a computer name»
Write-Debug «`$var contains $var
Обратите внимание, что в данном примере использования Write-Debug переменная и ее содержание помещены в двойные кавычки. Однако в первом случае переменная указана без знака $. В результате имя переменной отобразится как есть, вслед за ним идет содержимое переменной и ее значение. Выходные данные такой отладки весьма полезны, так как содержат имя переменной и ее значение. Также следует использовать Write-Debug везде, где скрипт принимает решение. Например, рассмотрим следующий отрывок:
If ($var –notlike «*srv*») {
Write-Host «Computer name is not a server»
}
You might modify this as follows:
If ($var –notlike «*srv*») {
Write-Debug «$var does not contain ‘srv’»
Write-Host «Computer name $var is not a server»
} else {
Write-Debug «$var contains ‘srv’»
}
Обратите внимание, что был добавлен блок Else, поэтому скрипт будет генерировать трассировочные сообщения независимо от того, какое логическое решение будет принято. По умолчанию оболочка скрывает выходные данные Write-Debug. Чтобы они отображались, поместите переменную $DebugPreference в начало скрипта:
$DebugPreference = ‘Continue’
Теперь выходные данные Write-Debug будут отображаться. Когда вы закончите отладку скрипта, удалять команды Write-Debug будет не нужно. Вместо этого снова скройте их выходные данные:
$DebugPreference = ‘SilentlyContinue’
Таким образом, команда Write-Debug останется в скрипте на тот случай, если в дальнейшем она снова понадобится для отладки.
На заметку: Выходные данные Write-Debug отличаются от обычных выходных данных в окне консоли Windows PowerShell. Сторонние скриптовые редакторы могут перенаправить эти данные в другую панель, окно или страницу, позволяя таким образом отделить трассировочные сообщения от других данных.
Пошаговый отладчик
Если скрипт очень длинный, то просмотр сотен строк трассировочных сообщений может стать утомительным и занять много времени. Поэтому в некоторых случаях вы можете воспользоваться пошаговым отладчиком. Пошаговый отладчик позволяет выполнять скрипт поэтапно – одна строка за один раз. Перед выполнением строки вы можете сделать паузу и просмотреть содержимое переменных, объектов, свойств и.т.д. Пошаговый отладчик запускается с помощью команды:
Set-PSDebug –step
После того, как вы завершили работу, отключите отладчик с помощью команды:
Set-PSDebug –off
Во время выполнения скрипта вы можете дать пошаговому отладчику команду пойти вперед и выполнить следующую строку или сделать паузу. Во время паузы оболочка показывает различные подсказки, которые напоминают о том, что вы находитесь внутри скрипта. Вы можете выполнять команды как обычно и одновременно просматривать информацию об объектах и переменных. Чтобы продолжить выполнение скрипта, запустите Exit.
Контрольные точки
Одним из недостатков пошагового отладчика является отсутствие возможности пропускать те части скрипта, в корректной работе которых вы не сомневаетесь. Если ваш скрипт состоит из 200 строк, и вы знаете, что проблема находится где-то в конце, нажимать Yes столько раз подряд довольно утомительно.
Чтобы облегчить ситуацию, Windows PowerShell предлагает возможность создания контрольных точек. С контрольными точками скрипт выполняется как обычно. Однако когда оболочка сталкивается с условием контрольной точки, которое вы задали, она автоматически приостанавливает скрипт так же, как и пошаговый отладчик. Так вы можете изучить значения свойств или переменные, после чего возобновить выполнение сценария.
Условия контрольных точек могут быть следующими:
• Остановить выполнение сценария при достижении определенной строки.
• Остановить выполнение сценария при чтении определенной переменной.
• Остановить выполнение сценария, когда определенная переменная изменяется или пишется.
• Остановить выполнение сценария, когда определенная переменная читается или пишется.
• Остановить выполнение сценария при выполнении опрделенной команды или функции.
Также вы можете указать конкретное действие, представляющее собой набор команд Windows PowerShell, которое вы хотели бы выполнить при достижении контрольной точки.
Управление контрольными точками осуществляется с помощью командлетов:
• Set-PSBreakpoint – создание нового условия контрольной точки.
• Remove-PSBreakpoint – удаление условия контрольной точки.
• Disable-PSBreakpoint — прекратить действие условия контрольной точки без его удаления.
• Enable-PSBreakpoint – возобновить действие остановленного условия контрольной точки.
• Get-PSBreakpoint – извлечь одно или несколько условий контрольной точки.
Контрольные точки позволяют вам задавать условия, при которых выполнение сценария будет приостановлено (или будет произведено другое действие).
Отладка в ISE
Отладчик Windows PowerShell обеспечивает базовую визуальную поддержку для отладки, в первую очередь, в сочетании с контрольными точками. Визуальных средств для создания контрольной точки нет. Однако когда вы создаете контрольную точку по номеру строки для сценария (используя параметр –script командлета Set-PSBreakpoint), ISE отображает эту контрольную точку внутри скрипта, подчеркивая соответствующую строку. Когда вы запускаете этот скрипт, ISE позволяет наводить курсор мышки на имена переменных, чтобы увидеть их содержимое.
Модуляризация
По мере того, как вы будете создавать все более сложные и полезные сценарии, вам все чаще будет требоваться повторное использование одних и тех же фрагментов. Модуляризация – это технология запаковки фрагментов кода в более простые и легко читаемые единицы. Windows PowerShell предлагает несколько уровней модуляризации, каждый из которых сложнее предыдущего, и в то же время обеспечивает больше гибкости и функциональности.
Модуляризация предназначена для создания полезных, независимых компонентов для многократного использования. Цель модуляризации – ускорить процесс написания скриптов, позволяя повторно использовать готовые фрагменты из предыдущих проектов. В Windows PowerShell базовой формой модуляризации является функция. Вы уже встречались с понятием функции ранее – сейчас мы рассмотрим их назначение более подробно.
Функция должна имеет настолько узкое предназначение и быть настолько независимой, насколько это возможно. Создавая функцию для выполнения одной конкретной задачи, вы делаете возможным ее повторное использование там, где выполнение этой же задачи снова потребуется.
Задачи могут включать такие вещи как написание базы данных, проверка возможности соединения с удаленным компьютером, валидация имени сервера и.т.д. В идеале функции должны настраивать себя на выполнение одной задачи так же, как это делает большинство командлетов.
Вы можете воспринимать командлеты как особую форму модуляризации, хотя настоящие командлеты требуют знания.NET Framework.
Для выполнения своей задачи функция должна получить особенный вид входящих данных. Функция никогда не должна пытаться получить доступ к информации, находящейся за пределами себя самой – это во многом снизит возможность ее повторного использования. Например, предположите, что вы имеете скрипт, содержащий функцию Get-ServerName. Если предполагается, что эта функция может читать переменные, содержащиеся в родительской оболочке, любой скрипт, в котором используется эта функция, должен содержать соответствующие переменные. Такая зависимость усложняет многократное использование функции в разных сценариях. Однако, поддерживая автономность функции, вы сможете с легкостью использовать ее в самых разных ситуациях.
Функции должны выдавать данные таким образом, чтобы их можно было использовать в разных ситуациях. В общем, это означает возможность передачи выходных данных по конвейеру. Например, функция, которая выводит данные напрямую в CSV файл, может использоваться только тогда, когда вам нужен результат в виде CSV файла. Функция, которая выводит выходные данные в конвейер, может использоваться в различных ситуациях, так как вы можете передать эти данные таким командлетам как Export- CSV, Export-CliXML, ConvertTo-HTML и другим.
Базовые функции
Базовая функция – это простейшая форма модуляризации. Она не принимает никаких входящих данных, что означает, что для ее выполнения не требуется никакой дополнительной информации. Она производит выходные данные, которые могут передаваться по конвейеру другим командлетам. Базовая функция указывается с функцией ключевых слов, а содержимое этой функции помещается в фигурные скобки:
Function Do-Something {
# function code goes here
}
Функции должны быть определены до того, как они могут быть использованы, а значит зачастую функции необходимо указывать в самом начале сценария. Чтобы запустить функцию, которая была определена, используйте ее имя, так же, как если бы это был командлет:
Do-Something
Командлет Write-Output – это верный способ извлечения выходных данных из функции. Этот командлет с псевдонимом Write отправляет объекты в конвейер, где они могут быть использованы другими командлетами. Существует три способа использования Write-Output. Предположим, вы имеете выходные данные в виде переменной с именем $var. Все три примера будут идентичными с функциональной точки зрения:
Write-Output $var
Write $var
$var
Помимо этого, функция может возвращать выходные данные, используя ключевое слово Return:
Return $var
Return является особенным в том плане, что он передает все, что получает в конвейер, после чего незамедлительно закрывает функцию.
Не используйте Write-Host для извлечения выходных данных из функции. Write-Host не передает данные в конвейер, напротив, он отправляет текст напрямую в окно консоли. Текст нельзя передать по конвейеру другому командлету, а значит, возможность повторного использования функции ограничивается.
Параметризованные функции
Параметризованная функция принимает базовую функцию и добавляет возможность передавать информацию в функцию. Как правило, функция не должна иметь жестко запрограммированных параметров, таких как имена компьютеров или имена пользователей. Вместо этого функции должна принимать эту информацию в качестве входящих данных – таким образом функция подойдет для использования в большем количестве ситуаций.
Существует два способа определить входящие параметры функции. Первый – это часть указание их как части функции:
Function Do-Something ($computername,$domainname) {
# function code goes here
}
На заметку: Старайтесь указывать имя функции в виде «глагол-существительное в единственном числе», так же, как это делается с командлетами. Однако следите за тем, чтобы случайно не присвоить функции имя существующего командлета.
Второй, и более предпочтительный способ определения входящих параметров функции выглядит так:
Function Do-Something {
Param(
$computername,
$domainname
)
# function code goes here
}
Этот метод предпочтительнее потому, что он легче читается, а также потому, что здесь используется условное обозначение, применяемое оболочкой для сохранения функции в памяти. Обратите внимание, что жестких правил форматирования здесь нет – вы также можете использовать следующую форму:
Function Do-Something {
Param($computername,$domainname)
# Function code goes here
}
Вынесение каждого параметра в отдельную строку упрощает чтение. Особенно, если вы следуете рекомендациям по оформлению входящих данных и значений по умолчанию для ваших параметров:
Function Do-Something {
Param(
[string]$computername = ‘localhost’,
[string]$domainname = ‘contoso.com’
)
# function code goes here
}
Так же, как и в случае с параметризованными скриптами, вы можете обозначить параметры, значения по умолчанию которых будут выдавать пользователю подсказки или сообщения об ошибке, если значение не обеспечивается:
Function Do-Something {
Param(
[string]$computername = $(Read-Host ‘Computer name’),
[string]$domainname = $(throw ‘Domain name required.’)
)
# function code goes here
}
Когда вы запускаете параметризованную функцию, вы можете передавать входящие значения с помощью:
Do-Something localhost ‘contoso.com’
Обратите внимание, что параметры не разделяются запятой, как в других языках программирования; функции, как и командлеты, разделяют параметры пробелами. Также вы можете передать входящие значения, используя имена параметров, что позволяет располагать параметры в любом порядке:
Do-Something –domainname contoso –computername localhost
Передача данных конвейером
Итак, вы узнали, как передать входящие значения функции с помощью параметров. Но функции также могут принимать данные по конвейеру. В нормальной параметризованной функции оболочка автоматически входящие по конвейеру данные в специальную переменную, которая называется $input. Указывать $input в качестве параметра не нужно. Однако имеет смысл перечислить элементы в $input, так как зачастую она содержит несколько объектов. Для этого лучше всего использовать конструкцию ForEach. Например:
function Do-Something {
param (
$domain = ‘contoso.com’
)
foreach ($computer in $input) {
write «Computer $computer is in domain $domain»
}
}
‘localhost’,’server1′ | do-something -domain adatum
Обратите внимание, что входящие по конвейеру данные о двух именах компьютера помещаются в $input, тогда как «adatum» помещается в стандартный параметр $domain.
Это лишь один из способов принятия функцией входящих данных по конвейеру. Более эффективным и легким способом является использование фильтров.
Функции-фильтры
Функции-фильтры предназначены специально для приема входящих данных из конвейера. Такая функция включает в себя три именованных скриптовых блока:
• BEGIN: этот блок выполняется один раз при обращении к функции. Вы можете использовать его для выполнения любой задачи по настройке, которую требует функция, например, для соединения с базой данных.
• PROCESS: этот блок выполняется один раз для каждого объекта, входящего по конвейеру. Внутри блока специальная переменная $_ содержит текущий объект.
• END: этот блок выполняется один раз, после того как все входящие объекты были обработаны. Его можно использовать для завершения работы, например, для закрытия базы данных.
Необязательно использовать все три скриптовых блока – включайте в ценарий только те, которые вам необходимы. Некоторые администраторы предпочитают включать все три блока, даже если некоторые из них не используются – это тоже допустимо. Например:
function Do-Something {
param (
$domain = ‘contoso.com’
)
BEGIN {}
PROCESS {
$computer = $_
write «Computer $computer is in domain $domain»
}
END {}
}
‘localhost’,’server1′ | do-something -domain adatum
Скриптовый блок PROCESS обычно работает так же, как встроенная конструкция ForEach, автоматически перечисляя входящие объекты, и помещая каждый объект по очереди в переменную $_. Обратите внимание, что обычные параметры тоже поддерживаются.
Cамостоятельное конструирование выходных данных
Функции-фильтры, с которыми вы только что познакомились, запускали команды Windows PowerShell и позволяли этим командам помещать выходные данные в конвейер. Таким образом, выходные данные этих команд превращались в выходные данные функций. Например, в предыдущих примерах сюда входили одно или два обращения к Get-WmiObject.
Windows PowerShell не всегда хорошо справляется с отображением выходных данных, когда в конвейере содержится несколько разных типов объектов, например, Win32_OperatingSystem и Win32_BIOS одновременно. Одним из способов исправления ситуации может стать самостоятельное конструирование выходных данных. Например, вы можете вывести текст и сформировать заголовки столбца, а затем заполнить каждую строку выходными данными. Windows PowerShell даже предлагает специального оператора форматирования –f, который упрощает процесс создания данных такого типа.
В двух предыдущих примерах выходными данными являлся текст, точнее, объекты String. Проблема здесь заключается в том, что текст сложно использовать повторно. Например, вам может понадобиться вывести данные в файл CSV, а не в текстовую экранную таблицу. Используя в качестве отправной точки два вышеописанных подхода, вы будете вынуждены переписывать часть функции, чтобы вывести данные в файл CSV. А если позже вам понадобятся выходные данные в формате XML, вы будете переписывать ее снова.
Как вы уже знаете, Windows PowerShell – это объектоориентированная оболочка, которая работает с объектами гораздо лучше, чем с текстом. В двух предыдущих примерах извлекались два класса WMI: Win32_OperatingSystem и Win32_BIOS. Поскольку это два разных класса, оболочка не может просто отобразить их в одной строчке таблицы – по крайней мере, с использованием средств форматирования, предлагаемых по умолчанию. Решением может стать вывод данных в виде текста, но, как мы знаем, это не лучший способ для Windows PowerShell.
Еще одним способом скомбинировать информацию разных типов может стать создание пустого пользовательского объекта:
$obj = New-Object PSObject
«PSObject» – это очень простой объект, который выступает в роли пустого, чистого холста или полотна. Ему можно придавать любые свойства. Например, свойство ComputerName добавляется следующим образом:
$obj | Add-Member NoteProperty ComputerName $computername
Таким образом добавляется новое свойство типа NoteProperty. NoteProperty – это статическое значение, придаваемое объекту. Новое свойство NoteProperty называется ComputerName, а его значением может быть все, что вы поместите в переменную $computername.
Вы можете добавлять свойства до тех пор, пока объект не примет всю необходимую вам информацию. Затем вы отправляете этот пользовательский объект в конвейер:
Write $obj
Так как вы отправляете в конвейер всего один объект, Windows PowerShell может с легкостью сформировать выходные данные. Также вы можете передать этот объект другим командлетам для того, чтобы сформировать CSV-файл, затем HTML, и.т.д. Используя выходные данные функции в виде объектов, вы упрощаете использование этой функции в дальнейшем в различных ситуациях.
Разные способы решения
По мере того, как вы будете изучать примеры использования Windows PowerShell из разных источников, в том числе, из Интернета, вы все чаще будете осознавать, что одну и ту же задачу можно выполнить разными способами.
Так, в предыдущем примере вы видели, как с помощью New-Object и Add-Member можно создать новый пользовательский объект. Еще одним подходом является использование Select-Object для придания пользовательских свойств новому пустому объекту:
function Get-Inventory {
PROCESS {
$computer = $_
$os = gwmi win32_operatingsystem -comp $computer
$bios = gwmi win32_bios -comp $computer
$obj = new-object psobject
$obj | select @{Label=’ComputerName’;Expression={$computer}},
@{Label=’SPVersion’;Expression={$os.servicepackmajorversion}},
@{Label=’BIOSSerial’;Expression={$bios.serialnumber}},
@{Label=’BuildNo’;Expression={$os.buildnumber}}
}
}
gc names.txt | get-inventory
Нельзя сказать, что какой-то один из этих подходов является верным – они оба работают и оба обеспечивают одни и те же результаты. Так что можете смело использовать тот, который кажется вам более удобным. Когда вы лучше познакомитесь с работой Windows PowerShell, вы поймете, что многие задачи можно выполнить с помощью одной-единственной команды, хотя эта команда может быть довольно сложной. Например, всю функцию Get-Inventory, показанную ранее, можно заменить одной сложной командой:
gwmi win32_operatingsystem -computer (gc names.txt) |
select @{Label=’ComputerName’;Expression={$_.__SERVER}},
@{Label=’BuildNo’;Expression={$_.BuildNumber}},
@{Label=’SPVersion’;Expression={$_.ServicePackMajorVersion}},
@{Label=’BIOSSerial’;Expression={
(gwmi win32_bios -comp $_.__SERVER).serialnumber
}}
Здесь первым запускается командлет Get-WmiObject. Его параметр –computerName получает выходные данные Get-Content, который читает текстовый файл, содержащий по одному имени компьютера в каждой строчке. WMI объект передается командлету Select-Object.
Первые три элемента в Select-Object создают пользовательские свойства объекта, которые используют свойства из Win32_OperatingSystem WMI объекта. Смысл этого – обеспечить пользовательские имена свойств, такие как ComputerName и BuildNo вместо того, чтобы использовать родные имена свойств класса WMI. Последний элемент в Select-Object создает пользовательское свойство, которое называется BIOSSerial. Это выражение свойства в действительности выполняет второй командлет Get-WmiObject для извлечения класса Win32_BIOS. Имя компьютера, передаваемое в этот Get-WmiObject, будет свойством __SERVER первого WMI объекта – это свойство содержит имя компьютера. Обратите внимание, что вся команда Get-WmiObject помещена в скобки – это заставляет оболочку выполнять команду, а скобки обозначают объект, который получится на выходе. Вслед за скобками идет точка, которая указывает на то, что мы хотим получить доступ к одному из элементов объекта, а затем имя этого элемента SerialNumber. Конечным результатом является то, что свойство SerialNumber объекта Win32_BIOS помещается в пользовательское свойство BIOSSerial в Select-Object.
Конечно, это сложная команда, но она наглядно демонстрирует, что Windows PowerShell позволяет выполнять сложные задачи без формального написания скриптов и программирования. Для прочтения и, тем более, написания такой команды, однако, требуется некоторый опыт. Поэтому вы вправе выбрать для себя такой способ работы, который вам кажется проще.
Расширенные функции
Расширенная функция является чуть более «продвинутой» по сравнению с функцией-фильтром. Точнее говоря, расширенная функция – это функция-фильтр, которая имеет дополнительные атрибуты для параметров, которые принимают входящие данные. За счет этих атрибутов расширенные функции выглядят и ведут себя практически так же, как командлеты, написанные на языке .NET Framework. Так указывается функция и параметр для очень простой расширенной функции:
function Get-ComputerDetails {
[CmdletBinding()]
param (
[parameter(Mandatory=$true,ValueFromPipeline=$true)]
[string[]]$computername
)
BEGIN {}
PROCESS {
Вы заметите, что главное различие между расширенной функцией и фильтром заключается в наличии дополнительных атрибутов, таких как [CmdletBinding()], [parameter] и так далее. В данном примере параметр $computername был создан для приема одной или нескольких строк в качестве входных данных из конвейера, и является обязательным. При использовании этой технологии переменная $_ внутри блока PROCESS не является обязательной. Вместо нее входные данные могут помещаться в параметр $computername. Скриптовый блок PROCESS помещает один входящий объект в параметр $computername за один раз и выполняется один раз для каждого объекта.
Расширенные функции являются завершающим элементом модуляризации в Windows PowerShell: использование атрибутов параметров, которые выглядят как командлеты, позволит вам написать структуру, которая будет действовать практически так же, как и настоящие командлеты оболчки. При желании вы даже можете поместить справочник в функцию – как это сделать, вы узнаете в следующих разделах.
На заметку: Подробное изучение расширенных функций выходит за рамки данного курса. Однако вы можете найти более подробную информацию о них в интернете, и попытаться изучить ее самостоятельно.
Visual Basic Scripting Edition (обычно просто VBScript) — скриптовый язык программирования, интерпретируемый компонентом Windows Script Host. Он широко используется при создании скриптов в операционных системах семейства Microsoft Windows.
VBScript был создан компанией Microsoft как замена устаревшему пакетному языку, интерпретируемому приложением command.com.
Область применения[]
Скрипты на языке VBScript чаще всего применяются в следующих областях, использующих продукцию Microsoft:
- автоматизация администрирования систем Windows;
- серверный программный код в страницах ASP;
- клиентские скрипты в браузере Internet Explorer.
Такой тип сценариев обычно используется для:
- создания сложных сценариев;
- использования объектов из других приложений и библиотек;
- скрытия окон в ходе выполнения сценария;
- шифрования логики сценария.
В основном VBS-сценарии применяются для обработки данных, управления системой, работы с учетными записями пользователей и компьютеров, взаимодействия с офисными приложениями, работы с базами данных и прочих сложных задач.
VBS-сценарий — это обычный текстовый файл с расширением *.vbs, который легко править в блокноте, а запускать на исполнение — двойным щелчком мыши или вызовом по имени в консоли.
Сценарии не компилируются, а интерпретируются. То есть для обработки скрипта в системе должен присутствовать интерпретатор языка VBS, и таких интерпретаторов в Windows два: оконный WScript и консольный CScript, оба интерпретатора это Windows Script Host (WSH).
Правила языка[]
В Visual Basic работают следующие правила:
- длина строки не ограничена;
- регистр символов не учитывается;
- количество пробелов между параметрами не учитывается;
- строку команды можно разрывать, а на месте разрыва нужно вставлять символ «_»;
- максимальная длина имени переменной 255 символов;
- комментарии обозначаются символом «’».
- несколько строк можно объединять в одну, предварительно разделив их символом «:»
Переменные[]
По умолчанию переменные в сценариях объявляются автоматически при первом использовании в теле скрипта, если это не запрещено директивой Option Explicit. Если же в начале сценария объявить директиву Option Explicit, то все переменные нужно определять заранее с помощью следующих конструкций:
Dim ValueName1 ' переменная, доступная всем подпрограммам; Public ValueName2 ' переменная, доступная всем подпрограммам; Private ValueName3 ' переменная, доступная только текущей программе и её подпрограммам;
Константы объявляются в начале сценария с помощью конструкции:
Const ConstName1 = Value1 ' константа, доступная всем подпрограммам; Public Const ConstName2 = Value2 ' константа, доступная всем подпрограммам; Private Const ConstName3 = Value3 ' константа, доступная только текущей программе и её подпрограммам;
Тип переменной присваивается автоматически после внесения в неё первого значения. В Visual Basic существуют следующие типы данных:
- empty — неинициализированная переменная;
- null — пустая переменная;
- boolean — логический тип, возможные значения: False, True или 0, 1;
- byte — 8-битное целое число без знака, возможные значения: 0 .. 255;
- integer — 16-битное целое число, возможные значения: −32768 .. 32767;
- long — 32-битное целое число, возможные значения: −2147483648 .. 2147483647;
- currency — денежный тип, возможные значения: −922337203685477,5808 до 922337203685477,5807;
- single — число с плавающей точкой, возможные значения: −3.402823e38 .. −1.401298e-45 для отрицательных чисел и 1.401298e-45 .. 3.402823e38 для положительных чисел;
- double — число с плавающей точкой, возможные значения: −1.79769313486232e308 .. −4.94065645841247e-324 для отрицательных чисел и 4.94065645841247e-324 .. 1.79769313486232e308 для положительных чисел;
- date — дата, возможные значения: 01.01.1900 .. 31.01.9999;
- string — строковая переменная, вместимость до 2 миллиардов символов;
- object — указатель на объект;
- error — код ошибки.
В VBS-сценариях возможно использование массивов переменных, которые позволяют хранить списки, таблицы и даже более сложные конструкции. Одномерные массивы (списки) могут быть динамическими, то есть они позволяют изменять свой размер в ходе работы сценария. Все массивы объявляются командой Dim:
Объекты, их методы и свойства[]
VBScript, как и их родитель — язык Visual Basic, является объектно-ориентированным языком программирования, то есть основной концепцией является понятие объектов и классов
Класс — это тип, описывающий устройство объектов. Объект подразумевает под собой нечто, что обладает определённым поведением и способом представления, объект — это экземпляр класса. Класс можно сравнить с чертежом, согласно которому создаются объекты. Обычно классы разрабатывают таким образом, чтобы их объекты соответствовали объектам предметной области.
Все объекты, с которыми работает Windows Script Host, имеют методы и свойства. Чтобы обратиться к методу, необходимо указать объект, а через точку — метод с необходимыми параметрами.
Аналогичная ситуация со свойствами, но свойства можно как назначать, так и считывать в переменные и другие свойства, правда, следует учитывать тип данных переменных и свойств, иначе сценарий выдаст ошибку несовместимости типов данных.
Пример[]
Вот пример небольшой программы на языке VBScript, которая выводит диалоговое окно с сообщением (символы после знака апостроф являются комментариями):
' Объявление переменной: Dim strMessage ' Присваивание переменной значения: strMessage = "Википедия — свободная энциклопедия" ' Вывод окна с сообщением: MsgBox strMessage
По эффекту работы она аналогична прямой инструкции
MsgBox "Википедия — свободная энциклопедия"
См. также[]
- Visual Basic for Applications
- JScript — альтернативный скриптовый язык, созданный компанией Microsoft на основе EcmaScript
Ссылки[]
- VBScriptШаблон:Ref-en — Руководство по VBScript от Майкрософт.
- The Script Center Script RepositoryШаблон:Ref-en — Коллекция скриптов на VBScript от Майкрософт.
Компоненты Microsoft Windows | |
---|---|
Основные |
Aero • |
Службы управления |
Архивация и восстановление • |
Приложения |
Контакты • |
Игры |
Chess Titans • |
Ядро ОС |
Ntoskrnl.exe • |
Службы |
Autorun.inf • |
Файловые системы |
ReFS • |
Сервер |
Active Directory • |
Архитектура |
NT • |
Безопасность |
BitLocker • |
Совместимость |
Подсистема UNIX (Interix) • |
Шаблон:Microsoft APIs
Scripting languages are a specific kind of computer languages that you can use to give instructions to other software, such as a web browser, server, or standalone application. Many of today’s most popular coding languages are scripting languages, such as JavaScript, PHP, Ruby, Python, and several others.
As scripting languages make coding simpler and faster, it’s not surprising that they are widely used in web development.
However, that’s not their only field of application. There are also scripting languages for operating systems, statistical analysis software, office applications, game engines, and many other kinds of platforms.
What Are Scripting Languages?
Scripting languages can perform different actions within a particular runtime environment, such as automating task execution, enhancing the functionality of the parent software, performing configurations, extracting data from data sets, and others.
Scripting languages can come about in two ways:
- A runtime environment can introduce its own scripting language, such as Bash for the GNU operating system or VBA for Microsoft Office applications.
- A runtime environment can adopt an existing scripting language, for instance, MongoDB’s
mongo
shell has been built around JavaScript.
On the other hand, sometimes it’s the scripting language that exists first and it gives birth to its own parent platform — however strange that may sound.
This is what happened in the case of Node.js, a backend runtime environment that was created to allow web developers to use JavaScript not just on the frontend but also on the backend, following the ‘JavaScript everywhere’ paradigm.
If you’re thinking about learning a new scripting language, check out this guide to the top 13 options 💻….then get to studying 🤓Click to Tweet
What Does Scripting Mean in Programming?
The action of scripting is essentially writing a series of commands that are interpreted one by one by an application or scripting engine. Even though the script guides the platform through what to do (gives it a script to read and interpret), the execution is performed by the runtime environment and not by the scripting language itself.
This is how scripting languages are different from programming languages such as Java that you can ‘write once, run anywhere’ (official Java slogan meaning Java programs can run as standalone applications in any environment; since being coined it has also become the WORA principle that refers to cross-platform capabilities).
Scripting Languages vs Programming Languages
Although the terms ‘scripting language’ and ‘programming language’ are frequently used interchangeably, they are not the same thing.
Platform-Specific vs Platform-Agnostic
Scripting languages are platform-specific, while programming languages are platform-agnostic (cross-platform) as they have the ability to execute themselves. For instance, you can run a Java program on any operating system.
(Mostly) Interpreted vs Compiled
While programming languages are compiled, scripting languages are mostly interpreted — even though there are some scripting languages that are both compiled and interpreted, such as Python and Groovy.
‘Compiled’ means that a programming language has its own compiler that translates the syntax into machine code before runtime. In contrast, scripting languages are interpreted line by line during runtime by the interpreter of the platform they are running on.
Faster vs Slower at Runtime
Because of this difference in implementation, programming languages run faster than scripting languages as they don’t have to be compiled in real-time. Compilers also perform collective error handling before execution, while interpreters evaluate code line by line, so they pause (or completely stop) every time they encounter an error.
This also adds to the total execution time of scripting languages, even though on modern and faster hardware, this is less of an issue than it was before.
More vs Less Code-Intensive
Programming languages are more code-intensive as you have to do many things manually that are handled by the platform in the case of scripting languages. If you use a scripting language you have to write much less code.
Standalone Apps vs Apps as Part of a Stack
There are some things that you simply can’t do with a scripting language. Most importantly, you can’t create standalone desktop and mobile applications with a scripting language, as there’s no runtime environment that interprets them.
For instance, you can use PHP frameworks such as WordPress and Laravel only for websites and web applications because they use the web browser as their runtime environment. Similarly, WordPress mobile apps run within mobile runtime environments, such as Capacitor, that incorporate web views.
Scripting vs Programming Languages — Differences Overview
So the main differences between scripting vs programming languages are as follows:
Scripting languages | Programming languages |
Platform-specific | Platform-agnostic (cross-platform) |
(Mostly) interpreted | Compiled |
Slower at runtime | Faster at runtime |
Less code-intensive | More code-intensive |
Creates apps as part of a stack | Creates standalone apps |
Confusions About Scripting Languages
There are some confusions about scripting languages that you’ll frequently run into, so let’s have a look at them before getting into the best scripting languages.
Most importantly, it doesn’t make much sense to speak about frontend vs backend scripting languages, even though many articles you’ll find all over the web use this kind of grouping.
There’s actually just one frontend scripting language currently in use, and that’s JavaScript (there existed other ones before, such as ActionScript and JScript, but now all are deprecated).
It’s not frontend vs backend that’s important in the context of scripting languages but the runtime environment(s) where a scripting language can run.
Note that ‘frontend’ just means something (image, font, markup, stylesheet, script, another type of static file) that a web browser can interpret. For instance, try to open a PHP file directly from the web browser: you can’t, because a PHP application server has to interpret it — so PHP is a backend scripting language in the context of web development, while the application layer of a server stack (e.g. LAMP) in the context of scripting languages.
Besides web development (frontend and backend scripting), scripting languages can also be used for multiple things such as programming and configuring operating systems and specific applications/environments, manipulating data sets, automating tasks, and many others.
A scripting language can run in multiple environments, too.
What Are Not Scripting Languages
Before getting into the best scripting languages, let’s see the coding languages that are sometimes falsely called scripting languages, but you can’t script with them:
- Markup languages, such as HTML and XML. In HTML, there are attributes for event handling such as onclick and onmouseover, but these are still JavaScript callbacks.
- Stylesheet languages, such as CSS, Sass, and LESS.
- Any kind of library or framework built on top of any scripting language, such as jQuery, PostCSS, React, Vue, Angular, Rails, Grails, Django, Laravel, WordPress, and others.
- Languages that are compiled into a scripting language, such as TypeScript and CoffeeScript.
- SQL as it’s for managing data in relational database management systems (RDBMS) such as MySQL and MariaDB. They don’t let you write dynamic functionality. However, many RDBMSs have shells that let you use a scripting language (e.g. JavaScript or Python in the MySQL Shell).
- Runtime environments for one or more scripting languages, such as NodeJS.
13 Best Scripting Languages
There are many great scripting languages that would deserve a mention in this guide, but they are not in active development anymore. However, the following 13 scripting languages are regularly updated and also being used in production.
So if you are thinking about learning a new scripting language as a new professional path, they are all worth a shot.
1. JavaScript/ECMAScript
JavaScript is an implementation of the ECMA-262 standard that defines the ECMAScript (ES) general-purpose scripting language. In other words, JavaScript is a dialect of the ECMAScript language, therefore it doesn’t have a standalone specification but uses the same syntax as ECMAScript.
JavaScript has first-class functions (functions are treated as variables) and supports prototype-based object-oriented programming (existing objects are reused as prototypes).
Code Example
ECMAScript uses a curly bracket syntax. The following JavaScript code example adds numbers from 1 to 10 together and outputs the result into the console (you can test it in your web browser’s JavaScript console by hitting F12):
let total = 0, count = 1;
while (count <= 10) {
total += count;
count += 1;
}
console.log(total);
// 55
Source: Eloquent JavaScript by Marijn Haverbeke: Introduction
Use Cases and Environments
JavaScript is the scripting language used by modern web browsers, such as Chrome’s V8 engine and Mozilla’s SpiderMonkey engine. Besides, frontend web development, it can be used in non-browser environments as well. The NodeJS runtime environment has been created to enable web developers to use it on the backend.
The shells of some NoSQL database management systems, such as MongoDB and Apache CouchDB, and some relational database management systems, such as the aforementioned MySQL Shell, also use it as a scripting language.
2. PHP
PHP is a general-purpose, open source scripting language used in backend web development. The acronym originally stood for ‘Personal Home Page’, as PHP was first created to add dynamic functionalities to static HTML pages.
Since then, PHP has evolved into a standalone language, so now the acronym is used in the sense of ‘Hypertext Preprocessor’. PHP is loosely typed (you don’t have to declare the data types of variables), can be embedded into HTML documents, and has object-oriented features too.
Code Example
PHP has a C-like syntax. The following PHP code example creates a numeric array with four elements, loops through them, multiples each item by two, and unsets the $value
variable when the loop is over.
<?php
$arr = array(1, 2, 3, 4);
foreach ($arr as &$value) {
$value = $value * 2;
}
// $arr is now array(2, 4, 6, 8)
unset($value);
?>
Source: PHP documentation: Control Structures
Use Cases and Environments
PHP can be executed on different HTTP servers, with Apache and Nginx being the most popular ones.
The most common PHP server stacks are LAMP (Linux, Apache, MySQL, PHP), LEMP (Linux, Nginx, MySQL, PHP — used by Kinsta), and WAMP (Windows, Apache, MySQL, PHP), and MAMP (macOS, Apache, MySQL, PHP).
It’s also used by many popular content management systems (CMS) such as WordPress, Drupal, and Joomla, and web application frameworks such as Laravel, Symfony, and CodeIgniter, that are all built on top of the PHP language and enhance it with extra functionalities.
You can use PHP for local WordPress development, too. Check out our in-depth guide on the main differences between Javascript and PHP.
3. Python
Python is currently the second most popular coding language on GitHub (after JavaScript). It’s loved for its clear and concise syntax — when coding in Python, you have to type much less than in most languages.
Python is a free and open source project, managed by the Python Software Foundation. It supports the structured, object-oriented, and functional programming paradigms, and has an extensive Standard Library that is a collection of commonly used Python modules.
Code Example
Python doesn’t use curly brackets and semicolons are optional, so the code is easy to read and write. The following Python code example loops through integers between 0 and 4, and prints them out:
count = 0
while count < 5:
print(count)
count += 1
Source: Learn Python: Loops
Use Cases and Environments
The most popular Python implementation is CPython, written in the C language. It’s also the reference implementation that you download together with the Python language. Even though Python is an interpreted language, CPython uses both a compilation and interpretation step. First, it compiles the source code into bytecode (not the same as machine code) that it interprets at runtime.
Besides CPython, Python has other runtime environments as well, most importantly PyPy that omits the compilation step and only does JIT (just-in-time) interpretation. Python implementations are cross-platform, meaning they run on multiple operating systems, including Linux, Windows, and macOS.
The Python language is frequently used in machine learning, backend web development (Django being the most popular web framework), data analytics, automation, scientific computing, and web scraping.
To find out the best way to learn Python, check out our blog post on Python tutorials.
4. Ruby
Ruby is an open source, general-purpose scripting language with a compact and easy-to-read syntax. It follows the principles of object-oriented programming and lets you write clean and logical code, making it one of the easiest programming language to learn. In Ruby, everything is an object — even types that are primitives in most languages, such as booleans and integers.
Object-oriented concepts such as inheritance, mixins, and metaclasses are also heavily used.
Although Ruby has a purely object-oriented design, it also supports procedural programming (functions and variables defined outside of classes belong to the Self
object) and functional programming (through anonymous functions, closures, and continuations).
Code Example
Ruby has a concise syntax similar to Python. The following Ruby code example defines the KaraokeSong
class as a subclass of the Song
class:
class KaraokeSong < Song
def initialize(name, artist, duration, lyrics)
super(name, artist, duration)
@lyrics = lyrics
end
end
Source: Programming Ruby reference guide: Classes, Objects, and Variables
Use Cases and Environments
Ruby is mainly used in backend web development, powering some robust web application frameworks such as Ruby on Rails. Many popular websites and applications run on Ruby on Rails, such as Airbnb, Shopify, GitHub, and Hulu.
Ruby is also the language many popular web development tools are written in, most notably the Sass CSS preprocessor, the Jekyll static website generator, and the Vagrant virtual machine environment.
The default implementation of Ruby is YARV (Yet Another Ruby Virtual Machine). It changed Ruby’s original interpreter Matz’s Ruby Interpreter (also Ruby MRI or CRuby) that had been criticized for issues with speed and scalability.
There are also several competing runtime environments for Ruby, such as JRuby (lets you run Ruby on the Java Virtual Machine), mruby (a lightweight implementation that you can embed within your application), TruffleRuby (Oracle’s Ruby interpreter built on GraalVM), Rubinius (a cloud-native virtual machine for Ruby), and others.
5. Groovy
Groovy is an incredible flexible language written for the Java Virtual Machine (JVM) that can be used both as a scripting and programming language. It’s an open source project maintained by the Apache Software Foundation. Groovy is an object-oriented language that extends the java.lang.Object
superclass.
It supports both static and dynamic typing (type checking can be performed both at compile time and runtime) and has native support for lists, associative arrays, regular expressions, and markup languages such as HTML and XML.
You can use Groovy together with existing Java libraries.
Code Example
Groovy has a Java-compatible syntax, using curly brackets. The following Groovy code example defines the Coordinates
class with the latitude and longitude properties and the getAt()
method:
@Immutable
class Coordinates {
double latitude
double longitude
double getAt(int idx) {
if (idx == 0) latitude
else if (idx == 1) longitude
else throw new Exception("Wrong coordinate index, use 0 or 1")
}
}
Source: Groovy Documentation: Semantics
Use Cases and Environments
As Groovy compiles into Java byte code, you can use it as a general-purpose programming language similar to Java. In this case, you can compile the source code into byte code before runtime using the groovyc compiler (the equivalent to javac).
However, there are also many Groovy implementations that let you use it as a scripting language. The most popular ones are the Grails web application framework (formerly known as Groovy on Grails) and the Gradle build automation tool, but there are several others too.
6. Perl
Perl is a general-purpose scripting language that’s been around for more than thirty years (since 1987). Originally, it was created as a UNIX scripting language for report processing. That’s also where its name comes from, as the Perl acronym standing for ‘Practical Extraction and Reporting Language’.
The Perl language became popular in the 1990s when programmers began to widely use it for CGI (Common Gateway Interface) scripting, which is an older interface specification for web servers (currently, it’s mainly used by legacy sites).
Despite being a relatively early player, Perl is still the 11th on the TIOBE index and the 21st most popular language on GitHub (as of October 2020).
Code Example
Perl’s syntax is similar to the C language. The Perl code example below first defines the square()
subroutine that calculates and returns the square of a number, then passes the value 8 as an argument, runs the subroutine, and saves the result into the $sq
variable:
sub square {
my $num = shift;
my $result = $num * $num;
return $result;
}
$sq = square(8);
Source: Perl docs: Perl Intro
Use Cases and Environments
Even though these days it’s not the most frequent choice of web developers, Perl can be successfully used in backend development. Besides the CGI runtime environment, it also executes on the Apache and Nginx web servers — the LAMP stack is actually LAMPP, standing for Linux, Apache, MySQL, PHP, and Perl.
There also exist some Perl web development frameworks, with Catalyst, Mojolicious, and Dancer being the most popular ones.
Perl is used by several notable websites and applications such as Amazon, IMDB, Booking.com, and the BBC iPlayer. It’s used in other areas, too, such as network programming and system administration. You can also check out the Comprehensive Perl Archive Network (CPAN) where 25,000+ open-source Perl projects are available for you to download.
7. Lua
Lua is a fast and lightweight scripting language. The word ‘lua’ means ‘moon’ in Portuguese, as the language is developed and maintained by the Pontifical Catholic University of Rio de Janeiro in Brazil. Lua supports the procedural, object-oriented, and functional programming paradigms.
As Lua’s interpreter is written in C, it can be easily embedded into applications using its C API. That being said, you can use Lua to extend existing applications written in C-based languages such as C, C++, C#, Java, Perl, Ruby, and others.
Code Example
Lua has a concise and easy-to-read syntax, similar to Python and Ruby. The following Lua code example shows how to use the if-then-else
statement. First, it evaluates the op
variable, then performs basic arithmetic operations depending on its value:
if op == "+" then
r = a + b
elseif op == "-" then
r = a - b
elseif op == "*" then
r = a * b
elseif op == "/" then
r = a / b
else
error("invalid operation")
end
Source: Programming in Lua reference guide: Statements
Use Cases and Environments
The default Lua implementation doesn’t interpret source code directly but first compiles it into byte code that it later executes on the Lua virtual machine. As all this happens at runtime, there’s no manual compilation step you need to perform (even though you can opt for compiling Lua before runtime to improve performance).
There are other Lua implementations as well, such as LuaJIT, LuaVela, and many others.
Lua is frequently used to develop video games, such as Angry Birds, World of Warcraft, and Grim Fandango. As it’s easy to embed, it’s also a frequent choice for embedded devices such as set-top boxes, instrument panels of cars (e.g. Volvo), IP cameras (e.g. Cisco), and others.
It can also be used in web development, as both Apache and Nginx servers have a Lua module (here’s Apache’s mod_lua, and here’s Nginx’s ngx_http_lua_module). Wikipedia chose Lua as its template scripting language, and the UI of Adobe Photoshop Lightroom is written in Lua as well.
8. Bash
Bash is the name of both a command-line interpreter (shell) for the GNU operating system and the belonging scripting language. ‘Linux’ is, in fact, the GNU operating system using the Linux kernel (a kernel is the core part of the OS, it’s the first program that the operating system loads).
It’s a replacement for the original UNIX Bourne shell (sh) — the Bash acronym stands for ‘Bourne Again SHell’ (a pun on ‘born again shell’).
Besides being the superset to the Bourne shell syntax, Bash also includes features from other shell scripting languages such as KornShell (ksh) and C shell (csh) — for example, command-line editing and command history. You can use Bash in an interactive mode (executing one command at a time and waiting for the machine’s reply) and scripting mode (running a set of commands — a Bash script — at once).
Code Example
Like most CLI scripting languages, Bash has a simple and descriptive syntax. The following Bash code example selects a file from the current folder and outputs a message containing the name and index of the file:
select fname in *;
do
echo you picked $fname ($REPLY)
break;
done
Source: Bash Reference Manual: Conditional Constructs
Use Cases and Environments
You can use Bash to make changes and perform different actions related to your operating system, such as executing commands, carrying out tasks that most people would do using a graphical user interface (e.g. creating, moving, or deleting folders and files), customizing and automating administrative tasks, connecting to a remote server, and many others.
Bash is the default shell for many Unix-based operating systems, including most Linux distros and all macOS releases up to macOS Catalina that replaced Bash with Z shell (Zsh) in 2019. You can also run Bash scripts on Windows 10, using the Windows Subsystem for Linux (WSL) compatibility layer developed by Microsoft.
9. PowerShell
Originally, PowerShell was a command-line shell and scripting language solely for the Windows operating system. Since then, Microsoft open sourced and moved it from the .NET Framework, which can create only Windows applications, to .NET Core, which can create applications for Windows, Linux, and macOS. This means PowerShell is now cross-platform.
It has also been renamed from Windows PowerShell to PowerShell Core, corresponding to the underlying framework. Unlike most command-line shells, PowerShell accepts and returns .NET objects instead of plain text, which gives way to new opportunities in task automation.
Code Example
PowerShell has a compact syntax that makes working in the command line faster. The PowerShell code example below creates a backup of the boot.ini file and saves it to the boot.bak file:
Copy-Item -Path C:boot.ini -Destination C:boot.bak
Source: PowerShell Documentation: Working with Files and Folders
Use Cases and Environments
You can use PowerShell on the Windows, Linux, macOS operating systems, and some ARM devices (e.g. wearables, multimedia players, tablets, and other consumer electronic devices).
You can use PowerShell for system administration, task automation, and configuration management. To find PowerShell modules and scripts, you can check out the PowerShell Gallery and Microsoft’s official sample script collection, too.
10. R
R is both a software environment and scripting language that you can use for statistical computing, data analysis, and graphical display. It’s a free and open source GNU project and an implementation of the S statistical computing language (not in active development anymore).
R allows you to use many different statistical techniques such as classical statistical tests, clustering, time series analysis, linear and non-linear modeling, and others.
Code Example
R’s syntax is different from most scripting languages and has some unusual elements, too — for instance, the primary assignment operator is <-
instead of the =
equals sign and it has loopless loops — see more about the quirks of the R syntax in this beginner’s guide to R by Sharon Machlis.
The following R code example defines a names
attribute for the fruit
vector (basic data structure in R that contains elements of the same type) that uses alphanumeric names (orange
, banana
, apple
, peach
) to help identify its components. Later, the lunch
(or another) subvector can access each component using its alias name:
> fruit <- c(5, 10, 1, 20)
> names(fruit) <- c("orange", "banana", "apple", "peach")
> lunch <- fruit[c("apple","orange")]
Source: An Introduction to R: Index vectors; selecting and modifying subsets of a data set
Use Cases and Environments
The R software environment is cross-platform; you can run it on Windows, Linux, and macOS operating systems. The default R implementation is also available from some other scripting languages such as Python and Perl. This means that you can access all the statistical functionality of R using these scripting languages.
Besides the default R environment, you can use the R scripting language in other environments as well, such as pqR (stands for ‘a pretty quick version of R’) and Renjin (an R implementation on top of the Java Virtual Machine).
11. VBA
VBA stands for Visual Basic for Applications and it’s an implementation of the Visual Basic 6 programming language (not in active development since 2008). It has been created for Microsoft Office applications to enable developers to automate repetitive tasks, add new functionalities, and interact with the end users of documents.
Similar to Visual Basic, VBA follows the event-driven programming paradigm that puts events such as user actions into the center that drive the flow of the program.
As Microsoft Office applications have a graphical user interface, you can attach VBA scripts to menu buttons, keyboard shortcuts, macros (programmable patterns), and OLE events (Object Linking and Embedding that lets you control one application from another; it’s a proprietary Microsoft technology).
Code Example
As VBA is based on Visual Basic (which is an augmentation of BASIC), it uses a syntax similar to the languages of the BASIC (Beginners’ All-purpose Symbolic Instruction Code) family — which means it’s very beginner-friendly.
The VBA code example below uses the GetCertificateDetail()
method of the SignatureInfo
object to get the expiration date of a digital certificate:
Sub GetCertDetails()
Dim objSignatureInfo As SignatureInfo
Dim varDetail As Variant
strDetail = objSignatureInfo.GetCertificateDetail(certdetExpirationDate)
End Sub
Source: Office VBA Reference: SignatureInfo object
Use Cases and Environments
The VBA scripting language is embedded into most Microsoft Office applications, respectively Access, Excel, Office for Mac, Outlook, PowerPoint, Project, Publisher, Visio, and Word — each having a separate reference guide on Microsoft’s documentation site while general VBA concepts are detailed in the library reference.
Besides Microsoft Office applications, there are other apps that also support VBA, such as AutoCAD and CorelDRAW.
12. Emacs Lisp
Emacs Lisp is a domain-specific scripting language designed for the GNU Emacs text editor. It’s a dialect of the Lisp programming language family (the name comes from LISt Processor).
As Emacs Lisp has been designed to be used within a code editor, it comes with a feature set specific to that environment, such as text scanning and parsing, buffer (objects with editable text) and display management, and others.
The Emacs Lisp scripting language is closely integrated with the editor interface itself, so every command is also a Lisp function that you can call from your script, and customization parameters are Lisp variables as well.
Code Example
The syntax of Emacs Lisp is based on a fully parenthesized prefix notation that can be a bit hard to read at first if you haven’t worked with any Lisp language before.
The following Emacs Lisp code example defines two variables (symbols) and assigns a list of values to each — a list of trees (pine
, fir
, oak
, maple
) to the symbol trees
and a list of herbivores (gazelle
, antelope
, zebra
) to the symbol herbivores
:
(setq trees '(pine fir oak maple)
herbivores '(gazelle antelope zebra))
Source: An Introduction to Programming in Emacs Lisp: Setting the Value of a Variable
Use Cases and Environments
The Emacs text editor is a cross-platform application that you can install on Windows, Linux, and macOS machines.
Using the Emacs Lisp scripting language, you can extend and customize the code editor, repeat and automate processes, create graphs, restrict focus to specific areas (for security), search regular expressions, store text, define modes and keymaps, ask questions from users, and perform many other actions.
There are also some configuration frameworks for Emacs Lisp — Doom Emacs and Spacemacs being the most well-known ones.
13. GML
The acronym GML stands for GameMaker Language. It’s a good example of a domain-specific scripting language used in game development. GML is a proprietary scripting language belonging to GameMaker Studio 2, a cross-platform game engine and development platform owned and maintained by YoYo Games.
Even though GML is mainly used for controlling game objects, it’s not an object-oriented language but a procedural one. It allows you to call custom scripts from any game object.
Besides the GML scripting language, GameMaker Studio 2 also has a visual scripting tool called Drag and Drop (DnD). Due to the flexible nature of GameMaker Studio 2, you can mix DnD with your GML scripts, too.
Code Example
The syntax of GML is similar to JavaScript and other C-like languages.
The following GML code example makes a game object move horizontally towards the mouse pointer on the screen at a speed of 5 pixels per step. Once it reaches the current position of the pointer, the script creates an explosion effect layer, runs it (there’s an explosion effect on the screen), then destroys the instance (the explosion effect gets removed):
if mp_linear_step(mouse_x, mouse_y, 5, 0) {
instance_create_layer(x, y, "Effects", obj_Explosion);
instance_destroy();
}
Source: GameMaker Studio 2 Docs – Scripting – GML Reference – Movement and Collisions – Motion Planning
Use Cases and Environments
GML is interpreted by GameMaker Studio 2 that you need to purchase if you want to develop games in this scripting language.
Pricing depends on the platform you want to create games for — Mac and Windows games being the cheapest ones; cross-platform (Windows, macOS, Ubuntu) desktop games, HTML5 web games, UWP (Universal Windows Platform) games, and cross-platform (Android, Fire, iOS) mobile games being in the mid-tier; and PS4, Xbox One, and Nintendo Switch being the most expensive ones.
Some examples of video games created with GML include Blackhole, 10 Second Ninja X, Death’s Gambit, Deltarune, and several others.
Ready to learn another scripting language? 👩💻These 13 options are regularly updated and used in production, which makes them a great addition to your resume. 💼Click to Tweet
Summary
There’s no doubt that scripting languages are fascinating. They have many different variations, syntaxes, and implementations, and can be used for plenty of things.
From building dynamic websites, to automating system administration, to creating video games, and so forth.
The three most important things to remember about scripting languages are:
They can’t run on their own but always need an environment (implementation, runtime) with an interpreter for that scripting language.
Sometimes you can use general-purpose scripting languages to access environments and platforms primarily created for other programming or scripting languages. Think of JRuby (lets you run Ruby on the Java Virtual Machine), Renjin (R implementation also on the JVM), Rpy2 (R interface that you can use from Python), as good examples.
Finally, before learning a new scripting language, it’s always a good idea to check out its current popularity using the TIOBE index or GitHut.
Depending on it, you will also find more or fewer sample scripts, GitHub repositories, module libraries, reference guides, detailed manuals, and app showcases that will help you get started with the language… and get better-paid projects and jobs!
Get all your applications, databases and WordPress sites online and under one roof. Our feature-packed, high-performance cloud platform includes:
- Easy setup and management in the MyKinsta dashboard
- 24/7 expert support
- The best Google Cloud Platform hardware and network, powered by Kubernetes for maximum scalability
- An enterprise-level Cloudflare integration for speed and security
- Global audience reach with up to 35 data centers and 275 PoPs worldwide
Test it yourself with $20 off your first month of Application Hosting or Database Hosting. Explore our plans or talk to sales to find your best fit.