Start в PowerShell

Введение

Википедия говорит нам: Windows PowerShell — расширяемое средство автоматизации от Microsoft, состоящее из оболочки с интерфейсом командной строки и сопутствующего языка сценариев.

Выглядеть среда PowerShell может так, как командная строка:


powershell.exe

Или в виде приложения:


powershell_ise.exe

Powershell_ise.exe называется интегрированной средой сценариев — Windows PowerShell ISE. Позволяет работать с языком в удобной среде с подсветкой синтаксиса, конструктором команд, автозаполнением команд по нажатию TAB и прочими прелестями. Идеальна для создания и тестирования сценариев.

Для запуска среды powershell.exe или powershell_ise.exe достаточно набрать аналогичное название в строке выполнить.

Файл сценария PowerShell имеет расширение .ps1.

Сценарий не получится запустить двойным ЛКМ. Это сделано специально для того, чтобы не нанести вред системе случайно запущенным скриптом.

Для запуска, по клику ПКМ следует выбрать «Выполнить с помощью PowerShell»:

Помимо того, что существует ограничение по запуску сценариев ЛКМ, по умолчанию выполнение сценариев в системе запрещено, опять же, по описанной выше причине — не нанести вред системе. Для проверки текущей политики выполнения выполним команду:

Get-ExecutionPolicy

Мы получим одно из следующих ниже значений. С большой вероятностью, если это был первый запуск, мы получим Restricted.

  • Restricted — Сценарии не могут быть запущены;
  • AllSigned — Могут быть запущены только сценарии, подписанные доверенным издателем. Перед выполнением сценария доверенного издателя будет запрашиваться подтверждение;
  • RemoteSigned — Разрешено выполнять созданные нами сценарии и скачанные сценарии, подписанные доверенным издателем;
  • Unrestricted — Никаких ограничений, все скрипты могут быть запущены.

Для выполнения и тестирования понизим политику до RemoteSigned выполнив команду:

Set-ExecutionPolicy RemoteSigned

Приступаем к работе

 

Командлет

 

  • Командлетами называются команды PowerShell, в которых заложена различная функциональность;
  • Командлеты могут быть как системными, так и пользовательскими, созданные кем-либо;
  • Командлеты именуются по правилу Глагол-Существительное, что упрощает их запоминание;
  • Командлеты выводят результаты в виде объектов или их коллекций;
  • Командлеты могут как получать данные для обработки, так и передавать данные по конвейеру (про конвейеры позже);
  • Командлеты не чувствительны к регистру (можно написать и get-process, и Get-Process, и GeT-pRoCeSs);
  • После командлетов не обязательно ставить «;«, за исключением, когда мы выполняем несколько командлетов в одну строку (Get-Process; Get-Services).

Например, для получения текущих процессов, мы выполним команду:

Get-Process 

И получим результат:

Попробуйте самостоятельно выполнить:

Get-Service #для получения статуса служб, запущенных на компьютерах

 

Get-Content C:\Windows\System32\drivers\etc\hosts #для получения содержимого файла. В данном случае, файл hosts

Не обязательно знать наизусть все командлеты. Get-Help спасёт ситуацию.
Информацию о всех доступных командлетах можно получить, введя следующую команду:

Get-Help -Category cmdlet

Если мы используем PowerShell ISE, мы облегчаем процесс разработки.
Достаточно ввести знак тире «» после того, как ввели командлет, и мы получим все возможные варианты параметров и их типы:

Попробуйте выполнить:

Get-Service -Name p*

Если, всё же, мы забудем какие свойства есть у того или иного командлета, прогоним его через Get-Member:

Get-Process | Get-Member

#Знак "|" называется конвейером. О нём ниже.

Недостаточно информации? Обратимся к справке с параметром -Examples:

Get-Help Get-Process -Examples

Получаем описание Get-Process, да ещё и с примерами использования:

  • Командлеты могут иметь сокращённые названия — алиасы. Например, вместо Get-Help можно использовать просто Help. Для получения всех сокращений выполните Get-Alias.

Попробуйте выполнить:

Start-Process notepad

Что аналогично записи:

start notepad

А теперь остановим процесс:

Stop-Process -Name notepad

Или так:

spps -Name notepad

