fix(windows): make collector fallback rust-primary
This commit is contained in:
@@ -0,0 +1,507 @@
|
||||
#!/usr/bin/env bash
|
||||
# aw-contour-diag.sh - Диагностика всего контура ActivityWatch-Russian
|
||||
# Запускать с машины администратора (где есть доступ по SSH/curl ко всем узлам).
|
||||
#
|
||||
# Использование:
|
||||
# ./scripts/aw-contour-diag.sh # полная диагностика
|
||||
# ./scripts/aw-contour-diag.sh --quick # быстрая (только AW server + buckets)
|
||||
# ./scripts/aw-contour-diag.sh --skip-windows # без RDP/WinRM проверок
|
||||
#
|
||||
# При красных проверках в скрипте указаны разделы 'REMEDIATION: ...'
|
||||
# с конкретными командами для восстановления.
|
||||
|
||||
set -uo pipefail
|
||||
|
||||
REPO_ROOT="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)"
|
||||
ANSIBLE_DIR="$REPO_ROOT/ansible"
|
||||
INVENTORY="$ANSIBLE_DIR/inventory.ini"
|
||||
AW_SERVER="http://10.10.10.13:5600"
|
||||
AW_WORKTIME_API="http://10.10.10.13:5610"
|
||||
INFLUXDB_URL="http://10.10.10.10:8086"
|
||||
GRAFANA_URL="http://10.10.10.11:3000"
|
||||
PROXMOX_HOST="10.10.10.2"
|
||||
AW_HOST="10.10.10.13"
|
||||
GRAFANA_HOST="10.10.10.11"
|
||||
INFLUXDB_HOST="10.10.10.10"
|
||||
WINDOWS_HOST="192.168.100.18"
|
||||
CLICKHOUSE_HOST="10.10.10.2"
|
||||
SOURCE_HOSTNAME="SHARKON2025"
|
||||
|
||||
QUICK_MODE=0
|
||||
SKIP_WINDOWS=0
|
||||
|
||||
while [[ $# -gt 0 ]]; do
|
||||
case "$1" in
|
||||
--quick) QUICK_MODE=1; shift ;;
|
||||
--skip-windows) SKIP_WINDOWS=1; shift ;;
|
||||
-h|--help)
|
||||
echo "Usage: $(basename "$0") [--quick] [--skip-windows]"
|
||||
exit 0 ;;
|
||||
*) echo "Unknown: $1"; exit 2 ;;
|
||||
esac
|
||||
done
|
||||
|
||||
export no_proxy="localhost,127.0.0.1,$PROXMOX_HOST,$AW_HOST,$GRAFANA_HOST,$INFLUXDB_HOST,$WINDOWS_HOST,$CLICKHOUSE_HOST,10.10.10.0/24,192.168.100.0/24"
|
||||
export NO_PROXY="$no_proxy"
|
||||
|
||||
OK_COUNT=0; WARN_COUNT=0; FAIL_COUNT=0; SKIP_COUNT=0
|
||||
|
||||
if [ -t 1 ]; then
|
||||
RED='\033[0;31m'; GREEN='\033[0;32m'; YELLOW='\033[1;33m'; CYAN='\033[0;36m'; NC='\033[0m'
|
||||
else
|
||||
RED=''; GREEN=''; YELLOW=''; CYAN=''; NC=''
|
||||
fi
|
||||
|
||||
pass() { OK_COUNT=$((OK_COUNT+1)); printf "%b[OK]%b %s\n" "$GREEN" "$NC" "$*"; }
|
||||
warn() { WARN_COUNT=$((WARN_COUNT+1)); printf "%b[WARN]%b %s\n" "$YELLOW" "$NC" "$*"; }
|
||||
fail() { FAIL_COUNT=$((FAIL_COUNT+1)); printf "%b[FAIL]%b %s\n" "$RED" "$NC" "$*"; }
|
||||
skip() { SKIP_COUNT=$((SKIP_COUNT+1)); printf "%b[SKIP]%b %s\n" "$YELLOW" "$NC" "$*"; }
|
||||
section() { printf "\n%b=== %s ===%b\n" "$CYAN" "$*" "$NC"; }
|
||||
have() { command -v "$1" >/dev/null 2>&1; }
|
||||
|
||||
check_tcp() {
|
||||
local name="$1" host="$2" port="$3"
|
||||
if timeout 4 bash -c ":</dev/tcp/${host}/${port}" >/dev/null 2>&1; then
|
||||
pass "TCP $host:$port ($name)"
|
||||
else
|
||||
fail "TCP $host:$port ($name)"
|
||||
echo " REMEDIATION: Проверьте, запущен ли сервис на $host:$port."
|
||||
echo " Для systemd: ssh igor@$host 'systemctl status <unit>'"
|
||||
echo " Для Docker: ssh igor@$PROXMOX_HOST 'sudo docker ps | grep <container>'"
|
||||
fi
|
||||
}
|
||||
|
||||
check_http_code() {
|
||||
local name="$1" url="$2" expected="${3:-^2[0-9][0-9]$}"
|
||||
local tmp code
|
||||
tmp="$(mktemp)"
|
||||
code="$(curl -k -sS --connect-timeout 5 --max-time 15 -o "$tmp" -w '%{http_code}' "$url" 2>"$tmp.err")"
|
||||
if printf "%s" "$code" | grep -Eq "$expected"; then
|
||||
pass "HTTP $code $url ($name)"
|
||||
else
|
||||
fail "HTTP $code $url ($name)"
|
||||
sed 's/^/ /' "$tmp.err" "$tmp" 2>/dev/null | head -20
|
||||
fi
|
||||
rm -f "$tmp" "$tmp.err"
|
||||
}
|
||||
|
||||
check_http_json_key() {
|
||||
local name="$1" url="$2" jq_filter="$3" remediation="$4"
|
||||
local tmp
|
||||
tmp="$(mktemp)"
|
||||
if curl -k -fsS --connect-timeout 5 --max-time 20 "$url" -o "$tmp" 2>"$tmp.err" && jq -e "$jq_filter" "$tmp" >/dev/null 2>&1; then
|
||||
pass "$name"
|
||||
else
|
||||
fail "$name"
|
||||
sed 's/^/ /' "$tmp.err" "$tmp" 2>/dev/null | head -10
|
||||
echo " REMEDIATION: $remediation"
|
||||
fi
|
||||
rm -f "$tmp" "$tmp.err"
|
||||
}
|
||||
|
||||
check_bucket_freshness() {
|
||||
local bucket="$1" label="$2" remediation="$3"
|
||||
local bucket_id="${bucket}_${SOURCE_HOSTNAME}"
|
||||
local tmp last_ts event_epoch now age_sec
|
||||
tmp="$(mktemp)"
|
||||
if ! curl -fsS --connect-timeout 5 --max-time 15 "$AW_SERVER/api/0/buckets/$bucket_id/events?limit=1" -o "$tmp" 2>"$tmp.err"; then
|
||||
fail "bucket $label ($bucket_id) — запрос не удался"
|
||||
sed 's/^/ /' "$tmp.err" | head -5
|
||||
echo " REMEDIATION: $remediation"
|
||||
rm -f "$tmp" "$tmp.err"
|
||||
return
|
||||
fi
|
||||
last_ts="$(jq -r '.[0].timestamp // empty' "$tmp" 2>/dev/null)"
|
||||
rm -f "$tmp"
|
||||
if [ -z "$last_ts" ]; then
|
||||
warn "bucket $label ($bucket_id) — нет событий"
|
||||
echo " REMEDIATION: $remediation"
|
||||
return
|
||||
fi
|
||||
event_epoch="$(date -d "$last_ts" +%s 2>/dev/null || echo 0)"
|
||||
now="$(date -u +%s)"
|
||||
age_sec=$((now - event_epoch))
|
||||
|
||||
case "$bucket" in
|
||||
aw-dlp-incidents|aw-dlp-review|aw-dlp-rules|aw-session-events)
|
||||
if [ "$age_sec" -lt 86400 ]; then
|
||||
pass "bucket $label — ${age_sec}s назад"
|
||||
else
|
||||
warn "bucket $label — ${age_sec}s назад (event-driven)"
|
||||
fi ;;
|
||||
aw-watcher-window|aw-dlp-endpoint-signals)
|
||||
if [ "$age_sec" -lt 7200 ]; then
|
||||
pass "bucket $label — ${age_sec}s назад"
|
||||
else
|
||||
warn "bucket $label — ${age_sec}s назад (INACTIVE)"
|
||||
fi ;;
|
||||
*)
|
||||
if [ "$age_sec" -lt 3600 ]; then
|
||||
pass "bucket $label — ${age_sec}s назад"
|
||||
elif [ "$age_sec" -lt 86400 ]; then
|
||||
warn "bucket $label — ${age_sec}s назад (STALE)"
|
||||
echo " REMEDIATION: $remediation"
|
||||
else
|
||||
fail "bucket $label — ${age_sec}s назад (DEAD)"
|
||||
echo " REMEDIATION: $remediation"
|
||||
fi ;;
|
||||
esac
|
||||
}
|
||||
|
||||
check_ansible_shell() {
|
||||
local name="$1" group="$2" command="$3"
|
||||
if ! have ansible; then
|
||||
skip "$name (ansible not available)"
|
||||
return
|
||||
fi
|
||||
if [ ! -f "$INVENTORY" ]; then
|
||||
skip "$name (inventory not found: $INVENTORY)"
|
||||
return
|
||||
fi
|
||||
local tmp
|
||||
tmp="$(mktemp)"
|
||||
if ANSIBLE_NOCOLOR=1 ansible "$group" -i "$INVENTORY" -m shell -a "$command" >"$tmp" 2>&1; then
|
||||
pass "$name"
|
||||
else
|
||||
fail "$name"
|
||||
sed 's/^/ /' "$tmp" | head -20
|
||||
fi
|
||||
rm -f "$tmp"
|
||||
}
|
||||
|
||||
check_ansible_win_shell() {
|
||||
local name="$1" command="$2"
|
||||
if ! have ansible; then skip "$name (ansible not available)"; return; fi
|
||||
if [ ! -f "$INVENTORY" ]; then skip "$name (inventory not found)"; return; fi
|
||||
local tmp
|
||||
tmp="$(mktemp)"
|
||||
if ANSIBLE_NOCOLOR=1 ansible aw_windows -i "$INVENTORY" -m win_shell -a "$command" >"$tmp" 2>&1; then
|
||||
pass "$name"
|
||||
else
|
||||
fail "$name"
|
||||
sed 's/^/ /' "$tmp" | head -20
|
||||
fi
|
||||
rm -f "$tmp"
|
||||
}
|
||||
|
||||
check_ansible_module() {
|
||||
local name="$1" group="$2" module="$3" args="${4:-}"
|
||||
if ! have ansible; then skip "$name (ansible not available)"; return; fi
|
||||
if [ ! -f "$INVENTORY" ]; then skip "$name (inventory not found)"; return; fi
|
||||
local tmp
|
||||
tmp="$(mktemp)"
|
||||
if ANSIBLE_NOCOLOR=1 ansible "$group" -i "$INVENTORY" -m "$module" ${args:+-a "$args"} >"$tmp" 2>&1; then
|
||||
pass "$name"
|
||||
else
|
||||
fail "$name"
|
||||
sed 's/^/ /' "$tmp" | head -20
|
||||
fi
|
||||
rm -f "$tmp"
|
||||
}
|
||||
|
||||
ssh_with_diag_password() {
|
||||
local host="$1"
|
||||
shift
|
||||
if [[ -z "${AW_DIAG_SSH_PASSWORD:-}" ]]; then
|
||||
return 125
|
||||
fi
|
||||
sshpass -p "$AW_DIAG_SSH_PASSWORD" ssh -o ConnectTimeout=10 -o StrictHostKeyChecking=no "igor@$host" "$@"
|
||||
}
|
||||
|
||||
ssh_aw() { ssh_with_diag_password 10.10.10.13 "$@"; }
|
||||
ssh_pve() { ssh_with_diag_password 10.10.10.2 "$@"; }
|
||||
|
||||
check_service_remote() {
|
||||
local name="$1" host="$2" unit="$3" remediation="$4"
|
||||
local result
|
||||
result=$(ssh_with_diag_password "$host" "systemctl is-active $unit 2>/dev/null || echo not_found" 2>/dev/null)
|
||||
local rc=$?
|
||||
if [ "$rc" -eq 125 ]; then
|
||||
skip "$name ($unit on $host — set AW_DIAG_SSH_PASSWORD for SSH checks)"
|
||||
return
|
||||
fi
|
||||
if [ "$rc" -ne 0 ] || [ "$result" = "not_found" ]; then
|
||||
skip "$name ($unit on $host — не удалось проверить)"
|
||||
return
|
||||
fi
|
||||
if [ "$result" = "active" ]; then
|
||||
pass "$name ($unit active on $host)"
|
||||
else
|
||||
fail "$name ($unit $result on $host)"
|
||||
echo " REMEDIATION: $remediation"
|
||||
fi
|
||||
}
|
||||
|
||||
printf "%b=== ActivityWatch-Russian: Диагностика контура ===%b\n" "$CYAN" "$NC"
|
||||
echo " $(date -u '+%Y-%m-%d %H:%M:%S UTC')"
|
||||
echo ""
|
||||
|
||||
# ============================================================
|
||||
section "1. Локальные предусловия"
|
||||
# ============================================================
|
||||
for cmd in bash curl jq timeout ssh sshpass; do
|
||||
if have "$cmd"; then pass "утилита $cmd найдена"; else fail "утилита $cmd не найдена (установите: apt install $cmd)"; fi
|
||||
done
|
||||
echo ""
|
||||
|
||||
# ============================================================
|
||||
section "2. TCP доступность узлов"
|
||||
# ============================================================
|
||||
check_tcp "AW Server" "$AW_HOST" 5600
|
||||
check_tcp "Worktime API" "$AW_HOST" 5610
|
||||
check_tcp "RDP WinRM" "$WINDOWS_HOST" 5985
|
||||
check_tcp "Proxmox SSH" "$PROXMOX_HOST" 22
|
||||
check_tcp "Proxmox HTTPS" "$PROXMOX_HOST" 443
|
||||
check_tcp "1C Company API" "$PROXMOX_HOST" 8710
|
||||
check_tcp "ClickHouse HTTP" "$CLICKHOUSE_HOST" 8123
|
||||
check_tcp "ClickHouse Native" "$CLICKHOUSE_HOST" 9000
|
||||
check_tcp "InfluxDB" "$INFLUXDB_HOST" 8086
|
||||
check_tcp "Grafana" "$GRAFANA_HOST" 3000
|
||||
|
||||
if [ "$QUICK_MODE" = "1" ]; then
|
||||
# В быстром режиме проверяем только AW Server и buckets
|
||||
echo ""
|
||||
section "3. AW Server (быстрый режим)"
|
||||
check_http_code "AW Server info" "$AW_SERVER/api/0/info" '^200$'
|
||||
check_http_code "AW Server CORS" "$AW_SERVER/api/0/settings/" '^200$'
|
||||
check_http_code "Worktime API health" "$AW_WORKTIME_API/health" '^200$'
|
||||
|
||||
section "4. Buckets (быстрый режим)"
|
||||
for entry in \
|
||||
"aw-watcher-afk|AFK watcher|Запустите на RDP: schtasks /Run /TN \"ActivityWatch Recovery\" или schtasks /Run /TN \"ActivityWatch Launch [SHARKON2025_Администратор]\"" \
|
||||
"aw-watcher-window|Window watcher|Запустите через ansible: ansible aw_windows -i $INVENTORY -m win_shell -a 'Start-Process -FilePath \"C:\\Program Files\\AWatch-rus\\bin\\aw-watcher-window\\aw-watcher-window.exe\" -ArgumentList @(\"--host\", \"10.10.10.13\", \"--port\", \"5600\") -WindowStyle Hidden'" \
|
||||
"aw-worktime-sessions|Worktime sessions|Проверьте работу worktime-api: systemctl status aw-worktime-api на AW сервере" \
|
||||
"aw-session-events|Session events|Проверьте collector-guard и aw-session-events-collector на RDP" \
|
||||
"aw-dlp-endpoint-signals|DLP signals|Запустите: ansible aw_windows -i $INVENTORY -m win_shell -a 'schtasks /Run /TN \"ActivityWatch Launch [SHARKON2025_Администратор]\"; Start-Sleep 30'" \
|
||||
"aw-dlp-incidents|DLP incidents|Проверьте aw-detmir-dlp-collector.ps1 на RDP (логи: C:\\ProgramData\\AWatch-rus\\logs\\)" \
|
||||
; do
|
||||
bucket="${entry%%|*}"; rest="${entry#*|}"
|
||||
label="${rest%%|*}"; remediation="${rest#*|}"
|
||||
check_bucket_freshness "$bucket" "$label" "$remediation"
|
||||
done
|
||||
echo ""
|
||||
echo "=== Быстрая диагностика завершена ==="
|
||||
printf "OK=%s WARN=%s FAIL=%s SKIP=%s\n" "$OK_COUNT" "$WARN_COUNT" "$FAIL_COUNT" "$SKIP_COUNT"
|
||||
[ "$FAIL_COUNT" -gt 0 ] && exit 2 || exit 0
|
||||
fi
|
||||
|
||||
# ============================================================
|
||||
section "3. AW Server (10.10.10.13)"
|
||||
# ============================================================
|
||||
check_http_json_key "AW Server info" "$AW_SERVER/api/0/info" \
|
||||
'.version' \
|
||||
"Проверьте: ssh igor@$AW_HOST 'systemctl status activitywatch-server'"
|
||||
check_http_code "AW Server CORS" "$AW_SERVER/api/0/settings/" '^200$'
|
||||
check_http_code "AW WebUI" "$AW_SERVER/" '^200$'
|
||||
check_http_json_key "Worktime API health" "$AW_WORKTIME_API/health" \
|
||||
'.status // .ok' \
|
||||
"Проверьте: ssh igor@$AW_HOST 'systemctl status aw-worktime-api && journalctl -u aw-worktime-api -n 20'"
|
||||
|
||||
# ============================================================
|
||||
section "4. Buckets (свежесть данных)"
|
||||
# ============================================================
|
||||
for entry in \
|
||||
"aw-watcher-afk|AFK watcher|Запустите на RDP: ansible aw_windows -i $INVENTORY -m win_shell -a 'schtasks /Run /TN \"ActivityWatch Recovery\"'" \
|
||||
"aw-watcher-window|Window watcher|Запустите: ansible aw_windows -i $INVENTORY -m win_shell -a 'schtasks /Run /TN \"ActivityWatch Launch [SHARKON2025_Администратор]\"; Start-Process -FilePath \"C:\\Program Files\\AWatch-rus\\bin\\aw-watcher-window\\aw-watcher-window.exe\" -ArgumentList @(\"--host\", \"10.10.10.13\", \"--port\", \"5600\") -WindowStyle Hidden'" \
|
||||
"aw-worktime-sessions|Worktime sessions|Проверьте: ssh igor@$AW_HOST 'systemctl status aw-worktime-api && journalctl -u aw-worktime-api -n 20'" \
|
||||
"aw-session-events|Session events|Проверьте collector-guard на RDP: ansible aw_windows -i $INVENTORY -m win_shell -a 'Get-Process -Name aw-session-events-* -ErrorAction SilentlyContinue'" \
|
||||
"aw-dlp-endpoint-signals|DLP endpoint signals|Запустите: ansible aw_windows -i $INVENTORY -m win_shell -a 'schtasks /Run /TN \"ActivityWatch Launch [SHARKON2025_Администратор]\"; Start-Sleep 60'" \
|
||||
"aw-dlp-incidents|DLP incidents|Проверьте: ansible aw_windows -i $INVENTORY -m win_shell -a \"Get-Content 'C:\\ProgramData\\AWatch-rus\\logs\\dlp-*.log' -Tail 20\"" \
|
||||
"aw-dlp-review|DLP review|Проверьте: ssh igor@$AW_HOST 'journalctl -u aw-dlp-policy-engine.service -n 20 --no-pager'" \
|
||||
"aw-dlp-rules|DLP rules|Проверьте: ssh igor@$AW_HOST 'journalctl -u aw-dlp-ioc-refresh.service -n 20 --no-pager'" \
|
||||
; do
|
||||
bucket="${entry%%|*}"; rest="${entry#*|}"
|
||||
label="${rest%%|*}"; remediation="${rest#*|}"
|
||||
check_bucket_freshness "$bucket" "$label" "$remediation"
|
||||
done
|
||||
|
||||
# ============================================================
|
||||
section "5. InfluxDB (10.10.10.10:8086)"
|
||||
# ============================================================
|
||||
check_http_json_key "InfluxDB health" "$INFLUXDB_URL/health" \
|
||||
'.status == "pass"' \
|
||||
"Проверьте InfluxDB на LXC 200: ssh igor@$PROXMOX_HOST 'sudo pct exec 200 -- systemctl status influxdb'"
|
||||
|
||||
# ============================================================
|
||||
section "6. Grafana (10.10.10.11:3000)"
|
||||
# ============================================================
|
||||
check_http_json_key "Grafana health" "$GRAFANA_URL/api/health" \
|
||||
'.database == "ok"' \
|
||||
"Проверьте: ssh igor@$PROXMOX_HOST 'sudo pct exec 201 -- systemctl status grafana-server'"
|
||||
check_http_code "Grafana datasources API" "$GRAFANA_URL/api/datasources" '^200$|^302$|^401$'
|
||||
|
||||
# ============================================================
|
||||
section "7. ClickHouse (10.10.10.2:8123)"
|
||||
# ============================================================
|
||||
# Проверяем через прямой HTTP — AUTHENTICATION_FAILED = сервер жив
|
||||
local_ch_ok=0
|
||||
ch_code=$(curl -sS --max-time 5 "http://$CLICKHOUSE_HOST:8123/?query=SELECT%201" 2>/dev/null | head -1)
|
||||
if echo "$ch_code" | grep -q "AUTHENTICATION_FAILED"; then
|
||||
pass "ClickHouse HTTP — отвечает (требуется аутентификация, это нормально)"
|
||||
local_ch_ok=1
|
||||
elif echo "$ch_code" | grep -q "1"; then
|
||||
pass "ClickHouse HTTP — SELECT 1 OK"
|
||||
local_ch_ok=1
|
||||
else
|
||||
fail "ClickHouse HTTP — не отвечает: $ch_code"
|
||||
echo " REMEDIATION: ssh igor@$PROXMOX_HOST 'cd /opt/activitywatch/clickhouse-1c && sudo docker compose ps; sudo docker compose logs --tail=20'"
|
||||
fi
|
||||
|
||||
# Проверка Docker контейнера через SSH
|
||||
container_status=$(ssh_pve 'sudo docker ps --filter name=aw-rus-1c-clickhouse --format "{{.Status}}" 2>/dev/null' 2>/dev/null)
|
||||
if [ -n "$container_status" ]; then
|
||||
pass "ClickHouse Docker контейнер: $container_status"
|
||||
else
|
||||
fail "ClickHouse Docker контейнер не запущен"
|
||||
echo " REMEDIATION: ssh igor@$PROXMOX_HOST 'cd /opt/activitywatch/clickhouse-1c && sudo docker compose up -d'"
|
||||
fi
|
||||
|
||||
# ClickHouse health timer
|
||||
check_service_remote "ClickHouse health timer" "$PROXMOX_HOST" "aw-1c-clickhouse-health.timer" \
|
||||
"Проверьте: ssh igor@$PROXMOX_HOST 'sudo journalctl -u aw-1c-clickhouse-health.service -n 30 --no-pager'"
|
||||
|
||||
# ClickHouse network health timer (с AW сервера)
|
||||
check_service_remote "ClickHouse network health timer" "$AW_HOST" "aw-clickhouse-network-health.timer" \
|
||||
"Проверьте: ssh igor@$AW_HOST 'sudo journalctl -u aw-clickhouse-network-health.service -n 30 --no-pager'"
|
||||
|
||||
# 1C-ingest timer
|
||||
check_service_remote "1C ingest timer" "$PROXMOX_HOST" "aw-1c-ingest.timer" \
|
||||
"Проверьте: ssh igor@$PROXMOX_HOST 'sudo systemctl status aw-1c-ingest.timer; sudo journalctl -u aw-1c-ingest.service -n 20'"
|
||||
|
||||
# ============================================================
|
||||
section "8. 1C Manager API (10.10.10.2:8710)"
|
||||
# ============================================================
|
||||
check_http_json_key "1C /api/health" "http://$PROXMOX_HOST:8710/api/health" \
|
||||
'.status == "ok"' \
|
||||
"Проверьте Python процесс: ssh igor@$PROXMOX_HOST 'ps aux | grep 8710 | grep -v grep'"
|
||||
check_http_code "1C /manager/brief" "http://$PROXMOX_HOST:8710/manager/brief" '^200$'
|
||||
|
||||
# ============================================================
|
||||
section "9. Nginx Gateway (10.10.10.2)"
|
||||
# ============================================================
|
||||
check_http_code "Gateway /healthz" "https://$PROXMOX_HOST/healthz" '^200$'
|
||||
check_http_code "Gateway /go/proxmox-gui (401=protected, OK)" "https://$PROXMOX_HOST/go/proxmox-gui" '^30[1278]$|^401$'
|
||||
check_http_code "Gateway /go/file1c-brief (401=protected, OK)" "https://$PROXMOX_HOST/go/file1c-brief" '^30[1278]$|^401$'
|
||||
|
||||
check_service_remote "Nginx service" "$PROXMOX_HOST" "nginx.service" \
|
||||
"Проверьте: ssh igor@$PROXMOX_HOST 'sudo systemctl status nginx; sudo nginx -t'"
|
||||
|
||||
# ============================================================
|
||||
section "10. DLP Pipeline (10.10.10.13)"
|
||||
# ============================================================
|
||||
# DLP Policy Engine — должен быть active (running)
|
||||
check_service_remote "DLP Policy Engine" "$AW_HOST" "aw-dlp-policy-engine.service" \
|
||||
"Проверьте: ssh igor@$AW_HOST 'sudo journalctl -u aw-dlp-policy-engine.service -n 30 --no-pager'"
|
||||
|
||||
# DLP Case Management
|
||||
check_service_remote "DLP Case Management" "$AW_HOST" "aw-dlp-case-management.service" \
|
||||
"Проверьте: ssh igor@$AW_HOST 'sudo journalctl -u aw-dlp-case-management.service -n 30 --no-pager'"
|
||||
|
||||
# DLP Aggregator
|
||||
aggr_status=$(ssh_aw 'systemctl is-active activitywatch-dlp-aggregator.timer 2>/dev/null || echo not_found' 2>/dev/null)
|
||||
if [ "$aggr_status" = "active" ]; then
|
||||
pass "DLP Aggregator timer (active)"
|
||||
else
|
||||
fail "DLP Aggregator timer ($aggr_status)"
|
||||
echo " REMEDIATION: ssh igor@$AW_HOST 'sudo systemctl enable --now activitywatch-dlp-aggregator.timer; sudo journalctl -u activitywatch-dlp-aggregator.service -n 30'"
|
||||
fi
|
||||
|
||||
# DLP Influx Exporter
|
||||
influx_exp_status=$(ssh_aw 'systemctl is-active aw-dlp-influx-exporter.timer 2>/dev/null || echo not_found' 2>/dev/null)
|
||||
if [ "$influx_exp_status" = "active" ]; then
|
||||
pass "DLP Influx Exporter timer (active)"
|
||||
else
|
||||
fail "DLP Influx Exporter timer ($influx_exp_status)"
|
||||
echo " REMEDIATION: ssh igor@$AW_HOST 'sudo systemctl enable --now aw-dlp-influx-exporter.timer; sudo journalctl -u aw-dlp-influx-exporter.service -n 30'"
|
||||
fi
|
||||
|
||||
# DLP CEF Exporter
|
||||
check_service_remote "DLP CEF Exporter timer" "$AW_HOST" "aw-dlp-cef-exporter.timer" \
|
||||
"ssh igor@$AW_HOST 'sudo systemctl enable --now aw-dlp-cef-exporter.timer; journalctl -u aw-dlp-cef-exporter.service -n 20'"
|
||||
|
||||
# DLP IOC Refresh
|
||||
check_service_remote "DLP IOC Refresh timer" "$AW_HOST" "aw-dlp-ioc-refresh.timer" \
|
||||
"ssh igor@$AW_HOST 'sudo systemctl enable --now aw-dlp-ioc-refresh.timer'"
|
||||
|
||||
# DLP Syslog Forwarder
|
||||
check_service_remote "DLP Syslog Forwarder timer" "$AW_HOST" "aw-dlp-syslog-forwarder.timer" \
|
||||
"ssh igor@$AW_HOST 'sudo systemctl enable --now aw-dlp-syslog-forwarder.timer'"
|
||||
|
||||
# DLP Webhook Sender
|
||||
check_service_remote "DLP Webhook Sender timer" "$AW_HOST" "aw-dlp-webhook-sender.timer" \
|
||||
"ssh igor@$AW_HOST 'sudo systemctl enable --now aw-dlp-webhook-sender.timer'"
|
||||
|
||||
# DLP Report Scheduler
|
||||
check_service_remote "DLP Report Scheduler timer" "$AW_HOST" "aw-dlp-report-scheduler.timer" \
|
||||
"ssh igor@$AW_HOST 'sudo systemctl enable --now aw-dlp-report-scheduler.timer'"
|
||||
|
||||
# Worktime Influx Exporter
|
||||
check_service_remote "Worktime Influx Exporter timer" "$AW_HOST" "aw-worktime-influx-exporter.timer" \
|
||||
"ssh igor@$AW_HOST 'sudo systemctl enable --now aw-worktime-influx-exporter.timer; journalctl -u aw-worktime-influx-exporter.service -n 20'"
|
||||
|
||||
# ============================================================
|
||||
if [ "$SKIP_WINDOWS" = "1" ]; then
|
||||
skip "Проверки RDP хоста пропущены (--skip-windows)"
|
||||
else
|
||||
section "11. RDP хост (192.168.100.18)"
|
||||
if have ansible && [ -f "$INVENTORY" ]; then
|
||||
check_ansible_module "WinRM ping" aw_windows win_ping
|
||||
|
||||
check_ansible_win_shell "Сессии RDP" 'query user 2>&1'
|
||||
|
||||
check_ansible_win_shell "Процессы watcher" \
|
||||
'Get-Process aw-watcher-afk,aw-watcher-window -ErrorAction SilentlyContinue | Select-Object Name,Id,SessionId,StartTime | Format-Table -AutoSize'
|
||||
|
||||
check_ansible_win_shell "Количество процессов powershell" \
|
||||
'(Get-Process powershell -ErrorAction SilentlyContinue | Measure-Object).Count'
|
||||
|
||||
check_ansible_win_shell "Scheduled tasks (Recovery)" \
|
||||
'schtasks /Query /TN "ActivityWatch Recovery" /FO LIST /V | Select-String "Status|Run|Next"'
|
||||
|
||||
check_ansible_win_shell "Scheduled tasks (Launch Admin)" \
|
||||
'schtasks /Query /TN "ActivityWatch Launch [SHARKON2025_Администратор]" /FO LIST /V | Select-String "Status|Run|Next"'
|
||||
else
|
||||
skip "Ansible или inventory не найдены"
|
||||
fi
|
||||
fi
|
||||
|
||||
# ============================================================
|
||||
section "12. Systemd health (AW server)"
|
||||
# ============================================================
|
||||
check_ansible_shell "AW server core units" aw_server \
|
||||
'systemctl is-active activitywatch-server aw-worktime-api aw-dlp-policy-engine aw-dlp-case-management aw-worktime-influx-exporter.timer aw-dlp-influx-exporter.timer activitywatch-dlp-aggregator.timer aw-clickhouse-network-health.timer | paste -sd,'
|
||||
|
||||
check_ansible_shell "AW server — нет failed units" aw_server \
|
||||
'failed=$(systemctl --failed --no-legend | awk "{print \$1}" | grep -E "activitywatch|aw-|dlp" || true); test -z "$failed" && echo "no AW-related failed units" || { echo "$failed"; exit 1; }'
|
||||
|
||||
# ============================================================
|
||||
section "13. Systemd health (Proxmox)"
|
||||
# ============================================================
|
||||
check_ansible_shell "Proxmox core units" proxmox \
|
||||
'systemctl is-active nginx docker aw-1c-clickhouse-health.timer aw-1c-ingest.timer 2>/dev/null | paste -sd,'
|
||||
|
||||
# ============================================================
|
||||
section "14. Диск и память"
|
||||
# ============================================================
|
||||
check_ansible_shell "Диски AW server" aw_server 'df -h / /var /opt 2>/dev/null | tail -5'
|
||||
check_ansible_shell "Память AW server" aw_server 'free -h | tail -5'
|
||||
|
||||
# ============================================================
|
||||
section "Итог диагностики"
|
||||
# ============================================================
|
||||
printf " OK=%s WARN=%s FAIL=%s SKIP=%s\n" "$OK_COUNT" "$WARN_COUNT" "$FAIL_COUNT" "$SKIP_COUNT"
|
||||
|
||||
if [ "$FAIL_COUNT" -gt 0 ]; then
|
||||
echo ""
|
||||
echo " Есть проблемы! Смотрите REMEDIATION выше для каждого FAIL."
|
||||
echo " После исправления запустите повторно: $0"
|
||||
exit 2
|
||||
elif [ "$WARN_COUNT" -gt 0 ]; then
|
||||
echo ""
|
||||
echo " Есть предупреждения (WARN) — стоит проверить, но не критично."
|
||||
exit 1
|
||||
else
|
||||
echo ""
|
||||
echo " Все проверки пройдены. Контур в рабочем состоянии."
|
||||
exit 0
|
||||
fi
|
||||
@@ -53,7 +53,11 @@ if command -v pwsh >/dev/null 2>&1; then
|
||||
[void][System.Management.Automation.Language.Parser]::ParseFile((Resolve-Path "windows/ActivityWatch.Windows.Common.psm1"),[ref]$null,[ref]$null)
|
||||
[void][System.Management.Automation.Language.Parser]::ParseFile((Resolve-Path "windows/ActivityWatch.Windows.Common.psd1"),[ref]$null,[ref]$null)
|
||||
'
|
||||
pwsh -NoLogo -NoProfile -File windows/aw-collector-guard.ps1 -SelfTest >/dev/null
|
||||
if [[ -f windows/aw-collector-guard.ps1 ]]; then
|
||||
pwsh -NoLogo -NoProfile -File windows/aw-collector-guard.ps1 -SelfTest >/dev/null
|
||||
else
|
||||
echo "windows/aw-collector-guard.ps1 absent; Rust collector guard is the primary runtime."
|
||||
fi
|
||||
else
|
||||
echo "pwsh not found, skipping."
|
||||
fi
|
||||
|
||||
@@ -48,7 +48,6 @@ wineserver -w >/dev/null 2>&1
|
||||
|
||||
required_files=(
|
||||
windows/AWatchRusCollectorGuardService.cs
|
||||
windows/aw-collector-guard.ps1
|
||||
windows/install-collector-guard-service.ps1
|
||||
windows/aw-windows-telemetry.exe
|
||||
windows/dlp-policy.native-cross-os.example.json
|
||||
@@ -70,9 +69,4 @@ for rel in "${required_files[@]}"; do
|
||||
fi
|
||||
done
|
||||
|
||||
if ! grep -q 'collector guard self-test OK' "${INSTALL_DIR_UNIX}/windows/aw-collector-guard.ps1"; then
|
||||
echo "Guard self-test marker missing in extracted installer payload" >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
echo "verify_innosetup_installer: OK"
|
||||
|
||||
@@ -312,7 +312,7 @@ function Get-ActivityWatchBuiltInAdministratorName {
|
||||
catch {
|
||||
}
|
||||
|
||||
if ([string]$env:COMPUTERNAME -ieq 'HOST-EXAMPLE') {
|
||||
if ([string]$env:COMPUTERNAME -ieq 'SHARKON2025') {
|
||||
$script:ActivityWatchBuiltInAdministratorName = 'Администратор'
|
||||
return $script:ActivityWatchBuiltInAdministratorName
|
||||
}
|
||||
@@ -803,12 +803,18 @@ function Copy-ActivityWatchCollectorAssets {
|
||||
$examplePolicyTarget = Join-Path $StateRoot 'dlp-policy.example.json'
|
||||
$policyTarget = Join-Path $StateRoot 'dlp-policy.json'
|
||||
|
||||
Copy-Item -LiteralPath $CollectorScriptSource -Destination $collectorTarget -Force
|
||||
Copy-Item -LiteralPath $EndpointCollectorScriptSource -Destination $endpointCollectorTarget -Force
|
||||
if ($CollectorScriptSource -and (Test-Path -LiteralPath $CollectorScriptSource)) {
|
||||
Copy-Item -LiteralPath $CollectorScriptSource -Destination $collectorTarget -Force
|
||||
}
|
||||
if ($EndpointCollectorScriptSource -and (Test-Path -LiteralPath $EndpointCollectorScriptSource)) {
|
||||
Copy-Item -LiteralPath $EndpointCollectorScriptSource -Destination $endpointCollectorTarget -Force
|
||||
}
|
||||
if ($PolicyClientScriptSource -and (Test-Path -LiteralPath $PolicyClientScriptSource)) {
|
||||
Copy-Item -LiteralPath $PolicyClientScriptSource -Destination $policyClientTarget -Force
|
||||
}
|
||||
Copy-Item -LiteralPath $FileCollectorScriptSource -Destination $fileCollectorTarget -Force
|
||||
if ($FileCollectorScriptSource -and (Test-Path -LiteralPath $FileCollectorScriptSource)) {
|
||||
Copy-Item -LiteralPath $FileCollectorScriptSource -Destination $fileCollectorTarget -Force
|
||||
}
|
||||
Copy-Item -LiteralPath $SessionCollectorScriptSource -Destination $sessionCollectorTarget -Force
|
||||
if ($EvtxExportScriptSource -and (Test-Path -LiteralPath $EvtxExportScriptSource)) {
|
||||
Copy-Item -LiteralPath $EvtxExportScriptSource -Destination $evtxExportTarget -Force
|
||||
@@ -841,11 +847,15 @@ function Copy-ActivityWatchCollectorAssets {
|
||||
Copy-Item -LiteralPath $examplePolicyTarget -Destination $policyTarget -Force
|
||||
}
|
||||
|
||||
$effectiveCollectorTarget = if (Test-Path -LiteralPath $collectorTarget) { $collectorTarget } else { '' }
|
||||
$effectiveEndpointCollectorTarget = if (Test-Path -LiteralPath $endpointCollectorTarget) { $endpointCollectorTarget } else { '' }
|
||||
$effectiveFileCollectorTarget = if (Test-Path -LiteralPath $fileCollectorTarget) { $fileCollectorTarget } else { '' }
|
||||
|
||||
return [pscustomobject]@{
|
||||
CollectorScript = $collectorTarget
|
||||
EndpointCollectorScript = $endpointCollectorTarget
|
||||
CollectorScript = $effectiveCollectorTarget
|
||||
EndpointCollectorScript = $effectiveEndpointCollectorTarget
|
||||
PolicyClientScript = $policyClientTarget
|
||||
FileCollectorScript = $fileCollectorTarget
|
||||
FileCollectorScript = $effectiveFileCollectorTarget
|
||||
SessionCollectorScript = $sessionCollectorTarget
|
||||
EvtxExportScript = $evtxExportTarget
|
||||
HayabusaUploadScript = $hayabusaUploadTarget
|
||||
@@ -960,6 +970,7 @@ function New-ActivityWatchDeploymentConfig {
|
||||
if ($File1CAutoUploadEnabled -and [string]::IsNullOrWhiteSpace($File1CTargetHost)) {
|
||||
throw 'File1CTargetHost is required when File1CAutoUploadEnabled is true.'
|
||||
}
|
||||
$toolkitRoot = Join-Path (Split-Path -Parent $InstallRoot) 'windows'
|
||||
|
||||
return [pscustomobject]@{
|
||||
version = 1
|
||||
@@ -983,7 +994,7 @@ function New-ActivityWatchDeploymentConfig {
|
||||
evtxExportScript = $EvtxExportScript
|
||||
hayabusaUploadScript = $HayabusaUploadScript
|
||||
file1cTelemetryScript = $File1CTelemetryScript
|
||||
file1cTelemetryExecutable = if ([string]::IsNullOrWhiteSpace($File1CTelemetryScript)) { '' } else { Join-Path (Split-Path -Parent $File1CTelemetryScript) 'aw-windows-telemetry.exe' }
|
||||
file1cTelemetryExecutable = Join-Path $toolkitRoot 'aw-windows-telemetry.exe'
|
||||
rulesPath = $RulesPath
|
||||
policyPath = $PolicyPath
|
||||
launchScript = $LaunchScriptPath
|
||||
@@ -998,6 +1009,9 @@ function New-ActivityWatchDeploymentConfig {
|
||||
windowEnabled = $WindowEnabled
|
||||
fileOpsEnabled = $FileOpsEnabled
|
||||
emailEnabled = $false
|
||||
browserCollectorMode = 'rust_primary'
|
||||
dlpEndpointMode = 'rust_primary'
|
||||
fileOpsMode = 'rust_primary'
|
||||
worktimeSessionEnabled = $true
|
||||
worktimeSessionMode = 'powershell_primary'
|
||||
worktimeLegacyFallbackEnabled = $true
|
||||
@@ -1446,19 +1460,20 @@ function Start-RustCollectorIfNeeded {
|
||||
)
|
||||
|
||||
if ([string]::IsNullOrWhiteSpace(`$ExePath) -or [string]::IsNullOrWhiteSpace(`$Subcommand)) {
|
||||
return
|
||||
return `$false
|
||||
}
|
||||
|
||||
if (-not (Test-Path -LiteralPath `$ExePath)) {
|
||||
return
|
||||
return `$false
|
||||
}
|
||||
|
||||
if (Test-RustCollectorRunning -Subcommand `$Subcommand -SessionId `$SessionId) {
|
||||
return
|
||||
return `$true
|
||||
}
|
||||
|
||||
`$argumentList = @(`$Subcommand, '--config-path', `$ConfigPath, '--mode', 'enforce')
|
||||
Start-Process -FilePath `$ExePath -ArgumentList `$argumentList -WindowStyle Hidden
|
||||
return `$true
|
||||
}
|
||||
|
||||
`$config = Get-DeploymentConfig -Path `$ConfigPath
|
||||
@@ -1466,6 +1481,9 @@ function Start-RustCollectorIfNeeded {
|
||||
`$installRoot = [string]`$config.paths.installRoot
|
||||
`$stateRoot = [string]`$config.paths.stateRoot
|
||||
`$deployRoot = if (`$config.paths.PSObject.Properties.Name -contains 'deployRoot' -and -not [string]::IsNullOrWhiteSpace([string]`$config.paths.deployRoot)) { [string]`$config.paths.deployRoot } elseif (`$config.paths.PSObject.Properties.Name -contains 'toolkitRoot' -and -not [string]::IsNullOrWhiteSpace([string]`$config.paths.toolkitRoot)) { [string]`$config.paths.toolkitRoot } else { `$installRoot }
|
||||
if ((Split-Path -Path `$deployRoot -Leaf) -ieq 'bin') {
|
||||
`$deployRoot = Split-Path -Path `$deployRoot -Parent
|
||||
}
|
||||
`$script:ApiBase = '{0}://{1}:{2}/api/0' -f [string]`$config.server.scheme, [string]`$config.server.host, [string]`$config.server.port
|
||||
`$script:Hostname = if (`$config.PSObject.Properties.Name -contains 'awHostname' -and -not [string]::IsNullOrWhiteSpace([string]`$config.awHostname)) { [string]`$config.awHostname } else { `$env:COMPUTERNAME }
|
||||
`$script:KnownBuckets = @{}
|
||||
@@ -1481,9 +1499,9 @@ function Start-RustCollectorIfNeeded {
|
||||
`$afkEnabled = if (`$config.PSObject.Properties.Name -contains 'collectors' -and `$config.collectors.PSObject.Properties.Name -contains 'afkEnabled') { [bool]`$config.collectors.afkEnabled } else { `$true }
|
||||
`$windowEnabled = if (`$config.PSObject.Properties.Name -contains 'collectors' -and `$config.collectors.PSObject.Properties.Name -contains 'windowEnabled') { [bool]`$config.collectors.windowEnabled } else { `$true }
|
||||
`$fileOpsEnabled = if (`$config.PSObject.Properties.Name -contains 'collectors' -and `$config.collectors.PSObject.Properties.Name -contains 'fileOpsEnabled') { [bool]`$config.collectors.fileOpsEnabled } else { `$true }
|
||||
`$browserCollectorMode = if (`$config.PSObject.Properties.Name -contains 'collectors' -and `$config.collectors.PSObject.Properties.Name -contains 'browserCollectorMode') { [string]`$config.collectors.browserCollectorMode } else { 'powershell_primary' }
|
||||
`$dlpEndpointMode = if (`$config.PSObject.Properties.Name -contains 'collectors' -and `$config.collectors.PSObject.Properties.Name -contains 'dlpEndpointMode') { [string]`$config.collectors.dlpEndpointMode } else { 'powershell_primary' }
|
||||
`$fileOpsMode = if (`$config.PSObject.Properties.Name -contains 'collectors' -and `$config.collectors.PSObject.Properties.Name -contains 'fileOpsMode') { [string]`$config.collectors.fileOpsMode } else { 'powershell_primary' }
|
||||
`$browserCollectorMode = if (`$config.PSObject.Properties.Name -contains 'collectors' -and `$config.collectors.PSObject.Properties.Name -contains 'browserCollectorMode') { [string]`$config.collectors.browserCollectorMode } else { 'rust_primary' }
|
||||
`$dlpEndpointMode = if (`$config.PSObject.Properties.Name -contains 'collectors' -and `$config.collectors.PSObject.Properties.Name -contains 'dlpEndpointMode') { [string]`$config.collectors.dlpEndpointMode } else { 'rust_primary' }
|
||||
`$fileOpsMode = if (`$config.PSObject.Properties.Name -contains 'collectors' -and `$config.collectors.PSObject.Properties.Name -contains 'fileOpsMode') { [string]`$config.collectors.fileOpsMode } else { 'rust_primary' }
|
||||
`$emailEnabled = if (`$config.PSObject.Properties.Name -contains 'collectors' -and `$config.collectors.PSObject.Properties.Name -contains 'emailEnabled') { [bool]`$config.collectors.emailEnabled } else { `$false }
|
||||
`$emailCollectorScript = if (`$config.paths.PSObject.Properties.Name -contains 'emailCollectorScript') { [string]`$config.paths.emailCollectorScript } else { Join-Path `$stateRoot 'email-outbound-collector.ps1' }
|
||||
`$launchLockPath = New-LaunchLock -StateRoot `$stateRoot -SessionId `$sessionId
|
||||
@@ -1514,18 +1532,24 @@ try {
|
||||
catch {
|
||||
}
|
||||
if (`$browserCollectorMode -ieq 'rust_primary') {
|
||||
Start-RustCollectorIfNeeded -ExePath `$telemetryExe -Subcommand 'browser-domains-collector' -ConfigPath `$ConfigPath -SessionId `$sessionId
|
||||
if (-not (Start-RustCollectorIfNeeded -ExePath `$telemetryExe -Subcommand 'browser-domains-collector' -ConfigPath `$ConfigPath -SessionId `$sessionId)) {
|
||||
Start-CollectorScriptIfNeeded -ScriptPath `$collectorScript -ConfigPath `$ConfigPath -PowerShellExe `$powershellExe -SessionId `$sessionId
|
||||
}
|
||||
} else {
|
||||
Start-CollectorScriptIfNeeded -ScriptPath `$collectorScript -ConfigPath `$ConfigPath -PowerShellExe `$powershellExe -SessionId `$sessionId
|
||||
}
|
||||
if (`$dlpEndpointMode -ieq 'rust_primary') {
|
||||
Start-RustCollectorIfNeeded -ExePath `$telemetryExe -Subcommand 'dlp-endpoint-collector' -ConfigPath `$ConfigPath -SessionId `$sessionId
|
||||
if (-not (Start-RustCollectorIfNeeded -ExePath `$telemetryExe -Subcommand 'dlp-endpoint-collector' -ConfigPath `$ConfigPath -SessionId `$sessionId)) {
|
||||
Start-CollectorScriptIfNeeded -ScriptPath `$endpointCollectorScript -ConfigPath `$ConfigPath -PowerShellExe `$powershellExe -SessionId `$sessionId
|
||||
}
|
||||
} else {
|
||||
Start-CollectorScriptIfNeeded -ScriptPath `$endpointCollectorScript -ConfigPath `$ConfigPath -PowerShellExe `$powershellExe -SessionId `$sessionId
|
||||
}
|
||||
if (`$fileOpsEnabled) {
|
||||
if (`$fileOpsMode -ieq 'rust_primary') {
|
||||
Start-RustCollectorIfNeeded -ExePath `$telemetryExe -Subcommand 'file-operations-collector' -ConfigPath `$ConfigPath -SessionId `$sessionId
|
||||
if (-not (Start-RustCollectorIfNeeded -ExePath `$telemetryExe -Subcommand 'file-operations-collector' -ConfigPath `$ConfigPath -SessionId `$sessionId)) {
|
||||
Start-CollectorScriptIfNeeded -ScriptPath `$fileCollectorScript -ConfigPath `$ConfigPath -PowerShellExe `$powershellExe -SessionId `$sessionId
|
||||
}
|
||||
} else {
|
||||
Start-CollectorScriptIfNeeded -ScriptPath `$fileCollectorScript -ConfigPath `$ConfigPath -PowerShellExe `$powershellExe -SessionId `$sessionId
|
||||
}
|
||||
|
||||
@@ -55,6 +55,41 @@ function Start-CollectorIfNeeded {
|
||||
Write-ServiceLog ("started collector: {0}" -f $ScriptPath)
|
||||
}
|
||||
|
||||
function Test-RustCollectorRunning {
|
||||
param([string]$Subcommand)
|
||||
if ([string]::IsNullOrWhiteSpace($Subcommand)) { return $false }
|
||||
return [bool](
|
||||
Get-CimInstance Win32_Process -ErrorAction SilentlyContinue |
|
||||
Where-Object {
|
||||
$_.Name -ieq 'aw-windows-telemetry.exe' -and
|
||||
$_.CommandLine -and
|
||||
$_.CommandLine -match [Regex]::Escape($Subcommand)
|
||||
} |
|
||||
Select-Object -First 1
|
||||
)
|
||||
}
|
||||
|
||||
function Start-RustCollectorIfNeeded {
|
||||
param(
|
||||
[string]$ExePath,
|
||||
[string]$Subcommand,
|
||||
[string]$ConfigPath
|
||||
)
|
||||
|
||||
if ([string]::IsNullOrWhiteSpace($ExePath) -or [string]::IsNullOrWhiteSpace($Subcommand)) {
|
||||
return $false
|
||||
}
|
||||
if (-not (Test-Path -LiteralPath $ExePath)) {
|
||||
return $false
|
||||
}
|
||||
if (Test-RustCollectorRunning -Subcommand $Subcommand) {
|
||||
return $true
|
||||
}
|
||||
Start-Process -FilePath $ExePath -ArgumentList @($Subcommand, '--config-path', $ConfigPath, '--mode', 'enforce') -WindowStyle Hidden | Out-Null
|
||||
Write-ServiceLog ("started rust collector: {0}" -f $Subcommand)
|
||||
return $true
|
||||
}
|
||||
|
||||
$cfg = Get-Config -Path $ConfigPath
|
||||
$stateRoot = if ($cfg.paths -and $cfg.paths.stateRoot) { [string]$cfg.paths.stateRoot } else { 'C:\ProgramData\AWatch-rus' }
|
||||
$logsRoot = Join-Path $stateRoot 'logs'
|
||||
@@ -70,6 +105,7 @@ while ($true) {
|
||||
$cfg = Get-Config -Path $ConfigPath
|
||||
$paths = $cfg.paths
|
||||
$collectors = $cfg.collectors
|
||||
$telemetryExe = if ($paths.PSObject.Properties.Name -contains 'file1cTelemetryExecutable' -and -not [string]::IsNullOrWhiteSpace([string]$paths.file1cTelemetryExecutable)) { [string]$paths.file1cTelemetryExecutable } else { Join-Path $PSScriptRoot 'aw-windows-telemetry.exe' }
|
||||
$isSession0 = ([System.Diagnostics.Process]::GetCurrentProcess().SessionId -eq 0)
|
||||
|
||||
# In Session 0 (SYSTEM) collectors that depend on interactive desktop/user profile
|
||||
@@ -78,10 +114,14 @@ while ($true) {
|
||||
$startFileOps = $true
|
||||
$startEmail = $true
|
||||
$startWorktime = $true
|
||||
$dlpEndpointMode = 'rust_primary'
|
||||
$fileOpsMode = 'rust_primary'
|
||||
if ($collectors) {
|
||||
if ($collectors.PSObject.Properties.Name -contains 'fileOpsEnabled') { $startFileOps = [bool]$collectors.fileOpsEnabled }
|
||||
if ($collectors.PSObject.Properties.Name -contains 'emailEnabled') { $startEmail = [bool]$collectors.emailEnabled }
|
||||
if ($collectors.PSObject.Properties.Name -contains 'worktimeSessionEnabled') { $startWorktime = [bool]$collectors.worktimeSessionEnabled }
|
||||
$dlpEndpointMode = if ($collectors.PSObject.Properties.Name -contains 'dlpEndpointMode') { [string]$collectors.dlpEndpointMode } else { 'rust_primary' }
|
||||
$fileOpsMode = if ($collectors.PSObject.Properties.Name -contains 'fileOpsMode') { [string]$collectors.fileOpsMode } else { 'rust_primary' }
|
||||
$worktimeSessionMode = if ($collectors.PSObject.Properties.Name -contains 'worktimeSessionMode') { [string]$collectors.worktimeSessionMode } else { 'powershell_primary' }
|
||||
$worktimeLegacyFallbackEnabled = if ($collectors.PSObject.Properties.Name -contains 'worktimeLegacyFallbackEnabled') { [bool]$collectors.worktimeLegacyFallbackEnabled } else { $true }
|
||||
if ($worktimeSessionMode -ieq 'rust_primary') {
|
||||
@@ -98,9 +138,23 @@ while ($true) {
|
||||
if ($startBrowser) {
|
||||
Start-CollectorIfNeeded -ScriptPath ([string]$paths.collectorScript) -ConfigPath $ConfigPath
|
||||
}
|
||||
Start-CollectorIfNeeded -ScriptPath ([string]$paths.endpointCollectorScript) -ConfigPath $ConfigPath
|
||||
if ($dlpEndpointMode -ieq 'rust_primary') {
|
||||
if (-not (Start-RustCollectorIfNeeded -ExePath $telemetryExe -Subcommand 'dlp-endpoint-collector' -ConfigPath $ConfigPath)) {
|
||||
Start-CollectorIfNeeded -ScriptPath ([string]$paths.endpointCollectorScript) -ConfigPath $ConfigPath
|
||||
}
|
||||
}
|
||||
else {
|
||||
Start-CollectorIfNeeded -ScriptPath ([string]$paths.endpointCollectorScript) -ConfigPath $ConfigPath
|
||||
}
|
||||
if ($startFileOps) {
|
||||
Start-CollectorIfNeeded -ScriptPath ([string]$paths.fileCollectorScript) -ConfigPath $ConfigPath
|
||||
if ($fileOpsMode -ieq 'rust_primary') {
|
||||
if (-not (Start-RustCollectorIfNeeded -ExePath $telemetryExe -Subcommand 'file-operations-collector' -ConfigPath $ConfigPath)) {
|
||||
Start-CollectorIfNeeded -ScriptPath ([string]$paths.fileCollectorScript) -ConfigPath $ConfigPath
|
||||
}
|
||||
}
|
||||
else {
|
||||
Start-CollectorIfNeeded -ScriptPath ([string]$paths.fileCollectorScript) -ConfigPath $ConfigPath
|
||||
}
|
||||
}
|
||||
if ($paths.PSObject.Properties.Name -contains 'emailCollectorScript') {
|
||||
if ($startEmail) {
|
||||
|
||||
@@ -76,6 +76,7 @@ $effectiveFile1CTelemetryScript = if ($existingConfig -and $existingConfig.paths
|
||||
$effectiveRules = Join-Path $effectiveStateRoot 'web-category-rules.json'
|
||||
$effectivePolicy = if ($existingConfig -and $existingConfig.paths.PSObject.Properties.Name -contains 'policyPath') { [string]$existingConfig.paths.policyPath } else { Join-Path $effectiveStateRoot 'dlp-policy.json' }
|
||||
$effectivePolicyClientScript = if ($existingConfig -and $existingConfig.paths.PSObject.Properties.Name -contains 'policyClientScript') { [string]$existingConfig.paths.policyClientScript } else { Join-Path $effectiveStateRoot 'dlp-policy-client.ps1' }
|
||||
$effectiveTelemetryExecutable = if ($existingConfig -and $existingConfig.paths.PSObject.Properties.Name -contains 'file1cTelemetryExecutable' -and -not [string]::IsNullOrWhiteSpace([string]$existingConfig.paths.file1cTelemetryExecutable)) { [string]$existingConfig.paths.file1cTelemetryExecutable } else { Join-Path $PSScriptRoot 'aw-windows-telemetry.exe' }
|
||||
|
||||
$effectiveServerHost = if ($ServerHost) { $ServerHost } elseif ($existingConfig) { [string]$existingConfig.server.host } else { $null }
|
||||
$effectiveServerPort = if ($PSBoundParameters.ContainsKey('ServerPort')) { $ServerPort } elseif ($existingConfig) { [int]$existingConfig.server.port } else { 5600 }
|
||||
@@ -116,6 +117,9 @@ $effectiveFile1CAutoUploadTaskName = if ($existingConfig -and $existingConfig.PS
|
||||
$effectiveFile1CAutoUploadRunAsUser = if ($existingConfig -and $existingConfig.PSObject.Properties.Name -contains 'analytics' -and $existingConfig.analytics.PSObject.Properties.Name -contains 'file1cAutomation' -and $existingConfig.analytics.file1cAutomation.PSObject.Properties.Name -contains 'runAsUser') { [string]$existingConfig.analytics.file1cAutomation.runAsUser } else { '' }
|
||||
$effectiveFile1CTargetHost = if ($existingConfig -and $existingConfig.PSObject.Properties.Name -contains 'analytics' -and $existingConfig.analytics.PSObject.Properties.Name -contains 'file1cAutomation' -and $existingConfig.analytics.file1cAutomation.PSObject.Properties.Name -contains 'targetHost') { [string]$existingConfig.analytics.file1cAutomation.targetHost } else { '' }
|
||||
$effectiveFile1CTargetUser = if ($existingConfig -and $existingConfig.PSObject.Properties.Name -contains 'analytics' -and $existingConfig.analytics.PSObject.Properties.Name -contains 'file1cAutomation' -and $existingConfig.analytics.file1cAutomation.PSObject.Properties.Name -contains 'targetUser') { [string]$existingConfig.analytics.file1cAutomation.targetUser } else { 'igor' }
|
||||
$effectiveBrowserCollectorMode = if ($existingConfig -and $existingConfig.PSObject.Properties.Name -contains 'collectors' -and $existingConfig.collectors.PSObject.Properties.Name -contains 'browserCollectorMode') { [string]$existingConfig.collectors.browserCollectorMode } else { 'rust_primary' }
|
||||
$effectiveDlpEndpointMode = if ($existingConfig -and $existingConfig.PSObject.Properties.Name -contains 'collectors' -and $existingConfig.collectors.PSObject.Properties.Name -contains 'dlpEndpointMode') { [string]$existingConfig.collectors.dlpEndpointMode } else { 'rust_primary' }
|
||||
$effectiveFileOpsMode = if ($existingConfig -and $existingConfig.PSObject.Properties.Name -contains 'collectors' -and $existingConfig.collectors.PSObject.Properties.Name -contains 'fileOpsMode') { [string]$existingConfig.collectors.fileOpsMode } else { 'rust_primary' }
|
||||
|
||||
if ([string]::IsNullOrWhiteSpace($effectiveFile1CTargetHost)) {
|
||||
$file1cLogPath = Join-Path $effectiveLogsRoot 'file1c-telemetry.log'
|
||||
@@ -232,6 +236,11 @@ $config = New-ActivityWatchDeploymentConfig `
|
||||
-UserTasks $taskDefinitions `
|
||||
-PackageVersion $effectiveVersion
|
||||
|
||||
$config.paths.file1cTelemetryExecutable = $effectiveTelemetryExecutable
|
||||
$config.collectors.browserCollectorMode = $effectiveBrowserCollectorMode
|
||||
$config.collectors.dlpEndpointMode = $effectiveDlpEndpointMode
|
||||
$config.collectors.fileOpsMode = $effectiveFileOpsMode
|
||||
|
||||
Write-ActivityWatchDeploymentConfig -Config $config -Path $effectiveConfigPath
|
||||
Remove-LegacyActivityWatchEntries
|
||||
Set-ActivityWatchAcl -InstallRoot $effectiveInstallRoot -StateRoot $effectiveStateRoot -LogsRoot $effectiveLogsRoot
|
||||
|
||||
@@ -25,8 +25,8 @@ $guardScriptPath = Join-Path $PSScriptRoot 'aw-collector-guard.ps1'
|
||||
$rustTelemetryPath = Join-Path $PSScriptRoot 'aw-windows-telemetry.exe'
|
||||
$serviceSourcePath = Join-Path $PSScriptRoot 'AWatchRusCollectorGuardService.cs'
|
||||
$serviceExePath = Join-Path $PSScriptRoot 'AWatchRusCollectorGuardService.exe'
|
||||
if (-not (Test-Path -LiteralPath $guardScriptPath)) {
|
||||
throw "Collector guard script not found: $guardScriptPath"
|
||||
if (-not (Test-Path -LiteralPath $rustTelemetryPath) -and -not (Test-Path -LiteralPath $guardScriptPath)) {
|
||||
throw "Neither Rust collector guard nor PowerShell fallback was found: $rustTelemetryPath ; $guardScriptPath"
|
||||
}
|
||||
if (-not (Test-Path -LiteralPath $serviceSourcePath)) {
|
||||
throw "Collector guard service source not found: $serviceSourcePath"
|
||||
@@ -70,6 +70,9 @@ if (Test-Path -LiteralPath $rustTelemetryPath) {
|
||||
$binPath = "`"$serviceExePath`" --service-name `"$ServiceName`" --exec `"$rustTelemetryPath`" --args `"$rustArgs`" --log `"$serviceLogPath`""
|
||||
}
|
||||
else {
|
||||
if (-not (Test-Path -LiteralPath $guardScriptPath)) {
|
||||
throw "Collector guard script not found: $guardScriptPath"
|
||||
}
|
||||
$binPath = "`"$serviceExePath`" --service-name `"$ServiceName`" --script `"$guardScriptPath`" --config `"$ConfigPath`" --mode $Mode --loop $LoopSeconds --log `"$serviceLogPath`""
|
||||
}
|
||||
|
||||
|
||||
@@ -29,6 +29,20 @@ function Ensure-Dir {
|
||||
}
|
||||
}
|
||||
|
||||
function Copy-IfExists {
|
||||
param(
|
||||
[Parameter(Mandatory = $true)]
|
||||
[string]$Source,
|
||||
[Parameter(Mandatory = $true)]
|
||||
[string]$Destination
|
||||
)
|
||||
if (Test-Path -LiteralPath $Source) {
|
||||
Copy-Item -LiteralPath $Source -Destination $Destination -Force
|
||||
return $Destination
|
||||
}
|
||||
return ''
|
||||
}
|
||||
|
||||
Assert-Admin
|
||||
|
||||
$logsRoot = Join-Path $StateRoot 'logs'
|
||||
@@ -40,14 +54,15 @@ $endpointCollectorScript = Join-Path $StateRoot 'dlp-endpoint-signals-collector.
|
||||
$fileCollectorScript = Join-Path $StateRoot 'file-operations-collector.ps1'
|
||||
$emailCollectorScript = Join-Path $StateRoot 'email-outbound-collector.ps1'
|
||||
$sessionCollectorScript = Join-Path $StateRoot 'worktime-session-collector.ps1'
|
||||
$telemetryExecutable = Join-Path $PSScriptRoot 'aw-windows-telemetry.exe'
|
||||
$rulesPath = Join-Path $StateRoot 'web-category-rules.json'
|
||||
$policyPath = Join-Path $StateRoot 'dlp-policy.json'
|
||||
$configPath = Join-Path $StateRoot 'deployment-config.json'
|
||||
$serviceScriptPath = Join-Path $PSScriptRoot 'aw-standalone-service.ps1'
|
||||
|
||||
Copy-Item -LiteralPath (Join-Path $PSScriptRoot 'browser-domains-native-collector.ps1') -Destination $collectorScript -Force
|
||||
Copy-Item -LiteralPath (Join-Path $PSScriptRoot 'dlp-endpoint-signals-collector.ps1') -Destination $endpointCollectorScript -Force
|
||||
Copy-Item -LiteralPath (Join-Path $PSScriptRoot 'file-operations-collector.ps1') -Destination $fileCollectorScript -Force
|
||||
$collectorScript = Copy-IfExists -Source (Join-Path $PSScriptRoot 'browser-domains-native-collector.ps1') -Destination $collectorScript
|
||||
$endpointCollectorScript = Copy-IfExists -Source (Join-Path $PSScriptRoot 'dlp-endpoint-signals-collector.ps1') -Destination $endpointCollectorScript
|
||||
$fileCollectorScript = Copy-IfExists -Source (Join-Path $PSScriptRoot 'file-operations-collector.ps1') -Destination $fileCollectorScript
|
||||
if (Test-Path -LiteralPath (Join-Path $PSScriptRoot 'email-outbound-collector.ps1')) {
|
||||
Copy-Item -LiteralPath (Join-Path $PSScriptRoot 'email-outbound-collector.ps1') -Destination $emailCollectorScript -Force
|
||||
}
|
||||
@@ -82,6 +97,7 @@ $config = [pscustomobject]@{
|
||||
fileCollectorScript = $fileCollectorScript
|
||||
emailCollectorScript = $emailCollectorScript
|
||||
sessionCollectorScript = $sessionCollectorScript
|
||||
file1cTelemetryExecutable = $telemetryExecutable
|
||||
rulesPath = $rulesPath
|
||||
policyPath = $policyPath
|
||||
}
|
||||
@@ -94,6 +110,9 @@ $config = [pscustomobject]@{
|
||||
windowEnabled = $false
|
||||
fileOpsEnabled = $true
|
||||
emailEnabled = $true
|
||||
browserCollectorMode = 'rust_primary'
|
||||
dlpEndpointMode = 'rust_primary'
|
||||
fileOpsMode = 'rust_primary'
|
||||
worktimeSessionEnabled = $true
|
||||
worktimeSessionMode = 'powershell_primary'
|
||||
worktimeLegacyFallbackEnabled = $true
|
||||
|
||||
@@ -97,6 +97,15 @@ function Update-AWatchConfigPaths {
|
||||
$Config.paths.logsRoot = $logsRoot
|
||||
$Config.paths.collectorScript = Join-Path $NewStateRoot 'browser-domains-native-collector.ps1'
|
||||
$Config.paths.endpointCollectorScript = Join-Path $NewStateRoot 'dlp-endpoint-signals-collector.ps1'
|
||||
if ($Config.paths.PSObject.Properties.Name -contains 'fileCollectorScript') {
|
||||
$Config.paths.fileCollectorScript = Join-Path $NewStateRoot 'file-operations-collector.ps1'
|
||||
}
|
||||
if ($Config.paths.PSObject.Properties.Name -contains 'file1cTelemetryExecutable') {
|
||||
$Config.paths.file1cTelemetryExecutable = Join-Path $ToolkitRoot 'aw-windows-telemetry.exe'
|
||||
}
|
||||
else {
|
||||
$Config.paths | Add-Member -NotePropertyName 'file1cTelemetryExecutable' -NotePropertyValue (Join-Path $ToolkitRoot 'aw-windows-telemetry.exe')
|
||||
}
|
||||
if ($Config.paths.PSObject.Properties.Name -contains 'sessionCollectorScript') {
|
||||
$Config.paths.sessionCollectorScript = Join-Path $NewStateRoot 'worktime-session-collector.ps1'
|
||||
}
|
||||
@@ -104,6 +113,20 @@ function Update-AWatchConfigPaths {
|
||||
if ($Config.paths.PSObject.Properties.Name -contains 'policyPath') {
|
||||
$Config.paths.policyPath = Join-Path $NewStateRoot 'dlp-policy.json'
|
||||
}
|
||||
if ($Config.PSObject.Properties.Name -contains 'collectors') {
|
||||
foreach ($entry in @(
|
||||
@{ Name = 'browserCollectorMode'; Value = 'rust_primary' },
|
||||
@{ Name = 'dlpEndpointMode'; Value = 'rust_primary' },
|
||||
@{ Name = 'fileOpsMode'; Value = 'rust_primary' }
|
||||
)) {
|
||||
if ($Config.collectors.PSObject.Properties.Name -contains $entry.Name) {
|
||||
$Config.collectors.PSObject.Properties[$entry.Name].Value = $entry.Value
|
||||
}
|
||||
else {
|
||||
$Config.collectors | Add-Member -NotePropertyName $entry.Name -NotePropertyValue $entry.Value
|
||||
}
|
||||
}
|
||||
}
|
||||
$Config.paths.launchScript = Join-Path $NewStateRoot 'launch-watchers.ps1'
|
||||
$Config.paths.recoveryScript = Join-Path $NewStateRoot 'recovery-loop.ps1'
|
||||
|
||||
@@ -194,7 +217,9 @@ if ($PSCmdlet.ShouldProcess($env:COMPUTERNAME, 'Миграция ActivityWatch W
|
||||
foreach ($file in @(
|
||||
'browser-domains-native-collector.ps1',
|
||||
'dlp-endpoint-signals-collector.ps1',
|
||||
'file-operations-collector.ps1',
|
||||
'worktime-session-collector.ps1',
|
||||
'aw-windows-telemetry.exe',
|
||||
'web-category-rules.example.json',
|
||||
'dlp-policy.example.json'
|
||||
)) {
|
||||
|
||||
@@ -16,6 +16,7 @@ $collectorScript = [string]$config.paths.collectorScript
|
||||
$endpointCollectorScript = if ($config.paths.PSObject.Properties.Name -contains 'endpointCollectorScript') { [string]$config.paths.endpointCollectorScript } else { Join-Path $stateRoot 'dlp-endpoint-signals-collector.ps1' }
|
||||
$fileCollectorScript = if ($config.paths.PSObject.Properties.Name -contains 'fileCollectorScript') { [string]$config.paths.fileCollectorScript } else { Join-Path $stateRoot 'file-operations-collector.ps1' }
|
||||
$sessionCollectorScript = if ($config.paths.PSObject.Properties.Name -contains 'sessionCollectorScript') { [string]$config.paths.sessionCollectorScript } else { Join-Path $stateRoot 'worktime-session-collector.ps1' }
|
||||
$telemetryExecutable = if ($config.paths.PSObject.Properties.Name -contains 'file1cTelemetryExecutable' -and -not [string]::IsNullOrWhiteSpace([string]$config.paths.file1cTelemetryExecutable)) { [string]$config.paths.file1cTelemetryExecutable } else { Join-Path (Join-Path ([System.Environment]::GetFolderPath('ProgramFiles')) 'AWatch-rus\windows') 'aw-windows-telemetry.exe' }
|
||||
$evtxExportScript = if ($config.paths.PSObject.Properties.Name -contains 'evtxExportScript') { [string]$config.paths.evtxExportScript } else { Join-Path $stateRoot 'export-evtx-for-hayabusa.ps1' }
|
||||
$rulesPath = [string]$config.paths.rulesPath
|
||||
$policyPath = if ($config.paths.PSObject.Properties.Name -contains 'policyPath') { [string]$config.paths.policyPath } else { Join-Path $stateRoot 'dlp-policy.json' }
|
||||
@@ -36,6 +37,9 @@ $queueMaxDepth = 1000
|
||||
$afkExpected = if ($config.PSObject.Properties.Name -contains 'collectors' -and $config.collectors.PSObject.Properties.Name -contains 'afkEnabled') { [bool]$config.collectors.afkEnabled } else { $true }
|
||||
$windowExpected = if ($config.PSObject.Properties.Name -contains 'collectors' -and $config.collectors.PSObject.Properties.Name -contains 'windowEnabled') { [bool]$config.collectors.windowEnabled } else { $true }
|
||||
$fileOpsExpected = if ($config.PSObject.Properties.Name -contains 'collectors' -and $config.collectors.PSObject.Properties.Name -contains 'fileOpsEnabled') { [bool]$config.collectors.fileOpsEnabled } else { $true }
|
||||
$browserCollectorMode = if ($config.PSObject.Properties.Name -contains 'collectors' -and $config.collectors.PSObject.Properties.Name -contains 'browserCollectorMode') { [string]$config.collectors.browserCollectorMode } else { 'rust_primary' }
|
||||
$dlpEndpointMode = if ($config.PSObject.Properties.Name -contains 'collectors' -and $config.collectors.PSObject.Properties.Name -contains 'dlpEndpointMode') { [string]$config.collectors.dlpEndpointMode } else { 'rust_primary' }
|
||||
$fileOpsMode = if ($config.PSObject.Properties.Name -contains 'collectors' -and $config.collectors.PSObject.Properties.Name -contains 'fileOpsMode') { [string]$config.collectors.fileOpsMode } else { 'rust_primary' }
|
||||
$sessionEventsConfig = if ($config.PSObject.Properties.Name -contains 'sessionEvents') { $config.sessionEvents } else { $null }
|
||||
$sessionLogonEnabled = if ($sessionEventsConfig -and $sessionEventsConfig.PSObject.Properties.Name -contains 'logonEnabled') { [bool]$sessionEventsConfig.logonEnabled } else { $false }
|
||||
$sessionProcessEventsEnabled = if ($sessionEventsConfig -and $sessionEventsConfig.PSObject.Properties.Name -contains 'processEventsEnabled') { [bool]$sessionEventsConfig.processEventsEnabled } else { $false }
|
||||
@@ -438,8 +442,6 @@ function Get-TaskSnapshot {
|
||||
}
|
||||
|
||||
$requiredFiles = @(
|
||||
$collectorScript,
|
||||
$endpointCollectorScript,
|
||||
$sessionCollectorScript,
|
||||
$evtxExportScript,
|
||||
$rulesPath,
|
||||
@@ -449,7 +451,16 @@ $requiredFiles = @(
|
||||
$recoveryScript,
|
||||
$ConfigPath
|
||||
)
|
||||
if ($fileOpsExpected) {
|
||||
if ($browserCollectorMode -ieq 'rust_primary' -or $dlpEndpointMode -ieq 'rust_primary' -or ($fileOpsExpected -and $fileOpsMode -ieq 'rust_primary')) {
|
||||
$requiredFiles += $telemetryExecutable
|
||||
}
|
||||
if ($browserCollectorMode -ine 'rust_primary') {
|
||||
$requiredFiles += $collectorScript
|
||||
}
|
||||
if ($dlpEndpointMode -ine 'rust_primary') {
|
||||
$requiredFiles += $endpointCollectorScript
|
||||
}
|
||||
if ($fileOpsExpected -and $fileOpsMode -ine 'rust_primary') {
|
||||
$requiredFiles += $fileCollectorScript
|
||||
}
|
||||
if ($afkExpected) {
|
||||
@@ -477,6 +488,15 @@ $sessionCollectorProcesses = @(Get-CollectorProcesses -ScriptPath $sessionCollec
|
||||
$endpointCollectorProcesses = @(Get-CollectorProcesses -ScriptPath $endpointCollectorScript)
|
||||
$fileCollectorProcesses = if ($fileOpsExpected) { @(Get-CollectorProcesses -ScriptPath $fileCollectorScript) } else { @() }
|
||||
$browserCollectorProcesses = @(Get-CollectorProcesses -ScriptPath $collectorScript)
|
||||
$rustCollectorProcesses = @(
|
||||
Get-CimInstance Win32_Process -ErrorAction SilentlyContinue |
|
||||
Where-Object {
|
||||
$_.Name -ieq 'aw-windows-telemetry.exe' -and
|
||||
$_.CommandLine -and
|
||||
($_.CommandLine -match 'browser-domains-collector' -or $_.CommandLine -match 'dlp-endpoint-collector' -or $_.CommandLine -match 'file-operations-collector')
|
||||
} |
|
||||
Select-Object @{ Name = 'Name'; Expression = { $_.Name } }, @{ Name = 'Id'; Expression = { [int]$_.ProcessId } }, @{ Name = 'SessionId'; Expression = { [int]$_.SessionId } }, @{ Name = 'CommandLine'; Expression = { [string]$_.CommandLine } }
|
||||
)
|
||||
|
||||
$liveLoggedOnUsers = Get-LoggedOnUsers
|
||||
$interactiveUsers = Get-LoggedOnUsers -IncludeDisconnected $true
|
||||
@@ -611,6 +631,12 @@ $result = [ordered]@{
|
||||
endpointCollectorDuplicates = @($endpointCollectorDuplicates)
|
||||
fileCollectors = @($fileCollectorProcesses)
|
||||
fileCollectorDuplicates = @($fileCollectorDuplicates)
|
||||
rustCollectors = @($rustCollectorProcesses)
|
||||
collectorModes = [ordered]@{
|
||||
browser = $browserCollectorMode
|
||||
endpoint = $dlpEndpointMode
|
||||
fileOps = $fileOpsMode
|
||||
}
|
||||
ok = [bool](
|
||||
$watcherCountsOk -and
|
||||
$sessionCollectorOk -and
|
||||
|
||||
Reference in New Issue
Block a user