Files
RDP-login-monitor/DEPLOY.md
T

116 lines
11 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# Развёртывание RDP Login Monitor в домене
Монитор ставится в **`C:\ProgramData\RDP-login-monitor\`**, задачи планировщика создаёт сам **`Login_Monitor.ps1`** (параметр `-InstallTasks`). Доставку по сети выполняет **`Deploy-LoginMonitor.ps1`**.
## Файлы на файловой шаре
Создайте каталог, доступный **конечным компьютерам** на чтение (часто учётная запись компьютера домена), например:
`\\dc.contoso.local\NETLOGON\RDP-login-monitor\`
Внутри должны лежать **три файла** (имена фиксированы):
| Файл | Назначение |
|------|------------|
| `Login_Monitor.ps1` | Основной скрипт (токен/chat id plain или DPAPI в параметрах). |
| `version.txt` | **Одна строка** — номер версии пакета на шаре (см. раздел «Версии» ниже). |
| `Deploy-LoginMonitor.ps1` | Установщик: сравнивает версию, копирует монитор, вызывает `-InstallTasks`, при необходимости запускает процесс монитора. |
При выпуске новой сборки обновляйте на шаре **`Login_Monitor.ps1`** и при необходимости **`version.txt`** (логика описана в разделе «Версии»).
## Как это работает
1. **`Deploy-LoginMonitor.ps1`** определяет корень дистрибутива:
- параметр **`-SourceShareRoot`** `\\server\share\RDP-login-monitor`, **или**
- если скрипт запущен по UNC, берётся **родительская папка** этого файла (удобно вызывать шару без параметров).
2. Читается **`version.txt`** на шаре и сравнивается с локальной меткой **`C:\ProgramData\RDP-login-monitor\deployed_version.txt`**. Если метки ещё нет — для сравнения подтягивается **`$ScriptVersion`** из уже установленного **`Login_Monitor.ps1`**.
3. Если версия на шаре **совпадает** с зафиксированной локально — выход без копирования (быстро, можно при каждой загрузке).
4. Если версия на шаре **новее** — останавливаются процессы монитора с каноническим путём → копируется **`Login_Monitor.ps1`** → выполняется **`Login_Monitor.ps1 -InstallTasks`** → записывается **`deployed_version.txt`** → запускается монитор (если не указан **`-SkipStartMonitorAfterUpdate`**).
5. Если версия на шаре **старее** локальной — обновление **не выполняется** (защита от отката), пока не указан **`-AllowDowngrade`**.
Лог установки: **`C:\ProgramData\RDP-login-monitor\Logs\deploy.log`**.
## Задачи планировщика после `-InstallTasks`
Параметр **`Login_Monitor.ps1 -InstallTasks`** создаёт две задачи:
| Имя | Назначение |
|-----|------------|
| **`RDP-Login-Monitor`** | Запуск основного монитора при старте ОС (`Register-ScheduledTask`, триггер «При запуске компьютера»). |
| **`RDP-Login-Monitor-Watchdog`** | Тот же файл **`Login_Monitor.ps1`** с аргументом **`-Watchdog`**: короткая проверка «жив ли монитор», при необходимости поднимает процесс. |
Watchdog регистрируется через **`schtasks.exe /Create /SC MINUTE /MO 5`** (а не через CIM-триггеры PowerShell): на части ОС у объектов триггера нет настраиваемых **`RepetitionInterval`** / длительность «раз и навсегда» режется планировщиком — из‑за этого раньше вторая задача могла не создаваться.
Перед созданием выполняется **`schtasks /Delete … /F`** (если задачи ещё не было, сообщение об ошибке подавляется — это нормально).
Сразу после успешного **`/Create`** вызывается **`schtasks /Run`** для watchdog: первый прогон не ждёт следующего 5‑минутного окна расписания.
Если watchdog срабатывает, а основной монитор «не поднимается», смотрите **`Logs\watchdog.log`** (сообщение о PID и предупреждение, если процесс сразу завершился) и **конец `Logs\login_monitor.log`** — частая причина (исправлено в **1.3.5+**): пустой **`$PSCommandPath`** у процесса, запущенного через **`Start-Process`**; скрипт теперь подставляет путь через **`$PSScriptRoot`**.
Проверка:
```powershell
Get-ScheduledTask -TaskName 'RDP-Login-Monitor','RDP-Login-Monitor-Watchdog' -ErrorAction SilentlyContinue
schtasks /Query /TN "RDP-Login-Monitor-Watchdog"
```
Логи: **`...\Logs\login_monitor.log`**, **`...\Logs\watchdog.log`**.
## Запуск Deploy и политики с файловой шары
Если при запуске **`Deploy-LoginMonitor.ps1`** или **`Login_Monitor.ps1`** с UNC по **FQDN** (`\\dc.domain.local\...`) PowerShell сообщает про **цифровую подпись** / политику выполнения, чаще всего помогает путь по **короткому имени** контроллера: **`\\DC01\NETLOGON\...`** (клиент относит UNC к интрасети иначе). Параллельно убедитесь, что команда реально с **`powershell.exe -ExecutionPolicy Bypass -File "..."`**.
## Версии: `version.txt` и `$ScriptVersion`
| Что | Роль |
|-----|------|
| **`version.txt` на шаре** | Единственный источник для **`Deploy-LoginMonitor.ps1`**: решение «класть ли новый файл на компьютер». Поднимайте номер **всякий раз**, когда нужно, чтобы доменные машины забрали **новую копию** скрипта с шары — в том числе при мелких правках **без** изменения «видимой» версии в логах. |
| **`$ScriptVersion` в `Login_Monitor.ps1`** | Версия для **логов и Telegram** (что видит администратор). Меняйте при **значимых** релизах; для полной ясности можно держать ту же строку, что и в **`version.txt`**. |
**Типичные сценарии:**
- Крупный релиз: обновили **`Login_Monitor.ps1`**, подняли **`$ScriptVersion`** (например `1.4.0`) и записали то же в **`version.txt`** на шаре.
- Мелкая правка на шаре (опечатка, узкий фикс), не хотите путать отчёты по версии в логах: поднимите только **`version.txt`** (например с `1.3.0` на **`1.3.0.1`** — поддерживаются четырёхкомпонентные номера .NET **Version**). **`$ScriptVersion`** можно не трогать; на клиентах после деплоя в логах по-прежнему будет старая «человеческая» версия, но файл будет актуальным.
- Идеально поддерживать синхронность **`version.txt`** и **`$ScriptVersion`**, когда правки крупные и версия в логах должна совпадать с дистрибутивом.
Итого: **обновляться «по сети» обязан именно `version.txt`**; строка **`$ScriptVersion`** нужна для прозрачности в мониторинге и может совпадать с шарой или отставать по «маркетингу», если вы сознательно крутите только patch в **`version.txt`**.
## Групповая политика (GPO)
1. Положите три файла на шару (см. выше).
2. **Конфигурация компьютера****Политики****Windows****Сценарии (запуск/завершение)****Автозагрузка**.
3. Добавьте сценарий PowerShell с **путём к установщику на шаре**, например:
`\\contoso.local\NETLOGON\RDP-login-monitor\Deploy-LoginMonitor.ps1`
Параметры можно оставить пустыми, если рядом на шаре лежат **`Login_Monitor.ps1`** и **`version.txt`**.
Скрипт выполняется от **SYSTEM** при старте ОС — этого достаточно для записи в **`ProgramData`** и регистрации задач.
Альтернатива: команда
```text
powershell.exe -NoProfile -ExecutionPolicy Bypass -File "\\...\Deploy-LoginMonitor.ps1"
```
в сценарии **cmd** / отдельном **bat**.
## Ручная проверка
```powershell
powershell.exe -NoProfile -ExecutionPolicy Bypass -File "\\...\Deploy-LoginMonitor.ps1"
```
- **`-WhatIf`** — только сообщение в лог, без копирования.
- **`-SkipStartMonitorAfterUpdate`** — после обновления не запускать процесс монитора (остаются задачи планировщика и следующая загрузка / watchdog).
## Безопасность и замечания
- ACL на шару: чтение только нужным **компьютерам** / группам; файл **`Login_Monitor.ps1`** может содержать токен — ограничивайте доступ.
- DPAPI-секреты привязаны к машине: шифровать на каждой цели или использовать plain на закрытой шаре (см. комментарии в **`Login_Monitor.ps1`**).
- Deploy при ошибках пишет в **`deploy.log`** и завершается с кодом **0**, чтобы не блокировать загрузку ОС; проблемы смотрите по логу на ПК.