Немногим ранее мы сказали, что командлеты именуются по правилу Глагол-Существительное. Уточню, что глагол не обязательно должен быть Get. Помимо того, что мы можем получать, мы можем задавать Set (помните, Set-ExecutionPolicy), запускать Start, останавливать Stop, выводить Out, создавать New и многие другие. Название командлета ни чем не ограничивается и, когда мы будем с вами создавать свой собственный, сможем назвать его так, как душе угодно.

Попробуем выполнить вывод в файл:

"Hello, Habr!" | Out-File C:\test.txt
& C:\test.txt

Кстати, аналогично можно записать так:

"Hello, Habr!" > C:\test.txt
& C:\test.txt

 

Комментарии

Мы все знаем, использовать комментарии является хорошим тоном.

Комментарии в PowerShell бывают строчные — # и блочные — <##>:

Обратим внимание, на код из примера:

Get-WmiObject -Class Win32_OperatingSystem | SELECT Caption

Для тех, кто знаком с WMI, кто делает это на старом добром VBScript, помните, сколько кода надо написать?

On Error Resume Next
strComputer = "."
Set objWMIService = GetObject("winmgmts:\\" & strComputer & "\root\cimv2")
Set colItems = objWMIService.ExecQuery("Select * from Win32_OperatingSystem",,48)
For Each objItem in colItems
    Wscript.Echo "Caption: " & objItem.Caption
Next

 

Конвейер

Конвейер (|) — передаёт выходные данные одной команды во входные данные на обработку другой команде. Мы использовали конвейер ранее, получая все свойства объекта или, в предыдущем примере, выбирая из набора данных только поле Caption.

Чтобы понять принцип конвейера, давайте выполним код:

Get-Service | Sort-Object -property Status

Что произойдёт: получаем все службы (Get-Service), передаём все полученные службы на сортировку в командлет Sort-Object и указываем, что хотим отсортировать их по параметру Status. На выводе мы получим сначала все службы со статусом Stop, а потом все службы со статусом Running.

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

Get-Service | WHERE {$_.status -eq "Running"} | SELECT displayname

В примере мы используем $_. Данная запись означает текущий элемент в конвейере.

Послесловие

В этой части мы научились запускать PowerShell, разобрались с политикой выполнения сценариев. Поняли, что такое командлеты, знаем, как передавать их по конвейеру и как получить их свойства. Если мы что-то забудем, обязательно Get-Help.

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

← Перейти к I части

Введение

Начать я хочу с ответов на вопросы, возникшие в первом нашем с Вами Jump Start’е:

В чём огромные возможности PowerShell? Зачем мне его изучать?

 

Я не занимаюсь администрированием, что тогда?

 

Можно же просто посмотреть видео на MVA!

 

Переменные

 

  • Переменная в PowerShell начинается со знака $ (в Евросоюзе со знака €) и в названии может содержать любые буквы, цифры и символ подчёркивания.
  • Чтобы назначить переменной значение, достаточно его ей присвоить знаком «=«. Чтобы вывести значение переменной, можно просто написать эту переменную. Вывод информации мы разберём по тексту ниже.
    $var = 619
    $var
    

  • Над числами можно производить арифметические операции, строки можно складывать. Если к строке прибавить число, число автоматически преобразуется в строку.
    $a = 1
    $b = 2
    $c = $a + $b
    $c   #c = 3
    
    $str = "Хабра"
    $str = $str + "хабр"
    $str   #str = Хабрахабр 
    
    $str = $str + 2014
    $str   #str = Хабрахабр2014
    
    
  • Если нам надо узнать, какой тип имеет та или иная переменная, можно воспользоваться методом GetType()
    $s = "Это строка?"
    $s.GetType().FullName
    

  • Тип переменной PowerShell определяет автоматически или его можно назначить вручную.
    $var = "one"
    [string]$var = "one"
    

    PowerShell использует типы данных Microsoft .NET Framework. Рассмотрим основные:

    Тип / .NET класс Описание
    [string]

    System.String

    Строка

    $var = "one"
    
    [char]

    System.Char

    Символ

    $var = [char]0x263b
    
    [bool]

    System.Boolean

    Булево. Может иметь значение $true или $false.

    $bvar = $true
    
    [int]

    System.Int32

    32-разрядное целое число

    $i = 123456789 
    
    [long]

    System.Int64

    64-разрядное целое число

    $long_var = 12345678910
    
    [decimal]

    System.Decimal

    128 битное десятичное число. Буква d на конце числа обязательна

    $dec_var = 12345.6789d
    
    [double]

    System.Double

    8-байтное десятичное число с плавающей точкой

    [double]$double_var = 12345.6789
    
    [single]

    System.Single

    32 битное число с плавающей точкой

    [single]$var = 123456789.101112
    
    [DateTime]

    System.DateTime

    Переменная даты и времени.

    $dt_var = Get-Date
    
    [array]

    System.Object[]

    Массив. Индекс элементов массива начинается с 0 — чтобы обратиться к первому элементу массива $mas, следует написать $mas[0].

    $mas = "one", "two", "three"; 
    

    Для добавления элемента к массиву, можно записать

    $mas = $mas + "four"
    

    Каждый элемент массива может иметь свой тип

    $mas[4] = 1
    
    [hashtable]

    System.Collections.Hashtable

    Хеш-таблицы. Различие между хэш-таблицами и массивами в том, что в массивах используются индексы, а в хэш-таблице именованные ключи. Хеш-таблицы строятся по принципу: @{ ключ = «значение» }

    $ht = @{odin="one"; dva="two"; tri="three"} 
    

    Чтобы добавить элемент к хеш-таблице, можно или присвоить ей тот ключ, которого ещё нет, или воспользоваться методом Add(). Если присваивание делать к существующему ключу — значение ключа изменится на присваиваемое. Для удаления элемента из хеш-таблицы есть метод Remove().

    $ht.Add("chetyre", "four")
    $ht.pyat = "five"
    $ht.Remove("dva")
    

