Доброго времени суток дорогие читатели. В данной статье мы познакомимся с основами Powershell. Данный язык программирования используется во всех ОС Microsoft начиная с Windows XP SP3. Писать Powershell скрипты должен уметь каждый уважающий себя системный администратор windows.
Все команды в Powershell как правило используются в форме командлетов. Все командлеты это специализированные классы .NET Framework и .NET Core (используется в PowerShell Core 6 и выше).
Powershell класса .NET Framework это версии с 1 по 5.1 а Powershell .NET Core это версия 6 и выше (на данный момент 7.0). По заявлению Microsoft новых функций в Powershell 5.1 (.NET Framework) вносить уже не будут. Однако 7 версия еще не полностью поддерживает все модули предыдущих версий. Но судя по всему Microsoft стремится к этому и скоро версия Core будет единственной. В общем cmd отходит в прошлое и теперь без Powershell никуда. Давайте приступим к практике. Так всегда лучше запоминается материал.
Запуск Powershell
На примере Windows 10 Powershell можно запустить просто нажав правой кнопкой мыши на меню пуск.
Также нижняя строчка позволяет запустить Powershell с повышенными правами администратора.
Еще можно воспользоваться поиском в WIndows 10 и ввести название powershell
Как видно на картинке выше нашелся не только Powershell но и Powershell ISE. Консоль powershell удобна если требуется запустить последовательно не больше одной команды. Либо несколько команд в конвейере. Однако в случае написания полноценных скриптов лучше использовать Powershell ISE. Это бесплатная среда разработки сценариев на языке Powershell поставляется вместе с ОС Windows.
Сразу после запуска консоли рекомендую запустить командлет Get-Help — встроенная справка по всем командлетам, аналог man в Linux.
Видим что консоль предлагает обновить встроенную помощь. Нажимаем Y и соглашаемся.
Командлеты
Командлеты — это название команд в Powershell. Каждый командлет реализует заложенную в него функциональность. Как правило наименование командлета состоит из пары: глагол-существительное. Например: Get-Help — получить помощь. Обычно Get используется чтобы получить информация, Set — внести изменение, New — создать новый объект, политику и т.п. и Remove -удалить объект, политику и т.п.
Командлеты не чувствительны к регистру. Написать Get или get не важно, powershell воспримет эти команды одинаково.
Чтобы получить список всех доступных командлетов необходимо использовать Get-Command
Для получения справки по любому командлету напишите Get-Help имя-комндлета. Например
Давайте представим что нам необходимо вывести список командлетов для управления процессами. Воспользуемся Get-Command и укажем ему параметры для более точного поиска.
И вот мы видим список командлетов позволяющих управлять процессами: Get-Process — список всех запущенных процессов, Start-Process — запустить указанный процесс, Stop-Process— остановить указанный процесс, Wait-Process — ожидать указанный процесс. Как видно из названий командлетов можно легко понять для чего каждый служит.
Используя командлет Get-Help можно получить справку по любому командлету.
PS C:WINDOWSsystem32> Get-Help Get-Process ИМЯ Get-Process ОПИСАНИЕ Gets the processes that are running on the local computer or a remote computer. СИНТАКСИС Get-Process [[-Name] <System.String[]>] [-ComputerName <System.String[]>] [-FileVersionInfo] [-Module] [<CommonParameters>] Get-Process [-ComputerName <System.String[]>] [-FileVersionInfo] -Id <System.Int32[]> [-Module] [<CommonParameters>] Get-Process [-ComputerName <System.String[]>] [-FileVersionInfo] -InputObject <System.Diagnostics.Process[]> [-Module] [<Com monParameters>] Get-Process -Id <System.Int32[]> -IncludeUserName [<CommonParameters>] Get-Process [[-Name] <System.String[]>] -IncludeUserName [<CommonParameters>] Get-Process -IncludeUserName -InputObject <System.Diagnostics.Process[]> [<CommonParameters>] ОПИСАНИЕ The `Get-Process` cmdlet gets the processes on a local or remote computer. Without parameters, this cmdlet gets all of the processes on the local computer. You can also specify a particular process b y process name or process ID (PID) or pass a process object through the pipeline to this cmdlet. By default, this cmdlet returns a process object that has detailed information about the process and supports methods that l et you start and stop the process. You can also use the parameters of the `Get-Process` cmdlet to get file version informati on for the program that runs in the process and to get the modules that the process loaded. ССЫЛКИ ПО ТЕМЕ Online Version: https://docs.microsoft.com/powershell/module/microsoft.powershell.management/get-process?view=powershell-5.1 &WT.mc_id=ps-gethelp Debug-Process Get-Process Start-Process Stop-Process Wait-Process ЗАМЕЧАНИЯ Для просмотра примеров введите: "get-help Get-Process -examples". Для получения дополнительных сведений введите: "get-help Get-Process -detailed". Для получения технических сведений введите: "get-help Get-Process -full". Для получения справки в Интернете введите: "get-help Get-Process -online"
При использовании командлета есть возможность указать несколько параметров при запуске. Первый параметр можно не называть. Выше я писал Get-Command *Process* где указал поиск командлетов со словом Process. Однако я не написал параметр -Name, хотя именно его и указал. Если полностью то поиск по имени выглядит так: Get-Command -Name *Process* . В случае отсутствия непосредственного указания -Name Powershell принимает в качестве имени введенное слово *Process*.
Давайте выведем список процессов с именем WhatsApp
Get-Process -Name WhatsApp -IncludeUserName
Мы вывели все процессы с именем WhatsApp и добавили в вывод дополнительный параметр -IncludeUserName, что позволило нам увидеть кем запущен процесс.
Алиасы
Алиасы в Powershell это по сути более короткие названия командлетов. Т.е. любому командлету можно присвоить свое короткое имя (alias). Например алиасом для командлета Get-Process является gps. Согласитесь куда проще и быстрее написать gps чем Get-Process.
Список всех alias можно получить используя командлет Get-Alias
PS C:WINDOWSsystem32> get-alias CommandType Name Version Source ----------- ---- ------- ------ Alias % -> ForEach-Object Alias ? -> Where-Object Alias ac -> Add-Content Alias asnp -> Add-PSSnapin Alias cat -> Get-Content Alias cd -> Set-Location Alias CFS -> ConvertFrom-String 3.1.0.0 Microsoft.PowerShell.Utility Alias chdir -> Set-Location Alias clc -> Clear-Content Alias clear -> Clear-Host Alias clhy -> Clear-History Alias cli -> Clear-Item Alias clp -> Clear-ItemProperty Alias cls -> Clear-Host Alias clv -> Clear-Variable Alias cnsn -> Connect-PSSession Alias compare -> Compare-Object Alias copy -> Copy-Item Alias cp -> Copy-Item Alias cpi -> Copy-Item Alias cpp -> Copy-ItemProperty Alias curl -> Invoke-WebRequest Alias cvpa -> Convert-Path Alias dbp -> Disable-PSBreakpoint Alias del -> Remove-Item Alias diff -> Compare-Object Alias dir -> Get-ChildItem Alias dnsn -> Disconnect-PSSession Alias ebp -> Enable-PSBreakpoint Alias echo -> Write-Output Alias epal -> Export-Alias Alias epcsv -> Export-Csv Alias epsn -> Export-PSSession Alias erase -> Remove-Item Alias etsn -> Enter-PSSession Alias exsn -> Exit-PSSession Alias fc -> Format-Custom Alias fhx -> Format-Hex 3.1.0.0 Microsoft.PowerShell.Utility Alias fl -> Format-List Alias foreach -> ForEach-Object Alias ft -> Format-Table Alias fw -> Format-Wide Alias gal -> Get-Alias Alias gbp -> Get-PSBreakpoint Alias gc -> Get-Content Alias gcb -> Get-Clipboard 3.1.0.0 Microsoft.PowerShell.Management Alias gci -> Get-ChildItem Alias gcm -> Get-Command Alias gcs -> Get-PSCallStack Alias gdr -> Get-PSDrive Alias ghy -> Get-History Alias gi -> Get-Item Alias gin -> Get-ComputerInfo 3.1.0.0 Microsoft.PowerShell.Management Alias gjb -> Get-Job Alias gl -> Get-Location Alias gm -> Get-Member Alias gmo -> Get-Module Alias gp -> Get-ItemProperty Alias gps -> Get-Process Alias gpv -> Get-ItemPropertyValue Alias group -> Group-Object Alias gsn -> Get-PSSession Alias gsnp -> Get-PSSnapin Alias gsv -> Get-Service Alias gtz -> Get-TimeZone 3.1.0.0 Microsoft.PowerShell.Management Alias gu -> Get-Unique Alias gv -> Get-Variable Alias gwmi -> Get-WmiObject Alias h -> Get-History Alias history -> Get-History Alias icm -> Invoke-Command Alias iex -> Invoke-Expression Alias ihy -> Invoke-History Alias ii -> Invoke-Item Alias ipal -> Import-Alias Alias ipcsv -> Import-Csv Alias ipmo -> Import-Module Alias ipsn -> Import-PSSession Alias irm -> Invoke-RestMethod Alias ise -> powershell_ise.exe Alias iwmi -> Invoke-WmiMethod Alias iwr -> Invoke-WebRequest Alias kill -> Stop-Process Alias lp -> Out-Printer Alias ls -> Get-ChildItem Alias man -> help Alias md -> mkdir Alias measure -> Measure-Object Alias mi -> Move-Item Alias mount -> New-PSDrive Alias move -> Move-Item Alias mp -> Move-ItemProperty Alias mv -> Move-Item Alias nal -> New-Alias Alias ndr -> New-PSDrive Alias ni -> New-Item Alias nmo -> New-Module Alias npssc -> New-PSSessionConfigurationFile Alias nsn -> New-PSSession Alias nv -> New-Variable Alias ogv -> Out-GridView Alias oh -> Out-Host Alias popd -> Pop-Location Alias ps -> Get-Process Alias pushd -> Push-Location Alias pwd -> Get-Location Alias r -> Invoke-History Alias rbp -> Remove-PSBreakpoint Alias rcjb -> Receive-Job Alias rcsn -> Receive-PSSession Alias rd -> Remove-Item Alias rdr -> Remove-PSDrive Alias ren -> Rename-Item Alias ri -> Remove-Item Alias rjb -> Remove-Job Alias rm -> Remove-Item Alias rmdir -> Remove-Item Alias rmo -> Remove-Module Alias rni -> Rename-Item Alias rnp -> Rename-ItemProperty Alias rp -> Remove-ItemProperty Alias rsn -> Remove-PSSession Alias rsnp -> Remove-PSSnapin Alias rujb -> Resume-Job Alias rv -> Remove-Variable Alias rvpa -> Resolve-Path Alias rwmi -> Remove-WmiObject Alias sajb -> Start-Job Alias sal -> Set-Alias Alias saps -> Start-Process Alias sasv -> Start-Service Alias sbp -> Set-PSBreakpoint Alias sc -> Set-Content Alias scb -> Set-Clipboard 3.1.0.0 Microsoft.PowerShell.Management Alias select -> Select-Object Alias set -> Set-Variable Alias shcm -> Show-Command Alias si -> Set-Item Alias sl -> Set-Location Alias sleep -> Start-Sleep Alias sls -> Select-String Alias sort -> Sort-Object Alias sp -> Set-ItemProperty Alias spjb -> Stop-Job Alias spps -> Stop-Process Alias spsv -> Stop-Service Alias start -> Start-Process Alias stz -> Set-TimeZone 3.1.0.0 Microsoft.PowerShell.Management Alias sujb -> Suspend-Job Alias sv -> Set-Variable Alias swmi -> Set-WmiInstance Alias tee -> Tee-Object Alias trcm -> Trace-Command Alias type -> Get-Content Alias wget -> Invoke-WebRequest Alias where -> Where-Object Alias wjb -> Wait-Job Alias write -> Write-Output
Как видно из списка для alias использованы аналогичные по значению команды из Linux: ls, man, mount, md, kill и т.п. Видимо чтобы линуксоиду было по привычнее 🙂 Можно создать свой alias используя командлет New-Alias
Конвейер
Конвейер используется для передачи выходных данных командлета идущего вначале во входные данные командлета следующего за ним. Ничего непонятно? 🙂 Давайте на примерах, так всегда яснее.
Возьмем уже известный нам командлет Get-Process, посмотрим на его вывод
Как по мне многовато лишних столбцов. Мне эта информация не нужна, поэтому я выберу только нужные данные. Для таких целей служит командлет Select-Object. Давайте используем его в конвейере.
Get-Process|Select-Object ID,CPU,ProcessName
Как вы уже наверно догадались конвейер обозначается знаком | и идет сразу следом за командлетом. И так данные по конвейеру можно передавать и дальше другим командлетам. Итак я передал выходные данные (список запущенных процессов) на вход командлета Select-Object. Который в свою очередь выбрал данные по 3 столбцам ID, CPU, ProcessName. Теперь можно передать эти данные дальше. Например выгрузить в текстовый файл
Get-Process|Select-Object ID,CPU,ProcessName|Out-File C:TMPout.txt
Просто не правда ли? У нас конвейер из трех командлетов, на выходе которого получаем текстовый файл со списком запущенных процессов и необходимой информацией по ним.
Структура объектов
В Powershell объекты играют самую важную роль. От типа объекта зависит что именно с ним можно сделать. Узнать тип объекта и вывести список всех его элементов позволяет команда Get-Member
Вот далеко не полный список элементов командлета Get-Process. В данному случае тип данных это System.Diagnostics.Process
Давайте посмотрим тип данных у новой переменной
$new="Test" $new|Get-Member
В данном случае тип данных System.String т.е. строка. Что вполне логично. А теперь посмотрите что можно сделать с этой строкой с учетом указанных выше параметров.
Как видно на картинке выше мы заключаем нашу тестовую переменную $new в скобки и после них пишем точку и указываем метод. В примере я использовал три метода:
- ToUpper — перевод всех букв в строке в верхний регистр
- ToLower — перевод всех букв в строке в нижний регистр
- Length — подсчитать количество символов в строке
Это всего лишь небольшой пример что можно сделать с параметрами объекта. Чаще используйте Get-Member и вы откроете для себя безграничные возможности манипуляции над объектами.
Скрипты Powershell
В самом начале статьи указал на встроенный инструмент Powershell ISE. Давайте запустим его и создадим свой первый скрипт. Кстати скрипты сохраняются в файлах с расширением ps1
Скрипт будет запускать блокнот, далее выполняется проверка если блокнот запущен выводится сообщение об этом и после блокнот закрывается. Если блокнот не запущен то выводится соответствующее сообщение об этом. На самом деле блокнот будет всегда запущен, т.к. мы вначале скрипта написали Start-Process notepad
Start-Process notepad $a=Get-Process notepad if ($a.ProcessName -like "Notepad") { Write-Host "Блокнот запущен, давайте его закроем" Stop-Process -name notepad } else { Write-Host "Блокнот не запущен, что поделать" }
В этом скрипте я использовал цикл if else. О циклах будет подробнее в следующей статье. Итак давайте сохраним скрипт и выполним его.
В ответ мы получим такую ошибку:
Невозможно загрузить файл, так как выполнение сценариев отключено в этой системе. Для получения дополнительных сведений см. about_Execution_Policies по адресу https:/go.microsoft.com/fwlink/?LinkID=1351 70. + CategoryInfo : Ошибка безопасности: (:) [], ParentContainsError RecordException + FullyQualifiedErrorId : UnauthorizedAccess
Все верно, изначально в WIndows запрещено выполнять скрипты Powershell. Это сделано для повышения безопасности системы. Для включения возможности запуска скриптов Powershell необходимо запустить Powershell от Администратора и ввести командлет Set-ExecutionPolicy с одним из параметров:
- Restricted — политика по умолчанию. Выполнение всех скриптов запрещено
- RemoteSigned — разрешено запускать собственные скрипты и подписанные доверенным разработчиком
- AllSigned — разрешено запускать скрипты, подписанные доверенным разработчиком. Каждый раз перед запуском такого скрипта PowerShell будет запрашивать подтверждение
- Unrestricted — в системе разрешается запускать любые скрипты
Если вы полностью уверены в запускаемых скриптах можете поставить Unrestricted. Давайте так и сделаем
Set-ExecutionPolicy -Unrestricted
Будет предупреждение по безопасности, соглашаемся нажав Y
Можем посмотреть текущую настройку политики безопасности при помощи командлета Get-ExecutionPolicy
В данной статье мы рассмотрели основы чтобы подготовиться писать скрипты Powershell. В следующих статьях мы более подробно изучим циклы, массивы, функции, работу со строками и много другое. Кстати вот раздел посвященный Powershell. Там много всего интересного 😉
Рекомендую к прочтению:
- Переменные
- Операторы сравнения
- Операторы условий
- Циклы
Хотите отблагодарить автора статьи? Это даст ему дополнительный стимул к написанию новых статей.
Windows 10 PowerShell – это средство командной строки, которое позволяет выполнять команды и сценарии для изменения параметров системы и автоматизации задач. Это похоже на командную строку, но PowerShell является более эффективным интерфейсом командной строки (CLI), который предоставляет широкий набор инструментов и обеспечивает большую гибкость и контроль (особенно для сценариев).
Скрипт – это просто набор команд, сохраненных в текстовый файл (с расширением .ps1), которые PowerShell может понять и выполнить в заданной последовательности. Единственное предупреждение заключается в том, что в отличие от командной строки, протокол безопасности по умолчанию предотвращает выполнение всех сценариев.
Это означает, что при двойном щелчке .ps1 файла в системе Windows 10 ничего не произойдёт, и если вы пытаетесь выполнить скрипт в PowerShell, вы получите сообщение об ошибке: «не может быть загружен, потому что запрещено выполнение сценариев в этой системе». Тем не менее, запускать сценарии на вашем устройстве довольно просто. Вам просто нужно включить правильную политику выполнения.
В этой версии урока по Windows 10 мы проведём вас шаг за шагом, чтобы вы смогли успешно запустить свой первый скрипт в PowerShell.
Создание файла сценария PowerShell
В Windows 10 файлы сценариев PowerShell можно создавать с помощью практически любого текстового редактора или консоли интегрированной среды сценариев (ISE).
Создание скрипта с помощью блокнота
Чтобы создать сценарий PowerShell с помощью блокнота, выполните следующие действия:
- Откройте приложение «Блокнот».
- Создайте или вставьте сценарий. Например:
Write-Host "«Поздравляем! Ваш первый скрипт успешно выполнен»"
Вышеприведенный скрипт просто выводит на экране фразу «Поздравляем! Ваш первый скрипт успешно выполнен».
- Сохраните файл под любым удобным названием, например, first_script.ps1
Создание сценария с помощью интегрированной среды сценариев
Кроме того, консоль PowerShell ISE можно использовать для кодирования сценариев в Windows 10. Интегрированная cреда сценариев является сложным инструментом, но вы можете начать работу с помощью этих шагов:
- Откройте системный поиск и введите запрос Windows PowerShell ISE, щелкните правой кнопкой мыши верхний результат, и выберите Запуск от имени администратора или выберите соответствующий параметр в правой колонке.
-
В PowerShell ISE создайте пустой файл .ps1, в котором можно создать или вставить скрипт. Например:
Write-Host "«Поздравляем! Ваш первый скрипт успешно выполнен»"
- Откройте меню Файл и нажмите кнопку Сохранить.
- Введите название сценария. Например, first_script_ise.ps1
- Сохраните скрипт.
Как только Вы выполнили эти шаги с помощью Блокнота или PowerShell ISE, сценарий готов к запуску, но он не будет выполнен. Это происходит потому, что параметры PowerShell по умолчанию всегда настроены на блокирование выполнения любого сценария.
Запуск файла сценария PowerShell
Чтобы запустить файл сценария в PowerShell, необходимо изменить политику выполнения, выполнив следующие действия:
- Откройте поиск и введите PowerShell, щелкните правой кнопкой мыши в верхний результат и выберите Запуск от имени администратора.
- Введите следующую команду, чтобы разрешить выполнение скриптов и нажмите клавишу Enter:
Set-ExecutionPolicy RemoteSigned
- Укажите тип А и ещё раз нажмите клавишу Enter.
-
Введите следующую команду для запуска скрипта и нажмите клавишу Enter:
& "C:PATHtoSCRIPTfirst_script.ps1"
В приведенной выше команде обязательно измените PATHtoSCRIPT на расположение вашего скрипта.
После выполнения этих шагов сценарий будет запущен, и если он был создан правильно, вы должны увидеть его вывод без проблем.
PowerShell в Windows 10 включает четыре политики выполнения:
- Restricted – останавливает выполнение скрипта.
- RemoteSigned – запускает скрипты, созданные на устройстве. Однако, сценарии, созданные на другом компьютере, не будут запускаться, если они не содержат подписи доверенного издателя.
- AllSigned – все скрипты будут работать до тех пор, пока они подписаны надежным издателем.
- Unrestricted запускает любой скрипт без каких-либо ограничений.
В приведенных выше шагах мы использовали команду, чтобы разрешить запуск локальных скриптов в Windows 10. Однако, если вы не планируете регулярно выполнять скрипты, можно восстановить настройки по умолчанию, используя те же инструкции, но на Шаге 4, обязательно используйте Set-ExecutionPolicy Restricted команду.
В этой статье про PowerShell для начинающих мы посмотрим, как писать скрипты, которые помогают оптимизировать управление Windows-окружением.
PowerShell — это объектно-ориентированный программный движок и скриптовый язык с интерфейсом командной строки, предоставляющий широкие возможности для конфигурирования операционных систем семейства MS Windows. Он предлагает как чисто консольный интерфейс, так и полноценную среду разработки PowerShell ISE (Integrated Scripting Environment, встроенное скриптовое окружение) для скриптов.
Для запуска интерфейса командной строки введите powershell
в меню «Выполнить» (WinKey + R). PowerShell ISE запускается с помощью команды «PowerShell ISE» в том же меню. ISE более предпочтительно, так как предоставляет более широкие возможности разработчику благодаря подсветке синтаксиса, функции автозаполнения кода и другим особенностям, присущим многим «большим» IDE.
Среда разработки Windows PowerShell ISE
Написание и запуск скриптов
Скрипты сохраняются в виде файлов с расширением .ps1
. Несмотря на то, что PowerShell уже давно является нативной частью ОС Windows, вы не сможете запустить его скрипты простым двойным щелчком. Для этого надо кликнуть правой кнопкой по скрипту и выбрать «Запустить в PowerShell».
Также существуют системные политики, ограничивающие выполнение скриптов. Можно проверить текущие параметры политики, введя команду Get-ExecutionPolicy
. Результатом будет одно из следующих значений:
- Restricted — выполнение скриптов запрещено. Стандартная конфигурация;
- AllSigned — можно запускать скрипты, подписанные доверенным разработчиком; перед запуском скрипта PowerShell запросит у вас подтверждение;
- RemoteSigned — можно запускать собственные скрипты или те, что подписаны доверенным разработчиком;
- Unrestricted — можно запускать любые скрипты.
Для начала работы необходимо изменить настройку политики запуска на RemoteSigned, используя команду Set-ExecutionPolicy
:
После выполнения команды можно будет запускать свои скрипты
Командлеты
Командлеты — это команды с предопределённой функцией, подобные условным операторам в языках программирования. У них есть несколько ключевых особенностей:
- существуют системные, пользовательские и опциональные командлеты;
- результатом выполнения командлета будет объект или массив объектов;
- командлеты могут обрабатывать данные и передавать их другим командлетам с помощью конвейеров;
- командлеты нечувствительны к регистру, так что нет никакой разницы между
Get-ADUser
,get-aduser
иgEt-AdUsEr
; - в качестве разделителя используется символ
;
.
Каждый командлет содержит в себе глагол и существительное, разделяемые дефисом. Например:
- Get-Process — отобразить текущие процессы, запущенные на компьютере;
- Get-Service — отобразить список служб и их статус;
- Get-Content — отобразить содержимое указанного файла, например
Get-Content C:WindowsSystem32driversetchosts
.
При необходимости список всех доступных командлетов можно вывести с помощью Get-Help-Category. Запомните эту команду — она крайне важна для тех, кто изучает PowerShell с нуля, так как помогает быстрее начать ориентироваться в его возможностях.
Результат выполнения команды Get-Help-Category
Также можно создавать свои командлеты, но эта тема выходит за рамки нашего руководства по PowerShell для начинающих.
Параметры
У каждого командлета есть несколько параметров, определяющих его работу. PowerShell ISE автоматически предлагает все доступные параметры с отображением их типа. Например, Get-Service-NameW*
выводит список служб, у которых имя начинается с W
. Если вы забыли, какие параметры у введённого командлета, воспользуйтесь Get-Member
.
Например, Get-Process | Get-Member
:
Список параметров командлета Get-Process
Если вы не нашли того, что нужно, или не уверены в том, как правильно задаются параметры, можно даже запросить примеры с помощью параметра -Examples
. Встроенное руководство по PowerShell покажет, для чего используются разные параметры:
Примеры использования командлета
Некоторые командлеты также могут вызываться с помощью алиасов. Например, вместо Get-Help
можно просто написать Help
— эта команда также вызовет встроенное руководство по PowerShell.
При написании больших скриптов или коллективной разработке можно пользоваться комментариями. Каждый комментарий начинается с символа #
, а блок комментариев ограничивается комбинациями символов <#
и #>
в начале и в конце соответственно.
Конвейер
PowerShell позволяет осуществлять обмен данными между командлетами с помощью конвейера. Например:
GetService | SortObject -property Status
— сортировка запущенных служб по статусу;“Hello World!” | Out-File C:pstest.txt
— запись текста в файл.
Можно использовать несколько конвейеров. Например, следующий скрипт выводит список имён всех служб за исключением остановленных:
Get-Service | WHERE {$_.status -eq “Running”} | SELECT displayname
Заключение
Это руководство для тех, кто изучает PowerShell с нуля, поэтому здесь раскрыты только базовые понятия и приёмы. После его прочтения у вас должно появиться представление о том, что собой представляет этот инструмент. Также мы рассмотрели варианты изменения политики выполнения скриптов, что такое командлет, как они обмениваются данными с помощью конвейера и как получить свойства нужного объекта. Помните, что в случае затруднений можно воспользоваться командлетом Get-Help — это одна из самых важных команд для начинающих изучать PowerShell.
Если пользуетесь не только Windows, но и Linux, посмотрите статью про команды терминала Linux для начинающих. В ней рассказывается про работу с процессами и файлами, навигацию, каналы, xargs, awk и grep.
Перевод статьи «Windows PowerShell Scripting Tutorial for Beginners»
Приди ко мне брате в Консоль!
— Админ Долгорукий.
Много ярлыков улетело в корзину со времён выхода в свет 2008 Windows. Люди попроще дивились новому синему окошку, которое ребята из Майкрософт зачем-то вставили в свои новые продукты. Люди, которые сидят на блогах и знают программирование начали изучать это окошко.
В итоге к народу начало приходить осознание того, что Майкрософт действительно разработали что-то новое и интересное.
И так, зачем вам это нужно? В основном, программа под названием PowerShell (в дальнейшем PS) предназначена для администраторов и программистов. Она позволяет автоматизировать примерно 99% всех действий в системе. С помощью неё вы можете настраивать удалённые компьютеры, запускать и перезапускать сервисы и производить обслуживание большиства серверных приложений. Как выяснилось, возможности у программы потрясающие.
Конечно же, продвинутые пользователи найдут множество способов использования этого восхитительного синего окошка.
Задача этой статьи проста — показать вам малую долю возможностей PS и дать вам концептуальное понимание предмета. В действительности документации по предмету написано несметное количество, так что я не стремлюсь охватить всё. Я так же ознакомлю вас с набором утилит, которые позволят не вылезать из PS в принципе.
Что представляет собой PS? Это интерпретатор командной строки. Вы вводите необходимые команды, на экране отображается результат их выполнения. Всё просто. Всё было так со времён доса и старого доброго Юникса.
Есть два основных отличия от предшественников, которые качественно выделяют PS среди других интерпретаторов.
- Очень хорошая интеграция с Microsoft .NET Framework. Это даёт вам возможность вплетать мощные программистские решения в свои команды и скрипты.
- Все значения, возвращаемые вам в терминал являются объектами, с которыми можно работать как с объектами, а не просто набором строк. Это позволяет вам создавать неимоверно мощные программные скрипты.
Приступая к работе
Если вы используете Windows 7 или 2008 то PS вам уже доступен. Для пользователей других версий Windows — добро пожаловать на сайт Майкрософт.
После установки вы можете запустить консоль и настроить её по своему вкусу, нажав на иконку в заголовке окна. Вы можете выбрать шрифт и изменить сам размер окна.
После этого, предпринимайте робкие шаги по выполнению первых команд. Для начала наберите
dir
и вы получите список папок в текущем каталоге. Приятным моментом для любителей Юникса
будет тот факт, что команда
ls
работает так же хорошо, как и dir. В PS существует система назначения алиасов на различные команды. В действительности, то что вы сейчас сделали — это выполнили командлет (так в PS называются команды, встроенные в сам PS) Get-ChildItem. Вы можете попробовать просто набрать Get-ChildItem и получить тот же результат, что и в двух предыдущих командах. Для того, чтобы вы быстро ознакомились со списком всех алиасов наберите
ls Alias:
И так, что-то произошло. Вы начали кое-что понимать. Сейчас я буду раскладывать всю магию по кусочкам.
Первое. Командлеты в оригинальной нотации PS имеют следующую систему именования — Глагол-Объект. Это позволяет вам лучше понимать, что можно ожидать в результате выполнения того или иного командлета. Например,
Get-Process # Получить список процессов
Remove-Item # Удалить что-то
Get-Help # получить справку по чему-то
Set-Alias # Создать новый алиас
New-Item # Создать новый объект (Объектом может быть всё что угодно, например, файл)
Далее, в PS достаточно много очевидных вещей находится в непривычных для виндузятника местах. В частности, вы можете посмотреть, что за диски есть в вашей системе, набрав команду
Get-PSDrive
И в ответ вы получаете намного более интересный список дисков в вашей системе, нежели тот, что вы видите в «Моём Компьютере»
Name Used (GB) Free (GB) Provider Root ---- --------- --------- -------- ---- Alias Alias C 16.56 63.44 FileSystem C: cert Certificate D .11 53.92 FileSystem D: Env Environment Function Function HKCU Registry HKEY_CURRENT_USER HKLM Registry HKEY_LOCAL_MACHINE Variable Variable WSMan WSMan
На диске Alias вы можете увидеть список всех алиясов в системе. Виртуальный диск Variable: хранит в себе все переменные, которые вы можете использовать в данной сессии. На диске Env — лежат переменные операционной системы. Диски HKCU и HKLM являются обёрткой для работы с соответствующими ветками реестра.
Давайте углубимся. Набирайте
Set-Location HKLM: # Или, если вы из людей подосёвее, набирайте cd HKLM:
Ну и как вам новый и невероятный способ хождения по реестру всея машины? Вы можете сделать ls по ветке реестра или перейти в нужный «каталог», набрав cd SYSTEM.
SKC VC Name Property --- -- ---- -------- 2 0 BCD00000000 {} 4 0 HARDWARE {} 1 0 SAM {} Get-ChildItem : Requested registry access is not allowed. At line:1 char:3 + ls <<<< -force + CategoryInfo : PermissionDenied: (HKEY_LOCAL_MACHINESECURITY:St ring) [Get-ChildItem], SecurityException + FullyQualifiedErrorId : System.Security.SecurityException,Microsoft.Power Shell.Commands.GetChildItemCommand 35 0 SOFTWARE {} 8 0 SYSTEM {}
(Кстати, даже из под администраторского аккаунта есть доступ не ко всем объектам, о чём мой шелл меня уведомляет красными буквами).
Не бойтесь использовать команды New-Item и Remove-Item чтобы создавать и удалять нужные вам ключи в реестре. (И по традиции, я напомню вам, что играться с ключами реестра в администраторском режиме опасно)
Ну, вот вам и небольшой экскурс вглубь. Конечно же, у вас не получится создать ключ реестра так просто. Что-то пойдёт не так, как надо. Ну что же, могу сказать, что PS — это система, которая поощряет обучение в этой системе. Поэтому
Обучение тому, как правильно чему-то научиться в PowerShell
Способность наблюдать и анализировать наблюдения отличает нормального человека от психа. Ребят в Майкрософт психами не назовёшь. Они действительно понаблюдали за пользователями других командных интерпретаторов и выяснили, какая команда чаще всего используется в интерпретаторах. И той командой был великий и могучий man. (Для незнающих — попробуйте сделать — гугл man или наберите в своём баше man man)
В PS есть аналогичная команда, которая звучит как
Get-Help # хотя вы можеше использовать алиас на неё, под названием help
Насколько поразительно отвратительно ребята из Майкрософт делают документацию для пользовательских приложений, настолько хорошо они заботятся о программистах. (Неверующие могут сравнить справку системы Windows XP и 2003)
И так, выбирайте приглянувшийся вам командлет и отправляйте его в help. Если после прочтения общей справки вы ничего не поняли, то попробуйте набрать
get-help New-Item -Examples
Ключ -Examples обычно выдаёт от двух до пяти потрясающих примеров использования выбранной вами команды, с детальным их описанием.
На самом деле, одним только Гет-Хелпом, я в своё время изучил основы PS, перебирая все команды и читая к ним справку.
Если же вы захотели получить справку по какой-то функции, но не знаете, как она называется, а просто предполагаете о её существовании, то просто наберите
get-help files
В ответ на эту команду вы получите список топиков, которые содержат ключевое слово:
PS C:> get-help Files Name Category Synopsis ---- -------- -------- FileSystem Provider Provides access to files and dire... about_profiles HelpFile Describes how to create and use a...
В нашем случая, для того, чтобы научиться работать с реестром, вы можете просто набрать
get-help Registry
В ответ вы получите длиннющее полотно, которое со всеми подробностями расскажет вам о том, как вы можете работать с реестром в PS.
К сожалению, читабельность полотна обратно пропорциональна его длине. Так что, научившись учиться, давайте обучимся тому, как сделать работу в шелле немного проще.
Маленькие, но очень полезные фишки, которые должны быть в жизни
Товарищ, смирись, ты — в командной строке. Тут безгуёво принципе. Но, если ты познаешь некоторые уловки, тебе здесь станет удобно.
И так, для тех, кто никогда не был в командной строке
- Нажатие кнопкок вверх и вниз позволяет вам прокручивать историю команд, и выбирать ранее набранные команды.
- Нажатие кнопки вправо, в конце строки, будет посимвольно перенабирать предыдущую команду.
Для тех, кто уже бывал в командных строках
- Ctrl+Home — удаляет всё, начиная с текущей позиции курсора до начала строки
- Ctrl+End — удаляет с курсора и до конца строки
- F7 — показывает окно со списком набранных команд, и позволяет выбрать одну из них.
- Для того, чтобы скопировать что-то в буфер, выделите это мышью и нажмите Enter.
- Для того, чтобы вставить строку из буфера — просто нажмите правую кнопку мыши.
Это — самые базовые, и необходимые действия, которые вам придётся выучить наизусть. Другое дело, что они помогут вам шустрее работать с шеллом.
Углубляемся в изучение окружения
Для того чтобы понять нижеследующие строки, нам надо будет разобраться с понятием конвейера.
Когда вы запускаете какой-либо командлет, то возвращаемые им значения преобразуются в текст и выводятся на экран. Но, это не всегда полезно. Например, если вы хотите передать возвращаемое значение одного командлета на вход другого. Для этого вам полезно будет использовать |, в народе именуемый конвейером.
Например, вы хотите отобразить на экране текст, который содержится во всех файлах формата bat в папке. Для того, чтобы выбрать файлы, выполняйте
PS C:> ls -filter "*.bat" | Get-Content REM Dummy file for NTVDM
Команда ls -filter «*.bat» выбирает все файлы с нужным расширением, а команда Get-Content выводит их на экран (на самом деле, исходя из названия, команда просто получает содержимое объекта, а на экран он выводится по факту того, что дальше некуда)
Конвейер может сделать очень много полезного для вас. Например, решить «портянку помощи».
Get-Help Registry | Set-Content reg.txt
И весь файл помощи по реестру сохранён в текстовом файле, который вы теперь можете открыть.
Если вы действительно хотите порадоваться жизни, и понять, что PS способен на многое, то вам придётся применить свой IQ на все 100% и вообразить что-то нереальное.
ps | ls
Выглядит невероятно, а результат даёт потрясающий! Если вы хотите узнать, из какого файла появился процесс, просто пустите его конвейером на get-childitem!
В частности, я сейчас набираю текст в вордпаде:
PS C:> ps wordpad | ls Directory: C:Program FilesWindows NTAccessories Mode LastWriteTime Length Name ---- ------------- ------ ---- -a--- 6/28/2010 9:57 PM 4247040 wordpad.exe
Вот это меня поразило до глубины души.
Теперь можно переходить к изучению окружения
Как я уже говорил, всё что вы видите на экране не является строками, а является объектами. Например, результат выполнения команды ps возвращает нам список процессов, запущенных в системе.
Но как узнать, что же у нас в руках?
Для этого мы воспользуемся командлетом Get-Member, который откроет нам методы любого класса. Давайте узнаем, что содержится в том же самом процессе, который выдаёт нам команда ps.
ps wordpad | Get-Member
Набирайте, и смотрите на список членов класса, которые вы можете увидеть в классе System.Diagnostics.Process. Тоесть, фактически, командлет ps вернул нам массив объектов типа Process и мы можем попрограммировать их!
Давайте поглумимся над блокнотом.
PS C:> notepad PS C:> ps notepad Handles NPM(K) PM(K) WS(K) VM(M) CPU(s) Id ProcessName ------- ------ ----- ----- ----- ------ -- ----------- 70 4 1148 5376 56 0.30 3900 notepad PS C:> ps notepad | get-member -type method TypeName: System.Diagnostics.Process Name MemberType Definition ---- ---------- ---------- BeginErrorReadLine Method System.Void BeginErrorReadLine() BeginOutputReadLine Method System.Void BeginOutputReadLine() CancelErrorRead Method System.Void CancelErrorRead() CancelOutputRead Method System.Void CancelOutputRead() Close Method System.Void Close() CloseMainWindow Method bool CloseMainWindow() CreateObjRef Method System.Runtime.Remoting.ObjRef CreateObj... Dispose Method System.Void Dispose() Equals Method bool Equals(System.Object obj) GetHashCode Method int GetHashCode() GetLifetimeService Method System.Object GetLifetimeService() GetType Method type GetType() InitializeLifetimeService Method System.Object InitializeLifetimeService() Kill Method System.Void Kill() Refresh Method System.Void Refresh() Start Method bool Start() ToString Method string ToString() WaitForExit Method bool WaitForExit(int milliseconds), Syst... WaitForInputIdle Method bool WaitForInputIdle(int milliseconds),...
Вот это неплохое количество методов, которые мы можем запустить, используя шелл. И так, как же это сделать? Просто.
(ps notepad).WaitForExit()
Если вы возьмёте результат выполнения командлета в скобки, то вы сможете обратиться к нему, как к объекту в вашей программе, прямо из командной строки.
После запуска этого метода шелл завис и ждёт у моря погоды. Нажмите пару раз Enter. Ничего не происходит. Что же, закройте открытый блокнот. Вуаля, вы снова в шелле.
Я думаю, теперь вы должны погулять свою фантазию. Попробуйте, пустите через конвейер в get-member результаты выполнения ls или других командлетов, каких только можете найти.
Если вы увидели, что в свойстве какого-то объекта лежит ещё один объект, не стесняйтесь пускать его на Get-Member
(ps notepad).StartTime | Get-Member
И так далее до бесконечности.
Задача для пытливых умов. Пролетела новость, что рефлектор станет платным. Как сделать рефлектор на чистом PS? Кстати, это не такая уж и трудная задача.
Ну, вот, мы немного разобрались с тем, как узнать, что нас окружает. Теперь, мы готовы к тому, чтобы понять ещё парочку принципов, существующих в шелле.
Переменные и объекты
И так, пару слов по поводу переменных. В PS они бывают нетипизированными:
$processList = ps
И типизированными
PS C:> [DateTime]$x = "febbrrr" Cannot convert value "febbrrr" to type "System.DateTime". Error: "The string was not recognized as a valid DateTime. There is a unknown word starting at index 0." At line:1 char:13 + [DateTime]$x <<<< = "febbrrr" + CategoryInfo : MetadataError: (:) [], ArgumentTransformationMetadataException + FullyQualifiedErrorId : RuntimeException PS C:> [DateTime]$x = "02/14/11" PS C:> $x Monday, February 14, 2011 12:00:00 AM
И так, у нас появились переменные, и теперь мы можем присваивать им значения. В общем, всё, что вы пускали на конвейер, можно пустить и в переменную. Но, тут PS предоставляет нам одну очень интересную фитчу, которая делает его незаменимым инструментом в руках .NET разработчика.
Помните, я сказал, что в PS всё, что возвращается — это объект? Ну так вот, объект это не простой, а дотнетовый. Любой программист уже обратил внимание на тот факт, что в списке процессов мы работали с объектом из окружения CLR. Что же, мы можем запросто создать такой объект.
Давайте, попробуйте
$x = new-object System.Object
Что-же, переменную мы создали, а толку от неё — как с икспи сервака. Никакого. Давайте пофантазируем и подумаем, что мы действительно можем сделать?
C:> $client = New-Object System.Net.WebClient C:> $client.DownloadString("http://google.com")
А вот это уже другое дело. Только что мы из подручных средств собрали себе wget на коленке. Как вам такой поворот событий?
Что же, в этот момент можно идти в MSDN и подряд перебирать все классы, смотреть, что в них есть интересного. Всё это позволяет создавать очень гибкие скрипты.
Кстати, о скриптах
PS позволяет выполнять скрипты. Ура! Делает он это с волшебного пендаля. Неура. По умолчанию в PS запрещён запуск скриптов, которые не были подписаны цифровой подписью. Для запуска скрипта вы должны его либо подписать (для этого используйте help about_signing) либо, просто понизить уровень безопасности, и выполнить
set-executionpolicy remotesigned
обычно я делаю второе. Ибо первый вариант требует скачивания многотонных SDK и долгого колдовства. Хотя, напомню о безопасности, и скажу, что второй вариант не канает для супер-сервера-всея-руси.
После выполнения этих действий, вы будете готовы писать свой первый скрипт. Для начала, рекомендую создать для него файл:
New-Item -type file $PROFILE
Переменная $PROFILE содержит в себе адрес файла с вашим профилем в PS. Этот файл будет запускаться в тот момент, когда вы стартуете PS. Плюс заключается в том, что вы можете нашпиговать свой профиль разными мелкими и полезными скриптами, которые помогут вам автоматизировать производство.
Теперь вы можете начать редактирование своего профиля:
vim $PROFILE
(О, кстати, я вам не сказал, но в PS, на мой взгляд, лучше всего смотрится текстовый редактор vim. Возможно кто-то назовёт меня настоящим извращенцем, но на самом деле, я уже не раз пытался использовать что-то другое, но всегда возвращался к виму. Попробуйте и вы. Его не просто изучить с нуля, но если вы поймёте основы, то сможете очень быстро и удобно редактировать тексты.)
Ладно, теперь повторим эту команду без того, чтобы умничать:
notepad $PROFILE
Ну, вот, например, то, что лежит у меня в профиле
$webClient = New-Object System.Net.WebClient $cred = New-Object System.Net.NetworkCredential("login", "Pass") $webClient.Proxy = New-Object System.Net.WebProxy("www.proxy.adrress", $true, $null, $cred)
Так как мы используем прокси сервер, а вэб клиент является моим любимым инструментом для работы, то я уже заготовил для себя переменную с этим клиентом, чтобы иметь возможность безболезненно подключаться к интернету и не отягощать себя вводом пароля.
Что ещё можно запихнуть в профиль?
Всё что угодно. Настройки цвета окна, ваши любимые функции и алиасы. Алиасы на ваши излюбленные программы и скрипты автоматизации…
На самом деле, я уже написал достаточно много. Вы увидели для себя кое-что новое. Я прекрасно знаю, что уровень этой статьи — для начинающих, но и продвинутые админы найдут для себя несколько интересных моментов. Моей задачей было предоставить вам возможность получить общее представление о том, что вы можете сделать.
Что же, вот, напоследок, вам задачи, над которыми можно поломать голову и решить интересные проблемы:
Написать скрипт, который сортирует изображения по папкам, исходя из их размера (для получения размера файла можно использовать дотнет объекты или ком объекты, предоставляемые эксплорером)
Для выполнения этого, вам уж точно понадобиться хорошо изучить Where-Object или Foreach-Object.
Написать простой NMAP
Что будет, если запустить команду Пинг в цикле? А теперь, возьмите выход от этой команды и пропарсите его как строку. Вам однозначно придётся прочитать мануал по -le -ge и том, как работать со строками.
Написать парсер для башорга.
Чтобы, после логина в систему, вам на выбор выдавалась цитата из лучших за последние пять лет. Тут можно использовать регэкспы, с которыми PS очень хорошо дружит.
Поиграться с переменной $host и сделать из синего экрана Матрицу!
Что ещё можно делать? Матёрые COM программисты найдут для себя отличный способ повеселиться, когда обнаружат, что new-object имеет ключ -comObject. Фактически, это открывает вам ворота к полному управлению практически любой функцией локального и удалённого компьютера.
Ещё хочу заметить, что последние версии программного обеспечения от Microsoft поддерживают работу в PowerShell. Например, есть SQL PowerShell, который поставляется с 2008 сиквелом и позволяет сделать ls по записям в любой таблице. Это даёт ещё больший простор для фантазий.
Так же, хочу заметить, что комьюнити по разработке на PS очень сильно растёт и ширится. В частности, вы можете найти скрипты, готовые для чего угодно — например, вы можете нагуглить себе способ управления ITunes через PowerShell или способ использования Google Desktop Search в PS.
Что же, мой неинтересующийся друг, надеюсь, я дал тебе что-то интересное, и ты теперь возьмёшься за покорение интерпретатора, который действительно поможет тебе упростить твою нелёгкую программерскую жизнь и даст тебе возможность автоматизировать больше и быстрее. Очень приятно, что ты прочитал мою статью. Спасибо большое, я могу продолжать конкретно описывать определённые области, если вдруг тебе станет очень интересно.
Написание скриптов 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: использование атрибутов параметров, которые выглядят как командлеты, позволит вам написать структуру, которая будет действовать практически так же, как и настоящие командлеты оболчки. При желании вы даже можете поместить справочник в функцию – как это сделать, вы узнаете в следующих разделах.
На заметку: Подробное изучение расширенных функций выходит за рамки данного курса. Однако вы можете найти более подробную информацию о них в интернете, и попытаться изучить ее самостоятельно.
description | ms.date | title |
---|---|---|
This article describes how to create, edit, run, and save scripts in the Script Pane. |
10/07/2021 |
How to Write and Run Scripts in the Windows PowerShell ISE |
How to Write and Run Scripts in the Windows PowerShell ISE
This article describes how to create, edit, run, and save scripts in the Script Pane.
How to create and run scripts
You can open and edit Windows PowerShell files in the Script Pane. Specific file types of interest
in Windows PowerShell are script files (.ps1
), script data files (.psd1
), and script module
files (.psm1
). These file types are syntax colored in the Script Pane editor. Other common file
types you may open in the Script Pane are configuration files (.ps1xml
), XML files, and text
files.
[!NOTE]
The Windows PowerShell execution policy determines whether you can run scripts and load Windows
PowerShell profiles and configuration files. The default execution policy, Restricted, prevents
all scripts from running, and prevents loading profiles. To change the execution policy to allow
profiles to load and be used, see
Set-ExecutionPolicy and
about_Signing.
To create a new script file
On the toolbar, click New, or on the File menu, click New. The created file appears in
a new file tab under the current PowerShell tab. Remember that the PowerShell tabs are only visible
when there are more than one. By default a file of type script (.ps1
) is created, but it can be
saved with a new name and extension. Multiple script files can be created in the same PowerShell
tab.
To open an existing script
On the toolbar, click Open, or on the File menu, click Open. In the Open dialog
box, select the file you want to open. The opened file appears in a new tab.
To close a script tab
Click the Close icon (X) of the file tab you want to close or select the File menu and
click Close.
If the file has been altered since it was last saved, you’re prompted to save or discard it.
To display the file path
On the file tab, point to the file name. The fully qualified path to the script file appears in a
tooltip.
To run a script
On the toolbar, click Run Script, or on the File menu, click Run.
To run a portion of a script
- In the Script Pane, select a portion of a script.
- On the File menu, click Run Selection, or on the toolbar, click Run Selection.
To stop a running script
There are several ways to stop a running script.
- Click Stop Operation on the toolbar
- Press CTRL+BREAK
- Select the File menu and click Stop Operation.
Pressing CTRL+C also works unless some text is currently selected, in which
case CTRL+C maps to the copy function for the selected text.
How to write and edit text in the Script Pane
You can copy, cut, paste, find, and replace text in the Script Pane. You can also undo and redo the
last action you just performed. The keyboard shortcuts for these actions are the same shortcuts
used for all Windows applications.
To enter text in the Script Pane
- Move the cursor to the Script Pane by clicking anywhere in the Script Pane, or by clicking Go
to Script Pane in the View menu. - Create a script. Syntax coloring and tab completion provide a richer editing experience in
Windows PowerShell ISE. - See How to Use Tab Completion in the Script Pane and Console Pane
for details about using the tab completion feature to help in typing.
To find text in the Script Pane
- To find text anywhere, press CTRL+F or, on the Edit menu, click Find
in Script. - To find text after the cursor, press F3 or, on the Edit menu, click Find Next in
Script. - To find text before the cursor, press SHIFT+F3 or, on the Edit menu,
click Find Previous in Script.
To find and replace text in the Script Pane
Press CTRL+H or, on the Edit menu, click Replace in Script. Enter the
text you want to find and the replacement text, then press ENTER.
To go to a particular line of text in the Script Pane
-
In the Script Pane, press CTRL+G or, on the Edit menu, click Go to
Line. -
Enter a line number.
To copy text in the Script Pane
-
In the Script Pane, select the text that you want to copy.
-
Press CTRL+C or, on the toolbar, click the Copy icon, or on the
Edit menu, click Copy.
To cut text in the Script Pane
- In the Script Pane, select the text that you want to cut.
- Press CTRL+X or, on the toolbar, click the Cut icon, or on the Edit
menu, click Cut.
To paste text into the Script Pane
Press CTRL+V or, on the toolbar, click the Paste icon, or on the Edit
menu, click Paste.
To undo an action in the Script Pane
Press CTRL+Z or, on the toolbar, click the Undo icon, or on the Edit
menu, click Undo.
To redo an action in the Script Pane
Press CTRL+Y or, on the toolbar, click the Redo icon, or on the Edit
menu, click Redo.
How to save a script
An asterisk appears next to the script name to mark a file that hasn’t been saved since it was
changed. The asterisk disappears when the file is saved.
To save a script
Press CTRL+S or, on the toolbar, click the Save icon, or on the File
menu, click Save.
To save and name a script
- On the File menu, click Save As. The Save As dialog box will appear.
- In the File name box, enter a name for the file.
- In the Save as type box, select a file type. For example, in the Save as type box,
select ‘PowerShell Scripts (*.ps1
)’. - Click Save.
To save a script in ASCII encoding
By default, Windows PowerShell ISE saves new script files (.ps1
), script data files (.psd1
), and
script module files (.psm1
) as Unicode (BigEndianUnicode). To save a script in another
encoding, such as ASCII (ANSI), use the Save or SaveAs methods on the
$psISE.CurrentFile object.
The following command saves a new script as MyScript.ps1 with ASCII encoding.
$psISE.CurrentFile.SaveAs("MyScript.ps1", [System.Text.Encoding]::ASCII)
The following command replaces the current script file with a file with the same name, but with
ASCII encoding.
$psISE.CurrentFile.Save([System.Text.Encoding]::ASCII)
The following command gets the encoding of the current file.
$psISE.CurrentFile.encoding
Windows PowerShell ISE supports the following encoding options: ASCII, BigEndianUnicode, Unicode,
UTF32, UTF7, UTF8, and Default. The value of the Default option varies with the system.
Windows PowerShell ISE doesn’t change the encoding of script files when you use the Save or
Save As commands.
See Also
- Exploring the Windows PowerShell ISE
description | ms.date | title |
---|---|---|
This article describes how to create, edit, run, and save scripts in the Script Pane. |
10/07/2021 |
How to Write and Run Scripts in the Windows PowerShell ISE |
How to Write and Run Scripts in the Windows PowerShell ISE
This article describes how to create, edit, run, and save scripts in the Script Pane.
How to create and run scripts
You can open and edit Windows PowerShell files in the Script Pane. Specific file types of interest
in Windows PowerShell are script files (.ps1
), script data files (.psd1
), and script module
files (.psm1
). These file types are syntax colored in the Script Pane editor. Other common file
types you may open in the Script Pane are configuration files (.ps1xml
), XML files, and text
files.
[!NOTE]
The Windows PowerShell execution policy determines whether you can run scripts and load Windows
PowerShell profiles and configuration files. The default execution policy, Restricted, prevents
all scripts from running, and prevents loading profiles. To change the execution policy to allow
profiles to load and be used, see
Set-ExecutionPolicy and
about_Signing.
To create a new script file
On the toolbar, click New, or on the File menu, click New. The created file appears in
a new file tab under the current PowerShell tab. Remember that the PowerShell tabs are only visible
when there are more than one. By default a file of type script (.ps1
) is created, but it can be
saved with a new name and extension. Multiple script files can be created in the same PowerShell
tab.
To open an existing script
On the toolbar, click Open, or on the File menu, click Open. In the Open dialog
box, select the file you want to open. The opened file appears in a new tab.
To close a script tab
Click the Close icon (X) of the file tab you want to close or select the File menu and
click Close.
If the file has been altered since it was last saved, you’re prompted to save or discard it.
To display the file path
On the file tab, point to the file name. The fully qualified path to the script file appears in a
tooltip.
To run a script
On the toolbar, click Run Script, or on the File menu, click Run.
To run a portion of a script
- In the Script Pane, select a portion of a script.
- On the File menu, click Run Selection, or on the toolbar, click Run Selection.
To stop a running script
There are several ways to stop a running script.
- Click Stop Operation on the toolbar
- Press CTRL+BREAK
- Select the File menu and click Stop Operation.
Pressing CTRL+C also works unless some text is currently selected, in which
case CTRL+C maps to the copy function for the selected text.
How to write and edit text in the Script Pane
You can copy, cut, paste, find, and replace text in the Script Pane. You can also undo and redo the
last action you just performed. The keyboard shortcuts for these actions are the same shortcuts
used for all Windows applications.
To enter text in the Script Pane
- Move the cursor to the Script Pane by clicking anywhere in the Script Pane, or by clicking Go
to Script Pane in the View menu. - Create a script. Syntax coloring and tab completion provide a richer editing experience in
Windows PowerShell ISE. - See How to Use Tab Completion in the Script Pane and Console Pane
for details about using the tab completion feature to help in typing.
To find text in the Script Pane
- To find text anywhere, press CTRL+F or, on the Edit menu, click Find
in Script. - To find text after the cursor, press F3 or, on the Edit menu, click Find Next in
Script. - To find text before the cursor, press SHIFT+F3 or, on the Edit menu,
click Find Previous in Script.
To find and replace text in the Script Pane
Press CTRL+H or, on the Edit menu, click Replace in Script. Enter the
text you want to find and the replacement text, then press ENTER.
To go to a particular line of text in the Script Pane
-
In the Script Pane, press CTRL+G or, on the Edit menu, click Go to
Line. -
Enter a line number.
To copy text in the Script Pane
-
In the Script Pane, select the text that you want to copy.
-
Press CTRL+C or, on the toolbar, click the Copy icon, or on the
Edit menu, click Copy.
To cut text in the Script Pane
- In the Script Pane, select the text that you want to cut.
- Press CTRL+X or, on the toolbar, click the Cut icon, or on the Edit
menu, click Cut.
To paste text into the Script Pane
Press CTRL+V or, on the toolbar, click the Paste icon, or on the Edit
menu, click Paste.
To undo an action in the Script Pane
Press CTRL+Z or, on the toolbar, click the Undo icon, or on the Edit
menu, click Undo.
To redo an action in the Script Pane
Press CTRL+Y or, on the toolbar, click the Redo icon, or on the Edit
menu, click Redo.
How to save a script
An asterisk appears next to the script name to mark a file that hasn’t been saved since it was
changed. The asterisk disappears when the file is saved.
To save a script
Press CTRL+S or, on the toolbar, click the Save icon, or on the File
menu, click Save.
To save and name a script
- On the File menu, click Save As. The Save As dialog box will appear.
- In the File name box, enter a name for the file.
- In the Save as type box, select a file type. For example, in the Save as type box,
select ‘PowerShell Scripts (*.ps1
)’. - Click Save.
To save a script in ASCII encoding
By default, Windows PowerShell ISE saves new script files (.ps1
), script data files (.psd1
), and
script module files (.psm1
) as Unicode (BigEndianUnicode). To save a script in another
encoding, such as ASCII (ANSI), use the Save or SaveAs methods on the
$psISE.CurrentFile object.
The following command saves a new script as MyScript.ps1 with ASCII encoding.
$psISE.CurrentFile.SaveAs("MyScript.ps1", [System.Text.Encoding]::ASCII)
The following command replaces the current script file with a file with the same name, but with
ASCII encoding.
$psISE.CurrentFile.Save([System.Text.Encoding]::ASCII)
The following command gets the encoding of the current file.
$psISE.CurrentFile.encoding
Windows PowerShell ISE supports the following encoding options: ASCII, BigEndianUnicode, Unicode,
UTF32, UTF7, UTF8, and Default. The value of the Default option varies with the system.
Windows PowerShell ISE doesn’t change the encoding of script files when you use the Save or
Save As commands.
See Also
- Exploring the Windows PowerShell ISE
Современная операционная система Windows, под которой вы вероятней всего работаете в данный момент, является прямым потомком таких динозавров, как DOS и MS-DOS. Однако PowerShell, как командная оболочка от Мелкомягких, появилась сравнительно недавно. А именно в 2006 году. До этого, говоря о командной оболочке в Винде, подразумевали знакомую всем CMD. Которая на поверку является лишь эмуляторкой командной строки, эмулирующая всё что было в DOSе и представляющее собой дырявейшее ведро с гвоздями по сравнению с UNIX’овским BASH’ем. На Юнихсе пишутся SHELL-скрипты, а в Винде БАТ. И соответственно синтаксис в этих батниках отличается. И он весь такой топорный и не логичный, аж зубы сводит. Короче видимо в нулевых, кого-то из программистов Билла эта катавасия окончательно выбесила и было решено написать отдельный язык программирования для любителей окон под названием PowerShell.
В отличие от первого блина, который, как вы уже поняли получился вонючим комом, PowerShell получила гораздо меньше хейта среди сообщества. Данная оболочка буквально дополняла Винду и приносила реальную пользу, а не умножала головняки.
Zip File, мамкины хаЦкеры. С вами Денчик и сегодня мы подробно рассмотрим вопрос применения PowerShell в операционных системах семейства Windows. Познакомимся с расширениями, узнаем, что из себя представляет Execution Policy.
Ну и традиционно поговорим про переменные, условные операторы, циклы и прочие прелести присущие командным оболочкам без графики. Если вам интересна данная тема и вы хотите научиться писать скрипты на pShell.
Тогда не теряйте времени даром. Устраивайтесь по удобней и приготовьте к погружению в максимально понятный ликбез по теме скриптописания на Винде.
Ни грамма лишней воды. Только суровая база и реальная практика с отработкой для закрепления полученных знаний ждёт вас в заключительной части видоса. Погнали.
Сам PowerShell вы можете легко найти в «ПУСКе». Выглядит он как типичное окно терминала, только синего цвета. Что как бы тонко намекает на склонность к синьке среднестатистических пользователей данной ОС.
Тут же мы видим рекламу гласящую, что PowerShell это кроссплатформенная история, а значит она есть даже под Linux. Не понятно зачем, но есть. Помимо стандартного Shell’а в вашей системе есть ISE.
Она же интегрированная среда для написания скриптов. Данная среда значительно упрощает это самое написание. Также настоятельно рекомендую запускать командную оболочку от имени Администратора. Это связано с особенностью политик.
Execution Policy PowerShell
По умолчанию PowerShell не позволяет вам запускать отдельные скрипты или какие-то командлеты. Командлеты это упрощённые команды шела. Так вот, несмотря на дефолтный запрет, данную политику можно изменить, используя несколько способов.
Можно запустить PowerShell с соответствующими аргументами. Либо ввести ту или иную команду для снятия блокировочного механизма. На логичный вопрос, зачем это вообще нужно и почему всё не работает из коробки – отвечу.
Для того, чтобы малограмотный пользователь или начинающий эникей не выстрелил себе в ногу решив поиграть с прикольной синей консолькой. И вам, как админу или спецу по ИБ не пришлось затем разгребать последствия его шаловливых проделок.
Иными словами, Мелкомягкие страхуются, снимая с себя ответственность. Мол, если ты выключил политики безопасности – то пеняй на себя. Грамотная политика, тут, как говорится, не докопаться.
На примере этих команд давайте сразу начнём знакомиться с систаксисом. Во-первых, в Винде, исторически всё пишут с заглавной буквы. А все командлеты, о которых я уже упоминал ранее, начинаются с глагола.
В данном случае Set – выставить. Есть ещё Add – добавить. Get – получить. Test – проверить. Ну и т.д. Суть думаю ясна. После глагола идёт дефис и обозначается, что мы собираемся выставить, добавить или же получить.
Ну а далее уже следуют параметры для этой истории. Т.е. в нашем случае – выставить политику исполнения bypass для вот этого вот процесса. Как по мне, синтаксис даже логичней, чем в Баше.
Переменные в PowerShell
Перейдём к рассмотрению переменных в PowerShell’е. Помните, как в Баше, о котором мы разговаривали в прошлом уроке, весь код представлял собой текстовую инфу.
Так вот. В PowerShell всё с точностью наоборот. Т.к. это не просто командная строка, а реально полноценный язык программирования, причём на поверку объектно-ориентированного типа.
Т.е. работающий с концепцией «Классы – объект». Это когда вы всё что вокруг себя в мире воспринимаете, можно разделить на классы и категории. Например, класс животные. В нём есть подклассы собак, кошек, юзверей.
У юзверей есть ещё подклассы, бухгалтеры, менеджеры и т.д. Ну а объект – это представитель определённого класса. Т.е. вы, смотрящие этот видосик, являетесь представителями класса пользователей платформы ютуб.
У объекта всегда есть какое-то свойство. Например, у вас принадлежность к определённой расе и нации, место проживания, способ зарабатывания денег и прочие интересные вещи.
Помимо свойств каждый объект имеет определённые методы. Т.е. функционал объекта. Например, складировать арбузы в коробку в Пятёрочке или умение писать скрипты на языке PowerShell.
Такая вот бобуйня. Баш нервно курит в сторонке глядя на такую махину. Тут вам не просто строка из текста, а целый объект, который можно передать в переменную.
Плюс ко всему, PowerShell не восприимчив к пробелам. Вот самый простой примерчик с блокнотом. Можно добавить к объекту командлет Get-Member и посмотреть все параметры, которые можно к нему применить.
Также, для заядлых любителей Баша Мелкомягкие встроили в PowerShell алиасы. Т.е., по сути, ярлыки с башевскими командами, которые активируют Шеловские.
Например, знакомый по башке Man включает здесь Get Help, а ls – виндовый GetChildItem. Общем, всё для того, чтобы очкастым пацанчикам было удобно и интуитивно понятно.
Операции в PowerShell
Над переменными и значениями можно выполнять различные операции. Аримфетику, логические операции. Само собой присваивание в переменной. И т.д.
Так, если в переменные вы загоните числа и попытаетесь произвести над ними какие-то операции, то само-собой всё получится. Однако, если эти же числа оградить кавычками, то Shell не поймёт, что вам надо и выдаст белиберду.
Синтаксис необходимый для работы с операциями объяснять подробно в данном видео я не буду, ибо он аналогичен истории с Башем. Если не смотрели, то видео, то обязательно ознакомьтесь.
В повседневной работе пригождается, как правило только арифметика, логика и присваивание. Как и в случае с башем у нас есть так называемые ПайпЛайны, они же трубы. Только в Башке всё построено на строках.
Т.е. там команды возвращают строки, которые могут быть переданы через конвейер в другие команды. А в PowerShell функции возвращают объекты.
Так, к примеру функция Write-Host имеющая более привычный для всех алиас Echo разрывает цепочку событий.
Если вы запускаете скрипт, то понятно, что у него есть какой-то параметр. В случае со скриптами написанными на PowerShell, которые, к слову, имеют расширение *ps1, эти параметры существуют в виде специального списка args.
Для того, чтобы получить конкретные аргументы этого списка, вам нужно указать это дело с помощью квадратных скобок. Логика тут такая же, как при работе с массивами.
Соответственно параметр Count выдаст вам количество аргументов всего.
Условный оператор PowerShell
Согласитесь, что было бы не так весело и интересно, если бы в PowerShell не было условного оператора. Синтаксис у этого дела здесь значительно проще, чем в Баше. За что Мелкомягким отдельный респект.
Вы пишите ключевое слово if, в условиях любое булевое сравнение, и соответственно всё что потом в скобках будет исполнено, если условие выполнено.
Соответственно если у вас есть часть Else, то будет выполняться, то что идёт после неё. В случае, когда необходимо проверить несколько условий, используется ключевое слово elseif.
В PowerShell есть даже специальные командлеты, которые позволяют проверить дополнительные условия. В частности, Test-Path, проверяющий наличие пути.
Например, можно задать конструкцию, где если такой-то путь существует – мы что-то делаем. С помощью ключей к данному командлету, можно проверить время создания, новее файл или старее, тип пути, наличие внутри данных и т.д.
Циклы PowerShell
Циклы в pShell, как и в баше позволяют выполнять одни и те же действия над разными элементами. В баше соответственно циклы проводились либо над элементами строчки, либо над набором строк.
В PowerShell’е всё почти также, только чутка по-другому. К примеру, есть цикл ForEach и в нём цикл для переменной задаётся в объекте списка. Т.е. вы передаёте список элементам и над ними уже что-то делаете.
Также есть цикл While, т.е. отрабатывать до тех пор, пока условие выполняется. И цикл Do While в котором условие проверяется в конце. В качестве примера вот вам простенький цикл.
Если вкурили, непременно напишите в комментах для чего применяется такая конструкция. Нечто подобное мы с вами уже проходили, но закрепить имеющиеся знания интерпретировав это в другой среде – лишним не будет.
Окей, давайте рассмотрим ещё примерчики. Если мы пихаем в переменную Проц Гет процесс, без каких-то аргументов, то мы получаем список всех процессов.
Если мы проходим по этому списку, то мы можем от каждого элемента, т.е. от каждого процесса-объекта что-то получить. Например, его имя.
Ещё один способ создать список чисел – это использовать конструкцию из двух точек между ними. В примере, в переменную Nodes присваивается список от 1 до 10, а потом для каждого элемента списка прогоняется какая-либо команда.
Вот ещё одна вариация. В ней вы генерите дополнительные имена. Как и в прошлом примере делается список Nodes, задаётся переменная равная двум, и до тех пор, пока значение переменной N меньше либо равно количеству элементов в этом списке, мы печатаем строчку файл плюс номер N. А сам N увеличиваем на два.
Если вы захотите создать бесконечный цикл, то в PowerShell для этого достаточно просто создать цикл от специальной переменной под названием True (истина).
Для выхода из циклов тут, как и в Баше, используется Брейк. Тут всё понятно. Если при исполнении вашего цикла PowerShell натыкается на слово Континью, то вместо продолжения тела цикла, происходи возврат назад для выполнения следующей итерации.
Эту историю можно использовать в ситуации, когда мы хотим прошерстить все файлы на диске и вывести имена для всех директорий, а для файлов пропустить.
Для этого потребуется написать соответствующее условие, мол если директория, то сделать то-то. А если файл, то не трогать. Если вы уже поднаторели в написании циклов на Баше, то с PowerShell’ом проблем у вас не возникнет.
Окей, друзья. Нынче мы узнали основные вещи про PowerShell. Рассмотрели возможности переменных, которые здесь в отличие от Баша представляют собой объекты.
Познакомились с условным оператором, циклами. Разобрали базовые командлеты. Узнали про специальную PowerShell’овскую интегрированную среду для написания скриптов.
И вообще, я считаю, отлично провели время. Надеюсь, вы поняли, что главным преимуществом PowerShell’а над любой командной строкой является прямая работа с ОС Windows.
Т.е. все эти командлеты – это не просто скрипты, а сущности операционной системы. С их помощью можно менять практически все настройки вышеупомянутой ОСьки.
В Unix-системах Баш, конечно, тоже позволяет делать подобные правки, но делать всё это через текст, поверьте в разы труднее. В этом плане продукт мелкомягких затыкает Линуху за пояс. Хотя и говорить это немножко больно.
А вот о чём, мне говорить не только не больно, а даже хочется, так это о моём авторском курсе, ориентированном на начинающих программистов и людей, занимающихся разработкой, с чётким названием «GIT-это просто!»
Для его создания с нанял стороннего специалиста по данной теме и в тандеме у нас получилось сделать не просто качественный и весёлый, а суперполезный продукт, изучив который вы приобретёте в копилку скилл востребованный в любой IT-ветке.
Если ты начинающий или более-менее опытный разработчик, сисадмин помешанный на автоматизации или безопасник занимающийся скриптами – эта темка тебе точно зайдёт.
Специально для тех, кто досмотрел видео до этой минуты, я приготовил скидочный промокод, введя который вы получите 15% скидку на курс. А внезапно образовавшийся профит можно потратить на распутных женщин и виски.
Ссылку на практический курс «GIT – Это просто!» и на другие авторские материалы от Денчика ищи в описании. Поддержки проект не только словом. И я непременно отблагодарю тебя новой порцией полезнейших знаний по полной программе.
Ну а на сим нынче всё. Если понравилось видео, то не забудьте влепить под ним лайк и написать комментарий, насколько вы шарите в PowerShell’е лучше меня.
Ведь это же Интернет и тут вы можете запросто самоутвердиться, просто умея лихо печатать с двух рук. В реальной жизни за любые дерзости вас бы уже, конечно, избили и обоссали, но тут вы вольны понтоваться сколько угодно.
Так что пользуйтесь мнимой иллюзией свободы, пока это вообще возможно. Прокачивайте полезные навыки. Изучайте современные инструменты для автоматизации окружающего пространства. И будем вам счастье.
Помните, технологии – это весело. Во всяком случае информационные сто пудово. За другие ручаться не буду. Ладненько, с вами, как обычно, был Денчик. До новых встреч, мои кайфные друже. Всем пока.