Files
AWatch-rus/windows/aw-standalone-service.ps1
T

175 lines
7.3 KiB
PowerShell

[CmdletBinding()]
param(
[string]$ConfigPath = 'C:\ProgramData\AWatch-rus\deployment-config.json',
[int]$LoopSeconds = 20
)
Set-StrictMode -Version Latest
$ErrorActionPreference = 'Stop'
function Get-Config {
param([string]$Path)
if (-not (Test-Path -LiteralPath $Path)) {
throw "Config not found: $Path"
}
Get-Content -LiteralPath $Path -Raw | ConvertFrom-Json
}
function Write-ServiceLog {
param([string]$Message)
try {
Add-Content -LiteralPath $script:LogPath -Value ('{0} {1}' -f (Get-Date -Format s), $Message)
}
catch {}
}
function Start-CollectorIfNeeded {
param(
[string]$ScriptPath,
[string]$ConfigPath
)
if ([string]::IsNullOrWhiteSpace($ScriptPath) -or -not (Test-Path -LiteralPath $ScriptPath)) {
return
}
$escaped = [Regex]::Escape($ScriptPath)
$running = Get-CimInstance Win32_Process -ErrorAction SilentlyContinue |
Where-Object {
$_.Name -eq 'powershell.exe' -and
$_.CommandLine -match $escaped -and
$_.CommandLine -match [Regex]::Escape($ConfigPath)
} |
Select-Object -First 1
if ($running) {
return
}
$args = @('-NoProfile', '-ExecutionPolicy', 'Bypass')
if ($ScriptPath -like '*dlp-endpoint-signals*') {
$args += '-STA'
}
$args += @('-File', $ScriptPath, '-ConfigPath', $ConfigPath)
Start-Process -FilePath 'powershell.exe' -ArgumentList $args -WindowStyle Hidden | Out-Null
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'
if (-not (Test-Path -LiteralPath $logsRoot)) {
New-Item -Path $logsRoot -ItemType Directory -Force | Out-Null
}
$script:LogPath = Join-Path $logsRoot 'standalone-agent-service.log'
Write-ServiceLog ('service loop started, config={0}' -f $ConfigPath)
while ($true) {
try {
$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
# will crash/exit or spin in useless restart loops. Keep only headless-safe collectors here.
$startBrowser = $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') {
$rustAgentRunning = @(Get-CimInstance Win32_Process -ErrorAction SilentlyContinue | Where-Object { $_.Name -ieq 'awatch-agent-rs.exe' }).Count -gt 0
$startWorktime = $worktimeLegacyFallbackEnabled -and (-not $rustAgentRunning)
}
}
if ($isSession0) {
$startBrowser = $false
$startFileOps = $false
$startEmail = $false
}
if ($startBrowser) {
Start-CollectorIfNeeded -ScriptPath ([string]$paths.collectorScript) -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) {
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) {
Start-CollectorIfNeeded -ScriptPath ([string]$paths.emailCollectorScript) -ConfigPath $ConfigPath
}
}
if ($paths.PSObject.Properties.Name -contains 'sessionCollectorScript') {
if ($startWorktime) {
Start-CollectorIfNeeded -ScriptPath ([string]$paths.sessionCollectorScript) -ConfigPath $ConfigPath
}
}
}
catch {
Write-ServiceLog ("loop error: {0}" -f $_.Exception.Message)
}
Start-Sleep -Seconds ([Math]::Max($LoopSeconds, 5))
}