вторник, 28 июля 2026 г.

Powershell, Policy, Bypass, Process, Process Bypass

Powershell, Policy, Bypass, Process, Process Bypass

260728_Alica_Notepad++_VSCode_Powershell_Word_Wordpad_Pdf_RTF_Markdown_.docx

А обычный способ заключается запуском этого скрипта PS C:\Users\Administrator> Set-ExecutionPolicy -Scope Process -ExecutionPolicy Bypass PS C:\Users\Administrator> Get-ExecutionPolicy Bypass PS C:\Users\Administrator> Get-ExecutionPolicy -List Scope ExecutionPolicy ----- --------------- MachinePolicy Undefined UserPolicy Undefined Process Bypass CurrentUser Undefined LocalMachine RemoteSigned PS C:\Users\Administrator> $PSExecutionPolicyPreference PS C:\Users\Administrator> ?
  • Алиса

    Да, это и есть обычный, самый правильный и безопасный способ для разовых задач — именно так и делают в CI/CD и при локальной отладке.

    Ты делаешь ровно то, что нужно:

    1. Меняешь политику только для текущего процесса (Scope Process) — она живёт, пока открыт этот терминал.
    2. Не трогаешь систему, не требуешь прав админа, не ломаешь настройки на машине.
    3. Как только терминал закроется — всё вернётся к LocalMachine: RemoteSigned.

    Почему $PSExecutionPolicyPreference пустой — ещё раз, чтобы закрыть этот вопрос

    Это не баг и не ошибка. Эта переменная — особенность Windows PowerShell 5.1. В PowerShell 7+ (у тебя 7.6.4) её просто нет: политика для Process хранится внутри рантайма, а не в отдельной переменной. Так что пустое значение — это ожидаемое поведение для твоей версии.


    Как это выглядит в реальных сценариях под твой C#‑проект

    Сценарий 1: Локальный запуск скрипта деплоя/остановки

    Ты в VS Code в терминале pwsh, делаешь:

    powershell
    Set-ExecutionPolicy -Scope Process -ExecutionPolicy Bypass
    .\deploy.ps1
    

    Скрипт останавливает твой BackgroundService, копирует новую сборку, запускает заново, проверяет health‑check. Всё работает, терминал закрыл — никаких следов.

    Сценарий 2: Azure DevOps / GitHub Actions (в пайплайне)

    В YAML‑шаге почти всегда пишут именно так:

    yaml
    - powershell: |
        Set-ExecutionPolicy -Scope Process -ExecutionPolicy Bypass
        .\build.ps1
      displayName: 'Build with PowerShell'
    

    Это стандарт индустрии: не менять настройки агента, а включать Bypass только на время шага.

    Сценарий 3: Быстрый тест логики с TPL Dataflow

    Допустим, ты хочешь проверить, как сервис реагирует на остановку. Пишешь маленький скрипт test-stop.ps1, который:

    • Запускает сервис.
    • Ждёт N секунд.
    • Останавливает процесс.
    • Проверяет, что все блоки TPL Dataflow завершили обработку.

    И запускаешь его в терминале с Bypass — быстро, изолированно, без лишних настроек.


    Важные правила безопасности (чтобы не привыкать к «всё разрешено»)

    • Никогда не ставь Bypass на LocalMachine. Это снимет защиту со всей системы. Scope Process — это золотая середина.
    • Не делай это в скриптах, которые лежат в репозитории и запускаются у других людей. Пусть каждый сам решает, запускать ли Bypass. Лучше явно писать в README: «Для запуска скриптов нужен Bypass в текущем процессе».
    • Для продакшн‑серверов часто вообще не используют скрипты, а ставят сервисы через MSI/MSIX или через готовые задачи CI/CD, где политика уже настроена администратором.

    Лайфхак: как не печатать эту команду каждый раз в VS Code

    Если ты часто запускаешь свои скрипты в VS Code и надоело каждый раз вводить Set-ExecutionPolicy, можно сделать один из двух вариантов:

    Вариант А: Task в VS Code (рекомендуется)
    В папке проекта создай .vscode/tasks.json:

    json
    {
      "version": "2.0.0",
      "tasks": [
        {
          "label": "Run Deploy Script",
          "type": "shell",
          "command": "pwsh",
          "args": [
            "-NoProfile",
            "-ExecutionPolicy", "Bypass",
            "-File", "${workspaceFolder}\\deploy.ps1"
          ],
          "problemMatcher": []
        }
      ]
    }
    

    Теперь в VS Code нажимаешь Ctrl+Shift+P → «Tasks: Run Task» → «Run Deploy Script», и всё запускается сразу с Bypass. Никаких ручных команд.

    Вариант Б: Профиль PowerShell (если только для себя)
    Создай (или отредактируй) профиль:

    powershell
    $profile
    

    И добавь туда:

    powershell
    if ($env:VSCODE_INSIDER -eq "true" -or $env:TERM_PROGRAM -eq "vscode") {
        Set-ExecutionPolicy -Scope Process -ExecutionPolicy Bypass -Force
    }
    

    Но этот вариант менее предсказуемый: он срабатывает при каждом запуске PowerShell в VS Code, и другие люди, открыв твой проект, могут не понять, откуда берётся Bypass. Поэтому для командных проектов лучше Вариант А.


    Учитывая, что ты делаешь асинхронный сервис с двухтактной остановкой, такой подход с временным Bypass идеален: ты можешь быстро гонять скрипты проверки остановки, не рискуя безопасностью системы и не усложняя инфраструктуру.

    Если скажешь, какой именно скрипт ты планируешь запускать (деплой, тест остановки, проверка логов), я помогу оформить его и задачу в VS Code под этот сценарий. 😊

  • Я

    А если ответ вот такой, то скрипты будут работать Scope ExecutionPolicy ----- --------------- MachinePolicy Undefined UserPolicy Undefined Process Bypass CurrentUser Undefined LocalMachine RemoteSigned ----------------------- Тут почти все Undefined ?
  • Алиса

    Да, скрипты будут работать — и именно потому, что в колонке Process стоит Bypass.

    Почему «почти все Undefined» — это нормально

    PowerShell применяет политику по приоритету (от самого локального к самому глобальному). Порядок такой:

    1. MachinePolicy (через GPO домена)
    2. UserPolicy (тоже через GPO)
    3. Process (то, что ты задал вручную в этом сеансе)
    4. CurrentUser
    5. LocalMachine

    Если на каком‑то уровне значение Undefined, PowerShell просто «пропускает» этот уровень и смотрит дальше. В твоём случае цепочка выглядит так:

    • MachinePolicy: Undefined → пропускаем
    • UserPolicy: Undefined → пропускаем
    • Process: Bypass → стоп, это самое локальное действующее значение. Его и применяем.

    Поэтому всё остальное (включая LocalMachine: RemoteSigned) уже не важно: Process перебивает их все.


    Что это значит для твоего сценария (C#, BackgroundService, CI/CD)

    • Скрипты запускаются без ошибок. Это именно тот результат, который нужен для разовых задач: быстро, безопасно, без изменений в системе.
    • Никакой «грязи» не остаётся. Как только терминал закроется, Process исчезнет, и останется только LocalMachine: RemoteSigned — стандартная безопасная настройка.
    • Идеально для CI/CD. В пайплайнах Azure DevOps/GitHub Actions делают ровно так: на время шага ставят Bypass в Process, прогоняют скрипты, а дальше агент живёт дальше со своими настройками.

    Частый вопрос: а если бы Process был Undefined?

    Тогда PowerShell взял бы следующее значение по списку. В твоём примере это был бы LocalMachine: RemoteSigned. И тогда .ps1‑скрипты запускались бы только если они подписаны или скачаны из «доверенной» зоны (RemoteSigned).

    Но у тебя Process: Bypass, поэтому RemoteSigned даже не участвует в решении.


    Практический совет под твой стек

    Учитывая, что ты делаешь асинхронный сервис с двухтактной остановкой и часто гоняешь локальные скрипты проверки, держи в голове эту простую формулу:

    Если в строке Process видишь Bypass — в этом окне всё будет работать.

    Для проверки можешь прямо сейчас сделать:

    powershell
    .\test.ps1
    

    (если файл есть) или:

    powershell
    Get-ExecutionPolicy
    

    И убедиться, что вывод — Bypass. Этого достаточно, чтобы спокойно запускать любые скрипты для тестов, деплоя, проверки логов и т. п.

    Если хочешь, могу показать, как оформить такой запуск в виде одной кнопки в VS Code (через tasks.json или через кнопку «Run» для конкретного скрипта), чтобы вообще не думать про политики — они будут применяться автоматически и только на время запуска. 😊

  • Я

    А может быть тогда все опции включить и не будет Undefined MachinePolicy Undefined UserPolicy Undefined Process Bypass CurrentUser Undefined LocalMachine RemoteSigned ------- НАдо ли стремиться к тому, чтобы все опции были определены, то есть не было Undefined ?
  • Алиса

    Нет, не надо. И стремиться к тому, чтобы везде были прописаны значения вместо Undefined, не нужно — это вообще не признак «правильной» настройки.

    Undefined — это не «ошибка» и не «дыра», а нормальное состояние: оно означает «здесь нет своей политики, смотри дальше по цепочке». PowerShell так и задумывался: он идёт сверху вниз и берёт первое найденное значение.


    Как на самом деле работает эта цепочка

    Представь это как систему исключений:

    1. MachinePolicy — политика домена (если компьютер в Active Directory). Если тут Undefined — значит, домен ничего не диктует.
    2. UserPolicy — тоже из групповых политик, но на уровне пользователя. Если Undefined — пользовательских правил нет.
    3. Process — то, что ты задал прямо сейчас в этом окне. Это самое «сильное» правило для текущего сеанса. У тебя тут Bypass — и этого достаточно.
    4. CurrentUser — настройка конкретно для этого пользователя (ставится через PowerShell без прав админа).
    5. LocalMachine — общая настройка для всей машины (нужны права админа). У тебя тут RemoteSigned — это стандартный безопасный вариант.

    Если на каком‑то уровне стоит Undefined, PowerShell просто пропускает этот уровень. В твоём случае он сразу берёт Process: Bypass и дальше не идёт.


    Почему не нужно «заполнять» все уровни

    • Это не даёт никаких преимуществ. Если ты принудительно задашь, например, CurrentUser: RemoteSigned, это никак не повлияет на работу скриптов, потому что Process: Bypass всё равно будет приоритетнее.
    • Можно случайно сделать хуже. Если поставить политику на уровне LocalMachine или CurrentUser, она сохранится после закрытия терминала и будет действовать всегда. Это уже не «временная настройка для теста», а постоянное изменение системы.
    • Лишние права. Чтобы задать LocalMachine, нужны права администратора. Для разовых скриптов и CI/CD это избыточно.
    • Путаница в команде. Если в проекте все начнут ставить свои политики на разных уровнях, у разных разработчиков будут разные правила, и поведение скриптов станет непредсказуемым.

    Что это значит для твоего C#‑проекта и скриптов

    Твоя текущая картина — идеальна для локальной разработки и CI/CD:

    text
    Process          Bypass      ← работает сейчас, только в этом окне
    LocalMachine     RemoteSigned ← безопасная база, если Process не задан
    Все остальные    Undefined    ← значит, нет лишних правил
    

    Это как надеть одноразовую перчатку, чтобы быстро что‑то сделать, а потом снять. Ты не меняешь «базовую одежду» системы.


    Когда вообще имеет смысл ставить политики на других уровнях

    • LocalMachine: RemoteSigned — часто стоит по умолчанию в Windows. Его оставляют как «страховку», если вдруг кто‑то запустит PowerShell без временных настроек.
    • CurrentUser — если ты хочешь, чтобы у твоего пользователя по умолчанию были чуть более мягкие правила (но всё равно не Bypass!), и ты готов, что они будут действовать всегда.
    • MachinePolicy / UserPolicy — только если ты администратор домена и настраиваешь правила для всей компании.

    Для твоих задач (тесты BackgroundService, двухтактная остановка, локальные скрипты, пайплайны) ничего дополнительно настраивать не нужно.


    Практический совет под твой стек

    Держи в голове простое правило:

    Для тестов, деплоя и CI/CD достаточно, чтобы в строке Process было Bypass. Всё остальное может спокойно оставаться Undefined.

    Если хочешь, могу показать, как оформить запуск твоего скрипта проверки остановки сервиса так, чтобы Set-ExecutionPolicy вообще не приходилось вводить вручную — через задачу VS Code или через параметры запуска pwsh, чтобы это было удобно и безопасно. Что ближе? 😊