Вы наверняка уже поняли, что в переменную можно записать не только какое-то определённое значение и заметили в таблице класс System.Object[]. В переменную так же можно записать вывод любого командлета.

Разберём боевую задачку: требуется узнать IP-адрес и MAC-адрес нескольких компьютеров в сети. Имена компьютеров domain-comp1, domain-comp2. Вариант решения под спойлером:

Показать код

 

Область действия переменных

Область действия переменной в PowerShell может быть либо локальной, либо глобальной. По умолчанию переменная имеет локальную область действия и ограничена областью действия, например, доступна только в функции или только в текущем сценарии. Глобальная переменная действует во всём текущем сеансе PowerShell. Для того, чтобы обозначить глобальную переменную, достаточно написать следующую конструкцию: $Global: переменная = значение

$Global:var = 12

И ещё фишка по теме переменных… Как-то, обсуждая с коллегой 1С и его русскоязычную среду программирования, задались вопросом:

— Интересно, а если в PowerShell задать функцию или переменную на русском языке, она будет работать?

 

Операторы сравнения и логические операторы

Операторы сравнения и логические операторы проверяют равенство или соответствие между двумя значениями.

  • При выполнении условия, конструкция сравнения всегда возвращает логическое значение $true или $false, если условие ложь.

В таблице ниже приведены операторы сравнения:

Оператор Описание Пример
-eq Equal / Равно (=)
$var = "619"
$var -eq 123   #$false
-ne Not equal / Не равно (<>)
$var = "619"
$var -ne 123   #$true
-gt Greater than / Больше (>)
$var = "619"
$var -gt 123   #$true
-ge Greater than or equal / Больше или равно (>=)
$var = "619"
$var -ge 123   #$true
-lt Less than / Меньше (<)
$var = "619"
$var -lt 123   #$false
-le Less than or equal / Меньше или равно (<=)
$var = "619"
$var -le 123   #$false
-like Сравнение с учётом символа подстановки
"Habra" -like "habr*"   #true
-notlike Сравнение с учётом не соответствия символа подстановки
"Habra" -notlike "habr*"   #false
-contains Содержит ли значение слева значение справа
1, 2, 3, 4, 5 -contains 3   #$true
-notcontains Если значение слева не содержит значение справа, получим истину
1, 2, 3, 4, 5 -notcontains 3   #$false
-match Использование регулярных выражений для поиска соответствия образцу
$str = "http://habrahabr.ru"
$str -match "^http://(\S+)+(.ru)$"   #$true
-notmatch Использование регулярных выражений для поиска несоответствия образцу
$str = "http://habrahabr.ru"
$str -notmatch "^http://(\S+)+(.com)$"   #true
-replace Заменяет часть или все значение слева от оператора
"Microhabr" -replace "Micro","Habra"   #Habrahabr

Разберём пример. В примере мы формируем путь до возможного профиля пользователя на удалённом компьютере в зависимости от операционной системы. Решение под спойлером:

Показать код

