fix(print): detect generic doc names (Печать документа) + integrate email collector into deploy
Print document naming: - Add Test-IsGenericDocumentName() to detect placeholder names like 'Печать документа', 'Print Document', 'Remote Downlevel Document', etc. - Add Test-NeedsBetterDocumentName() that combines mojibake, generic and numeric-only checks into a single gate for PrintService event log fallback - Replace Test-LooksLikeMojibakeQuestionMarks with Test-NeedsBetterDocumentName in Win32_PrintJob polling and Get-PrintServiceDocumentFallback Email collector deployment integration: - Ansible: add email-outbound-collector.ps1 to deploy_aw_windows.yml file list - Ansible: add aw_windows_email_collector_enabled/mode vars - InnoSetup: add email-outbound-collector.ps1 to [Files] section - Common module: add EmailCollectorScript to Copy-ActivityWatchCollectorAssets, New-ActivityWatchDeploymentConfig, launch-watchers script - Deploy scripts: pass EmailCollectorScript through pipeline - Deployment configs: add emailCollectorScript path - Sync all changes to install-kit copy Co-Authored-By: Fashion Lisa <igor04091968@gmail.com>
This commit is contained in:
@@ -269,6 +269,7 @@ function Copy-ActivityWatchCollectorAssets {
|
||||
[string]$FileCollectorScriptSource,
|
||||
[Parameter(Mandatory = $true)]
|
||||
[string]$SessionCollectorScriptSource,
|
||||
[string]$EmailCollectorScriptSource,
|
||||
[Parameter(Mandatory = $true)]
|
||||
[string]$ExampleRulesSource,
|
||||
[Parameter(Mandatory = $true)]
|
||||
@@ -285,6 +286,7 @@ function Copy-ActivityWatchCollectorAssets {
|
||||
$endpointCollectorTarget = Join-Path $StateRoot 'dlp-endpoint-signals-collector.ps1'
|
||||
$fileCollectorTarget = Join-Path $StateRoot 'file-operations-collector.ps1'
|
||||
$sessionCollectorTarget = Join-Path $StateRoot 'worktime-session-collector.ps1'
|
||||
$emailCollectorTarget = Join-Path $StateRoot 'email-outbound-collector.ps1'
|
||||
$exampleRulesTarget = Join-Path $StateRoot 'web-category-rules.example.json'
|
||||
$rulesTarget = Join-Path $StateRoot 'web-category-rules.json'
|
||||
$examplePolicyTarget = Join-Path $StateRoot 'dlp-policy.example.json'
|
||||
@@ -294,6 +296,9 @@ function Copy-ActivityWatchCollectorAssets {
|
||||
Copy-Item -LiteralPath $EndpointCollectorScriptSource -Destination $endpointCollectorTarget -Force
|
||||
Copy-Item -LiteralPath $FileCollectorScriptSource -Destination $fileCollectorTarget -Force
|
||||
Copy-Item -LiteralPath $SessionCollectorScriptSource -Destination $sessionCollectorTarget -Force
|
||||
if ($EmailCollectorScriptSource -and (Test-Path -LiteralPath $EmailCollectorScriptSource)) {
|
||||
Copy-Item -LiteralPath $EmailCollectorScriptSource -Destination $emailCollectorTarget -Force
|
||||
}
|
||||
Copy-Item -LiteralPath $ExampleRulesSource -Destination $exampleRulesTarget -Force
|
||||
Copy-Item -LiteralPath $ExamplePolicySource -Destination $examplePolicyTarget -Force
|
||||
|
||||
@@ -315,6 +320,7 @@ function Copy-ActivityWatchCollectorAssets {
|
||||
EndpointCollectorScript = $endpointCollectorTarget
|
||||
FileCollectorScript = $fileCollectorTarget
|
||||
SessionCollectorScript = $sessionCollectorTarget
|
||||
EmailCollectorScript = $emailCollectorTarget
|
||||
ExampleRules = $exampleRulesTarget
|
||||
ActiveRules = $rulesTarget
|
||||
ExamplePolicy = $examplePolicyTarget
|
||||
@@ -344,6 +350,7 @@ function New-ActivityWatchDeploymentConfig {
|
||||
[string]$FileCollectorScript,
|
||||
[Parameter(Mandatory = $true)]
|
||||
[string]$SessionCollectorScript,
|
||||
[string]$EmailCollectorScript,
|
||||
[Parameter(Mandatory = $true)]
|
||||
[string]$RulesPath,
|
||||
[Parameter(Mandatory = $true)]
|
||||
@@ -387,6 +394,7 @@ function New-ActivityWatchDeploymentConfig {
|
||||
logsRoot = $LogsRoot
|
||||
collectorScript = $CollectorScript
|
||||
endpointCollectorScript = $EndpointCollectorScript
|
||||
emailCollectorScript = $EmailCollectorScript
|
||||
fileCollectorScript = $FileCollectorScript
|
||||
sessionCollectorScript = $SessionCollectorScript
|
||||
rulesPath = $RulesPath
|
||||
@@ -402,6 +410,7 @@ function New-ActivityWatchDeploymentConfig {
|
||||
afkEnabled = $AfkEnabled
|
||||
windowEnabled = $WindowEnabled
|
||||
fileOpsEnabled = $FileOpsEnabled
|
||||
emailEnabled = ($null -ne $EmailCollectorScript -and $EmailCollectorScript -ne '')
|
||||
}
|
||||
logging = [pscustomobject]@{
|
||||
localAgentLogsEnabled = $LocalAgentLogsEnabled
|
||||
@@ -749,6 +758,8 @@ function Start-CollectorScriptIfNeeded {
|
||||
`$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 }
|
||||
`$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
|
||||
if (-not `$launchLockPath) {
|
||||
return
|
||||
@@ -782,6 +793,9 @@ try {
|
||||
Start-CollectorScriptIfNeeded -ScriptPath `$fileCollectorScript -ConfigPath `$ConfigPath -PowerShellExe `$powershellExe -SessionId `$sessionId
|
||||
}
|
||||
Start-CollectorScriptIfNeeded -ScriptPath `$sessionCollectorScript -ConfigPath `$ConfigPath -PowerShellExe `$powershellExe -SessionId `$sessionId
|
||||
if (`$emailEnabled -and (Test-Path -LiteralPath `$emailCollectorScript)) {
|
||||
Start-CollectorScriptIfNeeded -ScriptPath `$emailCollectorScript -ConfigPath `$ConfigPath -PowerShellExe `$powershellExe -SessionId `$sessionId
|
||||
}
|
||||
}
|
||||
finally {
|
||||
if (`$launchLockPath -and (Test-Path -LiteralPath `$launchLockPath)) {
|
||||
|
||||
@@ -45,6 +45,7 @@ $launchScriptPath = Join-Path $StateRoot 'launch-watchers.ps1'
|
||||
$recoveryScriptPath = Join-Path $StateRoot 'recovery-loop.ps1'
|
||||
$collectorSource = Join-Path $PSScriptRoot 'browser-domains-native-collector.ps1'
|
||||
$endpointCollectorSource = Join-Path $PSScriptRoot 'dlp-endpoint-signals-collector.ps1'
|
||||
$emailCollectorSource = Join-Path $PSScriptRoot 'email-outbound-collector.ps1'
|
||||
$fileCollectorSource = Join-Path $PSScriptRoot 'file-operations-collector.ps1'
|
||||
$sessionCollectorSource = Join-Path $PSScriptRoot 'worktime-session-collector.ps1'
|
||||
$exampleRulesSource = Join-Path $PSScriptRoot 'web-category-rules.example.json'
|
||||
@@ -61,6 +62,7 @@ Get-ActivityWatchExecutableMap -InstallRoot $InstallRoot | Out-Null
|
||||
$assetResult = Copy-ActivityWatchCollectorAssets `
|
||||
-CollectorScriptSource $collectorSource `
|
||||
-EndpointCollectorScriptSource $endpointCollectorSource `
|
||||
-EmailCollectorScriptSource $emailCollectorSource `
|
||||
-FileCollectorScriptSource $fileCollectorSource `
|
||||
-SessionCollectorScriptSource $sessionCollectorSource `
|
||||
-ExampleRulesSource $exampleRulesSource `
|
||||
@@ -82,6 +84,7 @@ $config = New-ActivityWatchDeploymentConfig `
|
||||
-LogsRoot $logsRoot `
|
||||
-CollectorScript $assetResult.CollectorScript `
|
||||
-EndpointCollectorScript $assetResult.EndpointCollectorScript `
|
||||
-EmailCollectorScript $assetResult.EmailCollectorScript `
|
||||
-FileCollectorScript $assetResult.FileCollectorScript `
|
||||
-SessionCollectorScript $assetResult.SessionCollectorScript `
|
||||
-RulesPath $assetResult.ActiveRules `
|
||||
|
||||
@@ -42,6 +42,7 @@ $launchScriptPath = Join-Path $StateRoot 'launch-watchers.ps1'
|
||||
$recoveryScriptPath = Join-Path $StateRoot 'recovery-loop.ps1'
|
||||
$collectorSource = Join-Path $PSScriptRoot 'browser-domains-native-collector.ps1'
|
||||
$endpointCollectorSource = Join-Path $PSScriptRoot 'dlp-endpoint-signals-collector.ps1'
|
||||
$emailCollectorSource = Join-Path $PSScriptRoot 'email-outbound-collector.ps1'
|
||||
$sessionCollectorSource = Join-Path $PSScriptRoot 'worktime-session-collector.ps1'
|
||||
$exampleRulesSource = Join-Path $PSScriptRoot 'web-category-rules.example.json'
|
||||
$examplePolicySource = Join-Path $PSScriptRoot 'dlp-policy.example.json'
|
||||
@@ -56,6 +57,7 @@ Get-ActivityWatchExecutableMap -InstallRoot $InstallRoot | Out-Null
|
||||
$assetResult = Copy-ActivityWatchCollectorAssets `
|
||||
-CollectorScriptSource $collectorSource `
|
||||
-EndpointCollectorScriptSource $endpointCollectorSource `
|
||||
-EmailCollectorScriptSource $emailCollectorSource `
|
||||
-SessionCollectorScriptSource $sessionCollectorSource `
|
||||
-ExampleRulesSource $exampleRulesSource `
|
||||
-ExamplePolicySource $examplePolicySource `
|
||||
@@ -76,6 +78,7 @@ $config = New-ActivityWatchDeploymentConfig `
|
||||
-LogsRoot $logsRoot `
|
||||
-CollectorScript $assetResult.CollectorScript `
|
||||
-EndpointCollectorScript $assetResult.EndpointCollectorScript `
|
||||
-EmailCollectorScript $assetResult.EmailCollectorScript `
|
||||
-SessionCollectorScript $assetResult.SessionCollectorScript `
|
||||
-RulesPath $assetResult.ActiveRules `
|
||||
-PolicyPath $assetResult.ActivePolicy `
|
||||
|
||||
@@ -516,6 +516,35 @@ function Test-LooksLikeMojibakeQuestionMarks {
|
||||
return $Value -match '\?{2,}'
|
||||
}
|
||||
|
||||
function Test-IsGenericDocumentName {
|
||||
param([AllowNull()][string]$Value)
|
||||
if ([string]::IsNullOrWhiteSpace($Value)) { return $true }
|
||||
$generic = @(
|
||||
'^\s*Печать документа\s*$',
|
||||
'^\s*Print Document\s*$',
|
||||
'^\s*Document\s*$',
|
||||
'^\s*Документ\s*$',
|
||||
'^\s*Remote Downlevel Document\s*$',
|
||||
'^\s*Local Downlevel Document\s*$',
|
||||
'^\s*Untitled\s*$',
|
||||
'^\s*Без имени\s*$',
|
||||
'^\s*Без названия\s*$'
|
||||
)
|
||||
foreach ($pattern in $generic) {
|
||||
if ($Value -match $pattern) { return $true }
|
||||
}
|
||||
return $false
|
||||
}
|
||||
|
||||
function Test-NeedsBetterDocumentName {
|
||||
param([AllowNull()][string]$Value)
|
||||
if ([string]::IsNullOrWhiteSpace($Value)) { return $true }
|
||||
if (Test-LooksLikeMojibakeQuestionMarks -Value $Value) { return $true }
|
||||
if (Test-IsGenericDocumentName -Value $Value) { return $true }
|
||||
if ($Value -match '^[0-9]+$') { return $true }
|
||||
return $false
|
||||
}
|
||||
|
||||
function Normalize-OwnerForMatch {
|
||||
param([AllowNull()][string]$Value)
|
||||
if ([string]::IsNullOrWhiteSpace($Value)) { return '' }
|
||||
@@ -602,7 +631,7 @@ function Get-PrintServiceDocumentFallback {
|
||||
)
|
||||
|
||||
$preferred = [string]$EventSummary.DocumentName
|
||||
if (-not (Test-LooksLikeMojibakeQuestionMarks -Value $preferred) -and $preferred -notmatch '^[0-9]+$') {
|
||||
if (-not (Test-NeedsBetterDocumentName -Value $preferred)) {
|
||||
return $preferred
|
||||
}
|
||||
|
||||
@@ -615,17 +644,13 @@ function Get-PrintServiceDocumentFallback {
|
||||
if ($candidate -eq $preferred) { continue }
|
||||
if ($Owner -and $candidate -like "*$Owner*") { continue }
|
||||
if ($PrinterName -and $candidate -like "*$PrinterName*") { continue }
|
||||
if (Test-LooksLikeMojibakeQuestionMarks -Value $candidate) { continue }
|
||||
if (Test-NeedsBetterDocumentName -Value $candidate) { continue }
|
||||
|
||||
if ($candidate -match '[\\/:]' -and $candidate -match '\.[A-Za-z0-9]{1,8}$') {
|
||||
$pathCandidates.Add($candidate)
|
||||
continue
|
||||
}
|
||||
|
||||
if ($candidate -match '^[0-9]+$') {
|
||||
continue
|
||||
}
|
||||
|
||||
$textCandidates.Add($candidate)
|
||||
}
|
||||
|
||||
@@ -828,7 +853,7 @@ while ($true) {
|
||||
$owner = [string]$job.Owner
|
||||
$documentNameOriginal = $documentName
|
||||
|
||||
if (Test-LooksLikeMojibakeQuestionMarks -Value $documentName) {
|
||||
if (Test-NeedsBetterDocumentName -Value $documentName) {
|
||||
$eventDocumentName = Get-BetterDocumentNameFromPrintServiceEvents -Owner $owner -PrinterName $printerName
|
||||
if ($eventDocumentName) {
|
||||
$documentName = $eventDocumentName
|
||||
|
||||
@@ -101,6 +101,7 @@ Get-ActivityWatchExecutableMap -InstallRoot $effectiveInstallRoot | Out-Null
|
||||
$assetResult = Copy-ActivityWatchCollectorAssets `
|
||||
-CollectorScriptSource (Join-Path $PSScriptRoot 'browser-domains-native-collector.ps1') `
|
||||
-EndpointCollectorScriptSource (Join-Path $PSScriptRoot 'dlp-endpoint-signals-collector.ps1') `
|
||||
-EmailCollectorScriptSource (Join-Path $PSScriptRoot 'email-outbound-collector.ps1') `
|
||||
-FileCollectorScriptSource (Join-Path $PSScriptRoot 'file-operations-collector.ps1') `
|
||||
-SessionCollectorScriptSource (Join-Path $PSScriptRoot 'worktime-session-collector.ps1') `
|
||||
-ExampleRulesSource (Join-Path $PSScriptRoot 'web-category-rules.example.json') `
|
||||
@@ -122,6 +123,7 @@ $config = New-ActivityWatchDeploymentConfig `
|
||||
-LogsRoot $effectiveLogsRoot `
|
||||
-CollectorScript $effectiveCollector `
|
||||
-EndpointCollectorScript $effectiveEndpointCollector `
|
||||
-EmailCollectorScript $assetResult.EmailCollectorScript `
|
||||
-FileCollectorScript $effectiveFileCollector `
|
||||
-SessionCollectorScript $effectiveSessionCollector `
|
||||
-RulesPath $effectiveRules `
|
||||
|
||||
@@ -42,6 +42,7 @@ Source: "..\..\migrate-awatch-rus-paths.ps1"; DestDir: "{app}\windows"; Flags: i
|
||||
Source: "..\..\worktime-session-collector.ps1"; DestDir: "{app}\windows"; Flags: ignoreversion
|
||||
Source: "..\..\browser-domains-native-collector.ps1"; DestDir: "{app}\windows"; Flags: ignoreversion
|
||||
Source: "..\..\dlp-endpoint-signals-collector.ps1"; DestDir: "{app}\windows"; Flags: ignoreversion
|
||||
Source: "..\..\email-outbound-collector.ps1"; DestDir: "{app}\windows"; Flags: ignoreversion
|
||||
Source: "..\..\web-category-rules.example.json"; DestDir: "{app}\windows"; Flags: ignoreversion
|
||||
Source: "..\..\dlp-policy.example.json"; DestDir: "{app}\windows"; Flags: ignoreversion
|
||||
; Offline payload (optional): place ZIP into windows/installkit/innosetup/payload/ before compiling.
|
||||
|
||||
Reference in New Issue
Block a user