Политика выполнения PowerShell и подпись скриптов — практическое руководство, как перестать «затыкать дыры» параметром Bypass
· Го Комура · PowerShell, Windows, Политика выполнения, Подпись кода, Безопасность, Скрипт, Улучшение эксплуатации, Автоматизация
«На новом ПК скрипт не запускается, выдавая «выполнение сценариев в данной системе отключено…»». «Просто добавили -ExecutionPolicy Bypass и всё заработало, теперь так написано во всех задачах». «Файл .ps1, лежащий в общей папке, выдаёт ошибку подписи только на одном компьютере». Политика выполнения PowerShell — это стена, в которую почти наверняка упрётесь, продвигая автоматизацию внутри компании. И на многих площадках накапливается практика «затыкать дыры Bypass», не разбираясь в самом механизме.
Сложность в том, что легко неправильно понять, «что именно защищает» политика выполнения. Одни считают её функцией безопасности, закручивают гайки слишком туго — и работа встаёт. Другие решают, что «всё равно бесполезно», ставят везде Bypass — и снимают тем самым последний защитный механизм, предотвращающий случайные ошибки. Обеих крайностей можно избежать, если понимать сам механизм.
Эта статья адресована сотрудникам ИТ-отделов малых и средних компаний, а также всем, кто автоматизирует рутинные внутренние задачи с помощью PowerShell. Мы разберём, опираясь на официальную документацию, что на самом деле представляет собой политика выполнения, как работает приоритет областей действия, как она связана с Zone.Identifier (так называемым Mark of the Web), и как организовать распространение скриптов через их подпись.
1. Сначала вывод
- Политика выполнения — это защитный механизм, а не граница безопасности. Официальная документация прямо утверждает: «политика выполнения — это не система безопасности, ограничивающая действия пользователя» и «её легко обойти, введя содержимое скрипта в командную строку». Её цель — задать базовые правила и предотвратить непреднамеренное выполнение (случайные ошибки).1
- Политика выполнения влияет только на запуск скриптов — интерактивный запуск команд всегда возможен. По умолчанию в Windows PowerShell 5.1 на клиентских ОС установлена политика Restricted (запуск скриптов запрещён), а на Windows Server — RemoteSigned. В PowerShell 7 политикой по умолчанию считается RemoteSigned.21
- У политики есть пять областей действия, приоритет которых выглядит так: MachinePolicy > UserPolicy > Process > CurrentUser > LocalMachine. MachinePolicy и UserPolicy предназначены только для групповой политики, их нельзя изменить командой
Set-ExecutionPolicy, и указание в командной строке их тоже не перекрывает.13 - RemoteSigned требует подписи только для скриптов «из интернета». Происхождение определяется по прикреплённому к файлу альтернативному потоку данных Zone.Identifier (Mark of the Web); проверив содержимое и удалив его командой
Unblock-File, скрипт можно запустить, не меняя политику.14 - AllSigned требует подписи доверенного издателя для всех скриптов, включая созданные локально. Подпись ставится командой
Set-AuthenticodeSignatureи встраивается в конец файла в виде блока комментариев# SIG #.15 - Обязательно ставьте временную метку (-TimestampServer) при подписании. С временной меткой скрипт остаётся действительным даже после истечения срока сертификата подписи. Поскольку большинство сертификатов для подписи кода действительны год, пропуск этого шага превращается в ежегодную бомбу замедленного действия.65
- Самоподписанный сертификат годится только для тестирования. Скрипт, подписанный самоподписанным сертификатом, не запустится на других компьютерах. Для распространения в организации используйте сертификат для подписи кода, выданный удостоверяющим центром (внутренним ЦС или коммерческим).57
- Для организационного контроля управляйте всем централизованно через параметр групповой политики «Включить выполнение сценариев». Этот параметр имеет приоритет над всеми настройками областей действия на стороне PowerShell.1
2. Что на самом деле представляет собой политика выполнения — «защитный механизм», а не «граница безопасности»
Сначала подтвердим исходную предпосылку. Формулировка официальной документации (about_Execution_Policies) предельно откровенна. Политика выполнения — это «функция безопасности» (safety feature), контролирующая условия, при которых PowerShell загружает файлы конфигурации и выполняет скрипты, и она «не является системой безопасности, ограничивающей действия пользователя». Причина в том, что даже пользователь, которому запрещено запускать скрипт, может выполнить ту же самую обработку, просто вставив содержимое скрипта в командную строку. Прямо указано, что роль политики выполнения — задать базовые правила и предотвратить их непреднамеренное нарушение.1 Во вводной документации та же мысль повторяется: «это не граница безопасности; она не может остановить пользователя, который намеренно пытается запустить скрипт».2
Если понять эту позицию, направление проектирования эксплуатации становится ясным. Ошибочны оба утверждения — и «раз мы ужесточили политику выполнения, атаки предотвращены», и «раз её всё равно можно обойти, в ней нет смысла». Противодействие атакам — задача другого уровня (контроль приложений, минимизация прав, аудит журналов), а задача политики выполнения — предотвращение случайных ошибок.8
Ниже сведены различия между основными политиками.1
| Политика | Выполнение скриптов | Требование подписи | Позиционирование |
|---|---|---|---|
| Restricted | Запрещено (только отдельные команды) | — | Значение по умолчанию для клиентских ОС в Windows PowerShell 5.12 |
| AllSigned | Разрешено | Требуется для всех скриптов и файлов конфигурации. Перед запуском чего-либо от неклассифицированного издателя запрашивается подтверждение | Для организаций, способных наладить процесс подписи |
| RemoteSigned | Разрешено | Требуется только для скриптов из интернета. Для локально созданных не требуется | Практический стандарт. Значение по умолчанию в PowerShell 71 |
| Unrestricted | Разрешено | Нет (предупреждение вне зоны интрасети) | Значение по умолчанию для не-Windows платформ (изменить нельзя)1 |
| Bypass | Разрешено | Нет. Ни предупреждений, ни запросов | Для встраивания в приложения на базе PowerShell с собственной моделью безопасности1 |
Часто упускают из виду, что Restricted блокирует не только рабочие скрипты, но и загрузку профилей (.ps1), модулей (.psm1) и файлов конфигурации форматирования (.ps1xml).1 Классическое обращение к нам — когда причиной «профиль не загружается на новом компьютере» оказывается именно политика выполнения.
3. Области действия и приоритет — что на самом деле стоит за «я изменил, но ничего не поменялось»
Политика выполнения — это не единое значение: её можно задать отдельно для каждой из пяти областей действия, а действующим значением становится то, что имеет наивысший приоритет.1
| Область действия | Способ настройки | Где хранится | Приоритет |
|---|---|---|---|
| MachinePolicy | Групповая политика (конфигурация компьютера) | GPO | 1 (наивысший) |
| UserPolicy | Групповая политика (конфигурация пользователя) | GPO | 2 |
| Process | Параметр запуска -ExecutionPolicy / -Scope Process |
Переменная окружения $Env:PSExecutionPolicyPreference (исчезает при завершении сеанса) |
3 |
| CurrentUser | Set-ExecutionPolicy -Scope CurrentUser |
Конфигурация пользователя | 4 |
| LocalMachine | Set-ExecutionPolicy (область по умолчанию, требуются права администратора) |
Конфигурация, общая для всех пользователей | 5 |
Стандартный способ разобраться с проблемой «я настроил, но ничего не изменилось» — смотреть не на действующее значение, а на весь список.
# Обязательно проверяйте не только действующую политику, но и то, какая область действия применяется
Get-ExecutionPolicy -List
# Пример: даже если LocalMachine настроен на AllSigned, побеждает RemoteSigned из CurrentUser
# Scope ExecutionPolicy
# ----- ---------------
# MachinePolicy Undefined
# UserPolicy Undefined
# Process Undefined
# CurrentUser RemoteSigned
# LocalMachine AllSigned
# Чтобы изменить только своё окружение, удобна область CurrentUser — она не требует прав администратора
Set-ExecutionPolicy -ExecutionPolicy RemoteSigned -Scope CurrentUser
Поскольку CurrentUser имеет приоритет выше, чем LocalMachine, действующей политикой в примере выше оказывается RemoteSigned.1 Команда Set-ExecutionPolicy по умолчанию записывает в область LocalMachine, поэтому требует прав администратора, но в области CurrentUser её может изменить и обычный пользователь.3
А главный инструмент организационного управления — групповая политика. Политика «Включить выполнение сценариев» (Turn on Script Execution) имеет приоритет над всеми областями действия, заданными на стороне PowerShell. Если её отключить, действие эквивалентно Restricted; если включить, можно выбрать один из вариантов — «Разрешить все сценарии» (Unrestricted), «Разрешить локальные сценарии и подписанные удалённые сценарии» (RemoteSigned) или «Разрешить только подписанные сценарии» (AllSigned); находится она в административных шаблонах, в разделе Компоненты Windows\Windows PowerShell. Конфигурация компьютера имеет приоритет над конфигурацией пользователя.1 В среде, управляемой через GPO, команда Set-ExecutionPolicy сохранит настройку, но она не будет действовать, и появится сообщение, объясняющее конфликт.3
Отсюда следует один важный вывод. Если политика управляется через GPO, -ExecutionPolicy Bypass, прописанный в задаче или ярлыке, не действует. Прямо указано, что указание области Process побеждает конфигурацию LocalMachine/CurrentUser, но не может победить групповую политику.1 Иными словами, приём «пропиши Bypass — и всё как-нибудь заработает» срабатывает только там, где организация вообще не управляет политикой выполнения.
4. Zone.Identifier (Mark of the Web) и Unblock-File
Понятие «удалённый (из интернета)» в RemoteSigned определяется не местом хранения файла, а меткой. Программы вроде браузеров прикрепляют к скачанным файлам альтернативный поток данных, помечая их как «файл, пришедший из интернета».1 Этот поток называется Zone.Identifier и содержит значение 3, обозначающее интернет-зону. Это и есть так называемый Mark of the Web.4
При попытке запустить неподписанный скрипт с этой меткой в среде с политикой RemoteSigned запуск блокируется с ошибкой «файл не имеет цифровой подписи». Решение состоит из двух шагов.
# 1) Сначала проверьте, какие файлы заблокированы (безопасная операция, только чтение)
Get-Item -Path C:\Tools\*.ps1 -Stream Zone.Identifier -ErrorAction SilentlyContinue
# 2) Снимайте блокировку только с тех файлов, чьё содержимое вы проверили и признали безопасным
# (Unblock-File удаляет поток Zone.Identifier; сама политика выполнения не меняется)
Unblock-File -Path C:\Tools\Get-InventoryReport.ps1
Unblock-File — это командлет, удаляющий альтернативный поток данных Zone.Identifier; это та же операция, что и кнопка «Разблокировать» (Unblock) в свойствах файла в проводнике. Важно то, что можно пропускать только проверенные файлы, не ослабляя саму политику выполнения.4 Официальная документация тоже указывает обязательным шагом «проверить файл и источник его получения перед использованием и убедиться в его безопасности».43
Стоит знать и о ловушке в обратную сторону. Не каждый способ получения файла прикрепляет Mark of the Web. Прямо указано, что файлы, скачанные через curl.exe, Invoke-WebRequest или Invoke-RestMethod, иногда не получают метку интернет-зоны.1 Иными словами, RemoteSigned — не гарантия того, что «все опасные скачанные файлы будут остановлены» (именно поэтому это защитный механизм, а не граница безопасности). Есть и предупреждение о том, что в системах, настроенных не различать пути UNC и интернет-пути, скрипт на общей папке иногда отклоняется при политике RemoteSigned.1 Если «.ps1 на общей папке останавливается только на некоторых компьютерах», подозревайте настройки зон и наличие Zone.Identifier.
Кстати, о механизме SmartScreen, вызывающем похожий симптом со стороны скачанных исполняемых файлов (.exe), мы пишем в статье «Почему Windows показывает сообщение «Windows защитил ваш компьютер»».
5. Практика подписи скриптов — Set-AuthenticodeSignature и временные метки
Чтобы перейти к эксплуатации AllSigned или к подписи распространяемых файлов в среде RemoteSigned, нужен сертификат для подписи кода. Способы его получения можно свести к трём вариантам.5
| Способ получения | Область доверия | Оценка |
|---|---|---|
Самоподписанный (New-SelfSignedCertificate) |
Только свой компьютер, на других не выполняется | Только для тестирования и проверки. Не использовать для распространения57 |
| Выдан внутренним ЦС (удостоверяющим центром) | Машины в организации, настроенные доверять внутреннему ЦС | Основной вариант для среды AD-домена. Организация контролирует выдачу и отзыв сертификатов |
| Выдан коммерческим ЦС (платно) | Windows в целом (публичные ЦС уже доверены) | Для распространения скриптов за пределами организации |
Официальная документация даёт ту же классификацию: «сертификат, выданный удостоверяющим центром, доверен и на других компьютерах», а «самостоятельно созданный сертификат бесплатен, но действителен только на вашем компьютере, и его следует использовать исключительно для тестирования».5 Если цель — внутреннее распространение, реалистичнее всего выдавать сертификат для подписи кода через внутренний ЦС, например Active Directory Certificate Services.
Сначала проверим весь процесс на тестовом самоподписанном сертификате.
# Создаём тестовый сертификат для подписи кода (самоподписанный ── доверен только на этой машине)
$params = @{
Subject = 'CN=KomuraSoft Code Signing (Test)'
Type = 'CodeSigningCert'
CertStoreLocation = 'Cert:\CurrentUser\My'
HashAlgorithm = 'sha256'
}
$cert = New-SelfSignedCertificate @params
New-SelfSignedCertificate — это командлет, создающий самоподписанный сертификат для целей тестирования; указав -Type CodeSigningCert, вы добавляете расширение для подписи кода. Срок действия по умолчанию — один год.7 Если самоподписанный сертификат используется для тестирования среды AllSigned, его нужно зарегистрировать в хранилище доверенных корневых центров сертификации на этой машине.5
Само подписание в боевом режиме — это одна строка.
# Получаем сертификат для подписи кода из хранилища сертификатов и подписываем
# -CodeSigningCert лишь сужает выбор до «сертификатов, пригодных для подписи кода»,
# поэтому дополнительно ограничиваем выбор действующими сертификатами с закрытым ключом,
# а при наличии нескольких подходящих — уточняем по Subject или Thumbprint
$cert = Get-ChildItem -Path Cert:\CurrentUser\My -CodeSigningCert |
Where-Object { $_.HasPrivateKey -and $_.NotAfter -gt (Get-Date) -and
$_.Subject -eq 'CN=KomuraSoft Code Signing (Test)' } |
Sort-Object NotAfter -Descending |
Select-Object -First 1 # Если из-за продления есть несколько сертификатов с одинаковым Subject, берём тот, что действует дольше всех
# Временная метка обязательна. Благодаря ей подпись остаётся действительной даже после истечения срока сертификата
# Замените URL на службу временных меток, которую рекомендует издатель вашего сертификата (внутренний ЦС или поставщик)
Set-AuthenticodeSignature -FilePath .\Invoke-NightlyBatch.ps1 -Certificate $cert `
-HashAlgorithm SHA256 -TimestampServer 'http://timestamp.example.com'
# Проверить статус подписи можно командой Get-AuthenticodeSignature (Valid/NotSigned/HashMismatch и т. д.)
Get-AuthenticodeSignature -FilePath .\Invoke-NightlyBatch.ps1
Есть три важные особенности, которые стоит зафиксировать.65
- Подпись встраивается в конец файла в виде блока комментариев
# SIG #. Если уже есть подпись, она заменяется. Иными словами, изменение скрипта хотя бы на один символ после подписания делает подпись недействительной. Именно это и работает как обнаружение изменений. - Указание
-TimestampServerозначает, что скрипт не перестанет работать даже после истечения срока действия сертификата. Подпись остаётся действительной «пока действителен сертификат подписи» либо «пока сервер меток времени способен подтвердить, что подпись была поставлена, когда сертификат ещё был действителен»; поскольку большинство сертификатов для подписи кода действительны год, временная метка становится жизненно важной для долгосрочной эксплуатации.65 URL используемой службы меток времени следует брать из инструкций издателя вашего сертификата (ЦС). - В Windows PowerShell 5.1 и в версиях PowerShell до 7.2 скрипт для подписания нужно было сохранять в кодировке ASCII или UTF8NoBOM. Начиная с PowerShell 7.2 поддерживаются подписанные скрипты в любой кодировке.5 На площадках, где ещё используется 5.1, стоит быть особенно внимательным: проверка подписи скриптов с комментариями на японском языке из-за кодировки часто ломается. Подробнее об общих различиях между 5.1 и 7 см. в статье «Различия между Windows PowerShell 5.1 и PowerShell 7 и переход между ними».
В среде AllSigned, даже если скрипт подписан, но издатель ещё не классифицирован как доверенный или отклонённый, при запуске появляется запрос «Выполнить программное обеспечение от этого недоверенного издателя?». Если выбрать «Всегда выполнять», в дальнейшем для этого издателя подтверждение запрашиваться не будет.15 При работе с внутренним ЦС можно дополнительно распространить сертификат издателя в хранилище «Доверенные издатели» на каждой машине и полностью убрать этот запрос из эксплуатации.
6. Стандартная практика (таблица решений) — от «затыкания дыр Bypass» до процесса подписи
Управление распространением и запуском внутренних скриптов принято продумывать по следующей таблице решений.
| Вопрос | Варианты | Ориентир для решения |
|---|---|---|
| Политика окружения | Оставить Restricted / RemoteSigned / AllSigned | RemoteSigned — минимум, если вы развиваете автоматизацию. AllSigned — если есть процесс подписи1 |
| Распространение настройки | Каждый настраивает Set-ExecutionPolicy сам / Групповая политика | В доменной среде выбор однозначен — GPO. Она имеет приоритет над всеми областями действия и блокирует самовольные изменения1 |
| Доверие к распространяемым файлам | Без подписи + размещение в общей папке / Подпись кода | Эксплуатация без подписи не позволяет обнаружить изменения. Начинайте переходить к подписи в первую очередь для рабочих скриптов, запускаемых регулярно |
| Сертификат | Самоподписанный / внутренний ЦС / коммерческий ЦС | Для внутреннего распространения — внутренний ЦС. Самоподписанный — только для тестов, для внешнего распространения — коммерческий ЦС5 |
| Обращение со скачанными файлами | Ослаблять политику / проверить и снять блокировку Unblock-File | Не трогать политику, пропускать только проверенные файлы4 |
| Запуск регулярных задач | Постоянно использовать -ExecutionPolicy Bypass / наладить политику окружения + подпись |
Постоянный Bypass — отказ от защитного механизма. Под управлением GPO он и вовсе не действует1 |
Дополним последнюю строку. Проблема эксплуатации, «затыкающей дыры ExecutionPolicy Bypass», заключается не в самом факте открытия бреши в безопасности (ведь политика выполнения изначально не была границей). Проблема в следующих трёх вещах.
- Отказ от защитного механизма — вы навсегда снимаете последнюю сетку, предотвращающую случайный запуск не того скрипта или незаметный запуск изменённого скрипта.
- Расхождение с управлением — в тот момент, когда политика выполнения начинает управляться через GPO, указание Bypass перестаёт действовать, и все задачи, которые оно «затыкало», разом начинают падать.1 Это технический долг, при котором «причина, по которой всё работало», оказывается неуправляемой лазейкой.
- Помеха расследованию причин — когда Bypass разбросан по разным местам, поведение системы перестаёт быть предсказуемым по действующей политике окружения, и расследование различий между машинами («почему падает именно на этой машине») сильно усложняется.
Сам по себе Bypass — это настройка, предусмотренная для конфигураций, где приложение, встраивающее PowerShell, управляется собственной моделью безопасности.1 Смиритесь с тем, что это не то, что стоит постоянно использовать как опцию запуска для написанных людьми рабочих скриптов. Построение безопасного регулярного выполнения в планировщике заданий подробно разобрано в статье «Почему задачи планировщика заданий не запускаются или завершаются с кодом 0x1 ── разбор причин и проектирование безопасной эксплуатации».
7. Итог
- Политика выполнения — это защитный механизм, а не граница безопасности. Противодействие атакам ведите на другом уровне, а на политику выполнения возлагайте задачу «предотвращения случайных ошибок».
- У политики пять областей действия с приоритетом MachinePolicy > UserPolicy > Process > CurrentUser > LocalMachine. Диагностику начинайте с команды
Get-ExecutionPolicy -List. - RemoteSigned опирается на Zone.Identifier (Mark of the Web). Проверенные файлы пропускайте командой
Unblock-File, не ослабляя саму политику. - Подписывайте командой
Set-AuthenticodeSignature, обязательно указывая-TimestampServer. Для внутреннего распространения используйте сертификат внутреннего ЦС; самоподписанный — только для тестов. - Организационный контроль централизуйте через параметр групповой политики «Включить выполнение сценариев». Он имеет приоритет над всеми областями действия и над указанием
-ExecutionPolicy. - Постоянное использование
-ExecutionPolicy Bypass— это отказ от защитного механизма, и под управлением GPO оно не действует. Правильный путь — сделать «затыкание дыр» ненужным, наладив политику окружения и процесс подписи.
Похожие статьи
- Основы команд PowerShell ── что выучить в первую очередь и как использовать их безопасно
- Почему Windows показывает сообщение «Windows защитил ваш компьютер»
- Почему задачи планировщика заданий не запускаются или завершаются с кодом 0x1 ── разбор причин и проектирование безопасной эксплуатации
- Обработка ошибок и проектирование повторных попыток (retry) для скриптов PowerShell
- Различия между Windows PowerShell 5.1 и PowerShell 7 и переход между ними
- Переход от bat-файлов к PowerShell: как принять решение
Смежные области консультирования
KomuraSoft LLC (合同会社小村ソフト) занимается проектированием политики выполнения и процесса подписи внутренних скриптов PowerShell, рассмотрением развёртывания через групповую политику и расследованием различий окружения — например, случаев «скрипт не работает только на определённых машинах». Мы также можем помочь перевести существующие активы в виде bat-файлов и скриптов на безопасную эксплуатацию.
- Техническая консультация и ревью проекта
- Исследование ошибок и анализ первопричин
- Доработка и сопровождение существующего ПО для Windows
- Связаться с нами
Справочные ссылки
-
Microsoft Learn, about_Execution_Policies. О том, что политика выполнения — функция безопасности, а не система, ограничивающая пользователя, об определениях каждой политики (AllSigned/Bypass/RemoteSigned/Restricted/Unrestricted и т. д.), о пяти областях действия и их приоритете, о том, что область Process хранится в $Env:PSExecutionPolicyPreference и не может победить GPO, о том, что групповая политика «Turn on Script Execution» имеет приоритет над всеми областями действия, о прикреплении альтернативного потока данных к скачанным файлам и о том, что curl.exe и подобные инструменты иногда не проставляют метку, а также о предупреждении относительно путей UNC. ↩ ↩2 ↩3 ↩4 ↩5 ↩6 ↩7 ↩8 ↩9 ↩10 ↩11 ↩12 ↩13 ↩14 ↩15 ↩16 ↩17 ↩18 ↩19 ↩20 ↩21 ↩22 ↩23 ↩24 ↩25
-
Microsoft Learn, Chapter 1 - Getting started with PowerShell. О том, что политика выполнения не является границей безопасности, что по умолчанию на Windows 10/11 установлена Restricted, а на Windows Server 2016/2019/2022 — RemoteSigned, и о том, что политика выполнения влияет только на скрипты, а интерактивные команды можно выполнять всегда. ↩ ↩2 ↩3
-
Microsoft Learn, Set-ExecutionPolicy. О том, что областью действия по умолчанию является LocalMachine и требуются права администратора, что области MachinePolicy/UserPolicy изменить нельзя, что групповую политику нельзя перекрыть и при конфликте выводится сообщение, а также о примере, где Unblock-File снимает блокировку скрипта, не меняя политику выполнения. ↩ ↩2 ↩3 ↩4
-
Microsoft Learn, Unblock-File. О том, что Unblock-File удаляет альтернативный поток данных Zone.Identifier со значением 3, обозначающим интернет-зону, что это та же операция, что и кнопка «Разблокировать» в свойствах файла в проводнике, что перед использованием следует проверить безопасность файла и источника его получения, а также о том, что файлы с Zone.Identifier можно обнаружить командой Get-Item -Stream. ↩ ↩2 ↩3 ↩4 ↩5
-
Microsoft Learn, about_Signing. О типах файлов, которые можно подписывать, о разнице между сертификатом, выданным удостоверяющим центром, и самоподписанным сертификатом (самоподписанный — только для тестирования и не выполняется на других компьютерах), о том, что подпись добавляется в виде блока комментариев # SIG #, что до PowerShell 7.2 требовалось сохранение в ASCII/UTF8NoBOM, что сервер меток времени сохраняет действительность подписи после истечения срока сертификата, а также о запросе относительно недоверенного издателя. ↩ ↩2 ↩3 ↩4 ↩5 ↩6 ↩7 ↩8 ↩9 ↩10 ↩11 ↩12
-
Microsoft Learn, Set-AuthenticodeSignature. О применении подписи Authenticode, замене существующей подписи, о том, что параметр -TimestampServer предотвращает сбой скрипта после истечения срока сертификата, а также о примере получения сертификата для подписи кода с закрытым ключом через параметр -CodeSigningCert на диске Cert:. ↩ ↩2 ↩3
-
Microsoft Learn, New-SelfSignedCertificate. О том, что это командлет для создания самоподписанного сертификата в целях тестирования, что параметр -Type позволяет указать сертификат для подписи кода, а срок действия по умолчанию составляет один год. ↩ ↩2 ↩3
-
Microsoft Learn, PowerShell security features. О том, что политика выполнения позиционируется как одна из нескольких функций, повышающих безопасность среды выполнения скриптов, и рассматривается как защитный механизм, помогающий предотвратить выполнение вредоносных скриптов. ↩
Похожие статьи
Недавние статьи с теми же тегами помогут подробнее изучить близкие темы.
Обработка ошибок и повторные попытки в PowerShell — от ловушки нерабочего try/catch до exit code и типовых схем повтора
Разбираем на практике различия между завершающими и незавершающими ошибками в PowerShell, ловушку неработающего try/catch и приём -ErrorA...
Прикладной PowerShell — безопасная автоматизация анализа логов, архивирования и отчётности
Разбираем практические шаги безопасной автоматизации PowerShell-скриптами: анализ логов, CSV-отчёты, архивирование старых логов, сохранен...
Как запустить PowerShell из C# (CSharp) и получить результат в виде объектов
Разбираем, как запустить PowerShell из C# и получать результаты не строками, а объектами PSObject, — от PowerShell SDK, AddCommand и AddP...
Тестирование PowerShell с помощью Pester — практический подход к тому, чтобы эксплуатационные скрипты было труднее сломать
Практическое руководство по тестированию PowerShell-скриптов с помощью Pester v5: безопасное покрытие обработки дат, файловых операций, л...
Практические команды PowerShell — расширяем набор маленьких инструментов для повседневной работы
Практическая подборка команд PowerShell для повседневной работы: разбираем, где применять Measure-Object, Group-Object, Select-String, Co...
Связанные темы
Эти страницы показывают тему статьи в более широком контексте услуг и решений.
Технические темы Windows
Раздел о разработке Windows, расследовании сбоев и использовании существующих активов.
Услуги по этой теме
Статья напрямую связана со следующими услугами.
Разработка приложений для Windows
Бизнес-приложения, интеграция оборудования и средства связи — от требований до разработки.
Частые вопросы
Вопросы, которые часто возникают при консультациях по теме статьи.
- Является ли политика выполнения PowerShell функцией безопасности?
- Официальная документация прямо говорит: «политика выполнения — это не система безопасности, ограничивающая действия пользователя». Причина в том, что её легко обойти, просто вставив содержимое скрипта в командную строку. Цель политики выполнения — задать базовые правила и служить защитным механизмом, который предотвращает случайное «непреднамеренное выполнение скрипта», а не строить архитектуру вокруг неё как вокруг границы безопасности, останавливающей злоумышленника. Противодействие атакам — задача другого уровня (контроль приложений, минимизация прав и так далее).
- В чём разница между RemoteSigned и AllSigned?
- RemoteSigned требует подписи доверенного издателя только для скриптов, полученных из интернета (несущих Mark of the Web); скрипты, созданные локально, могут выполняться без подписи. AllSigned требует подписи для всех скриптов и файлов конфигурации, включая созданные локально, и запрашивает подтверждение перед запуском скрипта от ещё не классифицированного издателя. AllSigned — реалистичный выбор, если в компании можно наладить процесс подписи (распространение сертификатов для подписи кода и процедуру подписания); если такой инфраструктуры нет, реалистичнее выбрать RemoteSigned.
- Почему скачанный скрипт не запускается с ошибкой «не имеет цифровой подписи»?
- Потому что к файлам, скачанным через браузер и подобные программы, прикрепляется альтернативный поток данных Zone.Identifier, и они помечаются как «файл, пришедший из интернета». При политике выполнения RemoteSigned неподписанный скрипт с этой меткой блокируется от запуска. Если вы проверили содержимое и убедились в его безопасности, можно снять Zone.Identifier командлетом Unblock-File или флажком «Разблокировать» в свойствах файла в проводнике — и запустить скрипт, не меняя политику выполнения.
- Как реалистично организовать эксплуатацию скриптов PowerShell, распространяемых внутри компании?
- В целом есть два варианта. Первый — RemoteSigned плюс размещение на файловом сервере: можно начать, не выстраивая систему подписи, но в зависимости от канала распространения может прикрепиться Mark of the Web и заблокировать выполнение, а изменение скрипта обнаружить тоже не получится. Второй — AllSigned плюс процесс подписи: скрипты подписываются командой Set-AuthenticodeSignature с помощью сертификата для подписи кода (реалистичнее всего — выданного внутренним удостоверяющим центром), а политика централизованно управляется через групповую политику. В обмен на контроль над политикой выполнения и возможность обнаруживать изменения приходится нести операционные затраты на распространение и обновление сертификатов.
- Можно ли и дальше постоянно указывать -ExecutionPolicy Bypass в планировщике заданий?
- Это будет работать, но не рекомендуется. Во-первых, в среде, где политика выполнения управляется через групповую политику, указание ExecutionPolicy в командной строке не может победить групповую политику, поэтому оно попросту не действует. Во-вторых, постоянное использование Bypass — это самостоятельный демонтаж защитного механизма, предотвращающего случайный запуск, и со временем это приводит к расхождению между политикой организации и реальным положением дел на местах. Если нужна постоянная эксплуатация, правильный путь — задать политику окружения через групповую политику или через Set-ExecutionPolicy от имени администратора, а доверие к скриптам обеспечивать подписью.
- Зачем при подписи скрипта нужна временная метка (-TimestampServer)?
- Действительность подписи в принципе привязана к сроку действия сертификата подписи, но при наличии временной метки сервер меток времени подтверждает, что «подпись была поставлена, пока сертификат ещё был действителен», поэтому скрипт можно продолжать использовать и после истечения срока действия сертификата. Большинство сертификатов для подписи кода действительны около года, поэтому эксплуатация без временной метки каждый год несёт риск того, что «в один прекрасный день все подписанные скрипты компании разом перестанут работать». Обязательно указывайте -TimestampServer при подписании.
Об авторе
Страница с профилем автора статьи.
Го Комура
Представитель KomuraSoft LLC
Специализируется на разработке программного обеспечения для Windows, техническом консалтинге и расследовании сбоев, особенно в проектах с унаследованными системами и трудно воспроизводимыми ошибками.
Публичные ссылки