Кстати, регулярные выражение в PowerShell очень хорошо описал Xaegr в своём блоге. Стоит того, чтобы потратить пару часов на прочтение и постичь умение написания regular expressions.

  • Можно дополнительно задать условие, если при сравнении следует учитывать регистр. Для этого следует перед оператором подставить букву «c»
    $str1 = "Habr"
    $str2 = "habr"
    $str1 -ceq $str2   #$false
    
  • Можно использовать несколько операторов сравнения, применяя логические операторы. Логические операторы перечислены в таблице ниже:

 

Оператор Описание Пример
-and Логическое и
("Строка" -eq "Строка") -and (619 -eq 619)   #$true
-or Логическое или
("Строка" -eq "Строка") -or (619 -eq 123)   #$true
-not Логическое не
-not (123 -gt 324)   #$true

или

!(123 -gt 324)   #$true

 

Пара слов про ifelseif и else
if ( условие1-верно ) { выполняем-код }   #если условие 1 верно, выполняем код, если нет - идём дальше
elseif ( условие2-верно ) { выполняем-код }   #необязательное условие: иначе, если условие 2 верно, выполняем код
else { выполняем-код }  #необязательное условие: если прошлое условие не верно, выполняем код

Всё совсем просто. Если условие верно, мы выполняем следующий за условием код в фигурных скобках. Если условие не верно, то мы пропускаем выполнение и смотрим, продолжается ли у нас условие дальше.
Если находим elseif — проверяем новое условие и так же, в случае успеха, выполняем код, иначе, снова смотрим, есть ли продолжение в виде elseif или else.
Если условие выполняется, то код выполняется и ветка elseif или else пропускается.

$str = ""
if ( 1 -gt 2 ) { $str = "Апельсин" } 
elseif ( $str -eq "Апельсин" ) { $str } 
else { $str = "Яблоко"; $str } 

 

Ответ

 

Вывод информации

Рассмотрим несколько основных вариантов вывода информации на экран:

  • Запись в файл, используя Out-File
    $str = "Hello Habr!"
    $str | Out-File D:\out_test1.txt
    

    или, как мы говорили в I части, использовать знак «>»

    $str = "Hello Habr!"
    $str > D:\out_test2.txt
    
  • Экспорт данных в .csv файл, используя Export-Csv
    $p = Get-Process
    $p | SELECT Name, Path | Export-Csv -Path D:\out_test3.csv
    
  • Запись в файл HTML, используя ConvertTo-Html
    $h = Get-Process
    $h | ConvertTo-Html -Property Name, Path > D:\out_test4.html
    & D:\out_test4.html   #Откроем файле после формирования
    

    Работать с HTML выводом на самом деле очень приятно. Имея навыки web-программирования можно добавить стилей и на выходе получить очень симпатичные отчёты.

Прочитать файл нам поможет уже знакомый нам командлет Get-Content

Get-Content D:\out_test1.txt

Циклы

Циклы в PowerShell мало чем отличаются от циклов в других языках. Почти всё как и везде:

Do While

Делать до тех пор, пока условие верно

$x = 10

do
{
    $x
    $x = $x - 1    
}
while ($x -gt 0)

 

Do Until

Цикл, который повторяет набор команд, пока выполняется условие

$x = 0

do
{
    $x
    $x = $x + 1    
}
until ($x -gt 10)

 

For

Цикл, который повторяет одинаковые шаги определённое количество раз

for ($i = 0; $i -lt 10; $i++)
{ 
    $i
}

 

ForEach

Цикл по коллекции объектов

$collection = "Имя-Компьютера1", "Имя-Компьютера2", "Имя-Компьютера3"
foreach ($item in $collection)
{
    $item 
}

 

Пишем функции

 

  • Функции в PowerShell имеют следующую структуру:
    function имя-функции ([параметр1, ..., параметрN]) 
         { 
            тело-функции 
         } 
    
  • Функции не обязательно должны возвращать результат.
  • При вызове функции, все параметры разделяются пробелами.

Например, функция для получения квадрата числа, на PowerShell будет выглядеть так:

function sqr ($a)
     {
      return $a * $a
     }

sqr 2   #Результат: 4

И на последок, пример функции, которая поможет нам выполнять транслитерацию. В этом примере как раз всё то, что мы сегодня рассматривали:

Показать код

 

Послесловие

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

Источник: https://habrahabr.ru/post/242425/

Добавить комментарий

Ваш адрес email не будет опубликован.