Політика виконання скриптів PowerShell.
При розробці PowerShell особливу увагу було приділено безпеці. Одним із заходів безпеки є наявність політики виконання (Execution Policy), яка визначає, чи можуть скрипти PowerShell виконуватися в системі, і якщо можуть, то які саме.
Для прикладу візьмемо чисту Windows 10, відкриємо консоль PowerShell і спробуємо виконати простий скрипт.Спроба завершиться помилкою, оскільки, як видно з повідомлення, виконання скриптів в системі заборонено.
Це спрацювала політика виконання, і якщо ми все ж хочемо виконати скрипт, то її необхідно змінити. Вибрати можна одне з наступних значень:
• Restricted - в системі заборонено виконання будь-яких скриптів, допускається тільки виконання окремих команд.Це політика за замовчуванням для клієнтських ОС Windows;
• AllSigned - дозволено виконання тільки скриптів, що мають цифровий підпис від довіреної видавця;
• RemoteSigned - для віддалених скриптів потрібна наявність цифрового підпису, локальні скрипти виконуються без обмежень.Віддаленими вважаються скрипти, отримані з віддалених джерел (завантажені з інтернету, отримані по електронній пошті і т.п.), локальними - скрипти, створені на локальному комп'ютері. Це політика за замовчуванням для серверних ОС Windows;
• Unrestricted - дозволено виконання будь-яких скриптів, як локальних так і віддалених.При виконанні віддаленого скрипта без цифрового підпису буде видано попередження. Це дефолтна і єдино можлива політика для всіх ОС, відмінних від Windows;
• Bypass - дозволено виконання будь-яких скриптів, ніякі попередження та інші запити не виводяться;
• Default - скидає політику на значення за замовчуванням.Для серверів це RemoteSigned, для клієнтів Restricted;
• Undefined - не визначене. У разі, якщо значення політики не визначено, то застосовується політика Restricted.
Теоретично все зрозуміло, перевіримо на практиці. Для перегляду параметрів політики використовується командлет Get-ExecutionPolicy, а для зміни Set-ExecutionPolicy.
Для початку виведемо діючу політику виконання командою:
Get-ExecutionPolicy
Як і очікувалося, поточна політика Restricted. Дозволимо виконання скриптів, встановивши для політики значення Unrestricted:
Set-ExecutionPolicy Unrestricted -Force
І ще спробуємо запустити скрипт. Цього разу він виконався без помилок.
Політика Unrestricted дозволяє виконання будь-яких скриптів, але у неї все ж є обмеження. Для перевірки я підготував два скрипта, локальний localscript.ps1 і віддалений remotescript.ps1. Спочатку запустимо локальний, він виконається без проблем. А ось при запуску віддаленого скрипта PowerShell видасть попередження і зажадає підтвердити його запуск.При ручному виконанні це не є великою проблемою, а от у випадку автоматичного запуску (напр. З планувальника) скрипт може не відпрацювати.
Тепер змінимо політику на Bypass і ще раз запустимо віддалений скрипт. Цього разу він просто виконався, без жодних повідомлень і підтверджень.Bypass зручно використовувати в ситуаціях, коли скрипт повинен гарантовано відпрацювати, причому автоматично, без втручання користувача.
Наступним пунктом нашого меню йде політика RemoteSigned. Вона є найбільш збалансованою як з точки зору безпеки, так і зручності використання, тому на серверах включена за замовчуванням.Встановимо для політики значення RemoteSigned і перевіримо її дію. Локальний скрипт знову виконується без проблем, а віддалений видає помилку, оскільки у нього немає підпису.
У вас може виникнути питання, як саме PowerShell розрізняє локальні і віддалені скрипти.Тут все просто. При завантаженні файлу додаток (напр. Браузер) додає файл ідентифікатор зони (ZoneId), який і визначає, звідки було взято файл. Ідентифікатор зберігається в альтернативному потоці і має значення від 0 до 4:
• Локальний комп'ютер (0)
• Місцева мережа (1)
• Надійні сайти (2)
• Інтернет (3)
• Небезпечні сайти (4)
Якщо файл має ZoneId 3 або 4, то PowerShell вважає його віддаленим.А якщо на комп'ютері включена конфігурація посиленої безпеки Internet Explorer, то файли, взяті з локальної мережі, теж можуть вважатися віддаленими.
Як виконати віддалений скрипт? По-перше його можна розблокувати (перетворити в локальний), для цього є спеціальний командлет Unblock-File.Хоча якщо просто відкрити скрипт на локальному комп'ютері і внести в нього зміни, то він теж стане локальним.
Ну і по-друге віддалений скрипт можна підписати. Підписування скриптів - це тема окремої статті, тому вдаватися в подробиці не будемо. Просто підпишемо його вже наявним сертифікатом, перевіримо підпис і виконаємо.Цього разу успішно.
Переходимо до політики AllSigned. Це найбільш жорстка політика, що вимагає підписування всіх без винятку скриптів, як віддалених так і локальних. І навіть з підписаними скриптами вона працює не так, як RemoteSigned. Для прикладу змінимо політику на AllSigned і знову запустимо підписаний скрипт.Цього разу для його виконання буде потрібно підтвердження, тому що PowerShell порахував підпис недовірених.
Області застосування
Політика виконання має свою область дії (scope). Всього є 5 областей:
• LocalMachine - політика діє на всіх користувачів даного комп'ютера.Значення зберігається в реєстрі, в розділі HKEY_LOCAL_MACHINE;
• CurrentUser - політика діє тільки на поточного користувача. Зберігається в розділі реєстру HKEY_CURRENT_USER;
• Process - дія політики поширюється тільки на поточний сеанс PowerShell. Значення зберігається в змінної оточення $ PSExecutionPolicyPreference і при закритті сеансу видаляється;
• Userpolicy - політика діє на всіх користувачів даного комп'ютера.Поширюється за допомогою групових політик. Значення зберігається в розділі користувача, відповідно політика застосовується при вході користувача в систему;
• MachinePolicy - діє на всіх користувачів даного комп'ютера. Поширюється за допомогою групових політик.Значення зберігається в розділі комп'ютера, політика застосовується при завантаженні системи;
Вивести значення політики для всіх областей можна командою:
Get-ExecutionPolicy -List
Виходить, що при установці політики без вказівки області змінюється значення LocalMachine.Якщо ж потрібно вказати конкретну область дії, то зробити це можна за допомогою параметра Scope командлет Set-ExecutionPolicy. Для прикладу встановимо для області СurrentUser політику Bypass:
Set-ExecutionPolicy -Scope CurrentUser -ExecutionPolicy Bypass -Force
Потім перевіримо значення політики в поточному сеансі та переконаємося в тому, що воно змінилося на Bypass.
Тепер встановимо політику Unrestricted для області Process:
Set-ExecutionPolicy -Scope Process -ExecutionPolicy Unrestricted -Force
Ще раз перевіримо поточну політику, тепер вона має значення Unrestricted. Тобто більш "конкретна" політика завжди має більший пріоритет.
Для областей UserPolicy і MachinePolicy значення політики задаються через GPO.За настройку відповідає параметр Turn on Script Execution (Включити виконання сценаріїв), що знаходиться в розділі Administrative Templates \ Windows Components \ Windows PowerShell. Для UserPolicy він знаходиться в конфігурації користувача (User Configuration), для MachinePolicy - в конфігурації комп'ютера (Computer Configuration). Політика, що застосовується до комп'ютера, має пріоритет перед політикою користувача.
Для установки політики треба включити параметр і вибрати одне з трьох значень:
• Allow only signed scripts (дозволяти тільки підписані сценарії) - політика AllSigned;
• Allow local scripts and remote signed scripts (дозволяти локальні і віддалені підписані сценарії) - політика RemoteSigned;
• Allow all scripts ( вирішувати все сценарії) - політика Unrestricted.
Політика Bypass вважається небезпечною і її не можна встановити через групові політики.
для прикладу встановимо для MachinePolicy політику RemoteSigned і перевіримо результат. Як бачите, політика, призначена через GPO, має більший пріоритет і перевизначає всі інші політики.
Більш того, при використанні GPO стає неможливим перепризначити політики вручну. При спробі зміни видається попередження, а поточна політика залишається без змін.
А що буде, якщо ні для однієї області політика не визначена, т.е. всюди стоїть значення Undefined? У цьому випадку все просто, виконання всіх скриптів забороняється, а поточна політика приймає значення Restricted.
Обхід політики
чи можна як то запустити скрип в обхід політики виконання, не змінюючи її значення? В принципі можна, є кілька способів.
Наприклад для того, щоб виконати скрипт, досить відкрити його в провіднику, натиснути правою кнопкою миші і вибрати пункт Виконати за допомогою PowewrShell (Run with PowerShell). Це запускає оболонку PowerShell c політикою Bypass. При цьому політика застосовується тільки для виконання конкретного скрипта, значення політики в реєстрі не змінюється.
Цей спосіб називається "Run with PowerShell" і у нього є деякі обмеження. Скрипти, запущені таким чином, не можуть взаємодіяти з користувачем (виводити повідомлення на екран, вимагати введення даних і т.п.). Скрипт просто запускається, виконується і негайно закривається.
Власне кажучи, попередній спосіб використовує запуск PowerShell із зазначенням необхідної політики. Зробити це можна з командного рядка, наприклад для запуску скрипта можна спробувати таку команду:
powershell.exe -file. \ Script.ps1 -Executionpolicy Bypass
Теоретично ця команда повинна виконати скрипт, не дивлячись на поточну політику.Так написано в офіційній документації Microsoft. На практиці ж цей спосіб працює не завжди, наприклад на одному з перевірених мною комп'ютерів я отримав помилку. При цьому з провідника скрипт успішно виконався.
Ще один варіант - це спробувати змінити політику виконання для області Process.Ця операція не вносить змін до реєстру і не вимагає прав адміністратора. Але в тому випадку, якщо для призначення політики виконання використовуються групові політики, цей спосіб не спрацює.
Ну і нарешті можна просто вважати вміст скрипта і виконати його у вигляді команди.Наприклад так:
$ script = Get-Content ./script.ps1
Invoke-Expression -Command "$ script"