fix: Exchange monitor encoding for PS 5.1 (v1.6.3)

ASCII runtime strings in Exchange-MailSecurity and Notify-Common avoid parser errors when scripts are copied without UTF-8 BOM. Deploy copies .ps1 to ProgramData with UTF-8 BOM via Copy-ScriptFileWithUtf8Bom.
This commit is contained in:
2026-05-22 14:57:35 +10:00
parent 7c13c96622
commit 872df98a2c
5 changed files with 101 additions and 82 deletions
+20 -2
View File
@@ -1,4 +1,4 @@
<#
<#
.SYNOPSIS
Deploy domain monitor scripts (Exchange / AD) from share to ProgramData.
.PARAMETER Target
@@ -47,6 +47,20 @@ function Write-TextFileUtf8Bom {
[System.IO.File]::WriteAllText($Path, $Text, $Utf8Bom)
}
function Copy-ScriptFileWithUtf8Bom {
param(
[Parameter(Mandatory = $true)][string]$SourcePath,
[Parameter(Mandatory = $true)][string]$DestPath
)
$raw = [System.IO.File]::ReadAllBytes($SourcePath)
$utf8NoBom = New-Object System.Text.UTF8Encoding $false
$text = $utf8NoBom.GetString($raw)
if ($text.Length -gt 0 -and [int][char]$text[0] -eq 0xFEFF) {
$text = $text.Substring(1)
}
[System.IO.File]::WriteAllText($DestPath, $text, $Utf8Bom)
}
function Resolve-SourceShareRoot {
if (-not [string]::IsNullOrWhiteSpace($SourceShareRoot)) {
return [System.IO.Path]::GetFullPath($SourceShareRoot.TrimEnd('\'))
@@ -128,7 +142,11 @@ foreach ($name in $filesToCopy) {
Write-DeployLog "WhatIf: copy $src -> $dst"
continue
}
Copy-Item -LiteralPath $src -Destination $dst -Force
if ($name -like '*.ps1') {
Copy-ScriptFileWithUtf8Bom -SourcePath $src -DestPath $dst
} else {
Copy-Item -LiteralPath $src -Destination $dst -Force
}
Write-DeployLog "Copied: $name"
}
+71 -70
View File
@@ -1,4 +1,4 @@
<#
<#
.SYNOPSIS
Мониторинг Exchange: очереди транспорта, пересылка на внешние адреса (Inbox rules + mailbox forwarding + transport rules).
.DESCRIPTION
@@ -25,7 +25,7 @@ $ErrorActionPreference = 'Stop'
# КОНФИГУРАЦИЯ
# ============================================
$ScriptVersion = '1.6.1'
$ScriptVersion = '1.6.3'
$script:InstallRoot = [System.IO.Path]::GetFullPath("$env:ProgramData\RDP-login-monitor")
$script:CanonicalScriptName = 'Exchange-MailSecurity.ps1'
$LogFile = Join-Path $script:InstallRoot 'Logs\exchange_mail_security.log'
@@ -172,7 +172,7 @@ function Register-ExchangeMonitorScheduledTasks {
& $schtasksExe /Run /TN $script:ScheduledTaskWatchdog 2>&1 | Out-Null
$ErrorActionPreference = 'Stop'
Write-ExchLog "InstallTasks: зарегистрированы $($script:ScheduledTaskQueues), $($script:ScheduledTaskInbox), $($script:ScheduledTaskWatchdog)"
Write-ExchLog "InstallTasks: registered $($script:ScheduledTaskQueues), $($script:ScheduledTaskInbox), $($script:ScheduledTaskWatchdog)"
}
if ($Watchdog) { $Mode = 'Watchdog' }
@@ -183,7 +183,7 @@ if (-not (Test-Path -LiteralPath $notifyPath)) {
$notifyPath = Join-Path (Split-Path -Parent (Get-ExchangeMonitorScriptPath)) 'Notify-Common.ps1'
}
if (-not (Test-Path -LiteralPath $notifyPath)) {
Write-Host "Не найден Notify-Common.ps1 рядом с $script:InstallRoot"
Write-Host "Notify-Common.ps1 not found near $script:InstallRoot"
exit 1
}
. $notifyPath
@@ -200,25 +200,26 @@ if ($TelegramChatID -eq '<TELEGRAM_CHAT_ID>') { $TelegramChatID = '' }
function Send-ExchangeInstallNotification {
$scope = Get-ExchangeInboxScanScopeLabel
$vipNote = if ($VipMailboxesOnly) { "VIP: да ($scope)" } else { 'VIP: нет (полный скан)' }
$msg = "<b>✅ Exchange Mail Security установлен</b>`r`n"
$msg += "🖥️ $(ConvertTo-TelegramHtml $env:COMPUTERNAME) | v$ScriptVersion`r`n"
$msg += "📢 Каналы: $(ConvertTo-TelegramHtml (Get-NotifyChainHuman))`r`n"
$msg += "📬 Inbox/пересылка: $vipNote`r`n"
$msg += "📋 Очереди: порог $QueueMessageCountThreshold | Inbox 02:00 | Queues /10 мин`r`n"
$msg += "🛡️ Первый скан: $(if ($SuppressAlertsOnFirstBaselineRun) { 'baseline без всплеска алертов' } else { 'алерт по всем находкам' })"
$vipNote = if ($VipMailboxesOnly) { "VIP on ($scope)" } else { 'VIP off (full scan)' }
$firstScan = if ($SuppressAlertsOnFirstBaselineRun) { 'baseline, no alert flood on first run' } else { 'alert on all findings' }
$msg = "<b>Exchange Mail Security installed</b>`r`n"
$msg += "Host: $(ConvertTo-TelegramHtml $env:COMPUTERNAME) | v$ScriptVersion`r`n"
$msg += "Notify: $(ConvertTo-TelegramHtml (Get-NotifyChainHuman))`r`n"
$msg += "Inbox/forward: $vipNote`r`n"
$msg += "Queues threshold: $QueueMessageCountThreshold | Inbox 02:00 | Queues every 10 min`r`n"
$msg += "First scan: $firstScan"
Send-MonitorNotification -Message $msg -EmailSubject 'Exchange Mail Security: install' | Out-Null
}
if ($InstallTasks) {
if (-not (Test-RunningElevated)) {
Write-Host 'InstallTasks: нужны права администратора.'
Write-Host 'InstallTasks: run as Administrator.'
exit 1
}
Register-ExchangeMonitorScheduledTasks
if ((Test-NotifyTelegramConfigured) -or (Test-NotifyEmailConfigured)) {
Send-ExchangeInstallNotification
Write-ExchLog 'InstallTasks: отправлено уведомление об установке'
Write-ExchLog 'InstallTasks: install notification sent'
}
exit 0
}
@@ -269,7 +270,7 @@ function Import-ExchangeManagementShell {
return $true
}
throw 'Не удалось загрузить Exchange Management Shell (snap-in / RemoteExchange / укажите $ExchangeServerFqdn).'
throw 'Failed to load Exchange Management Shell (snap-in / RemoteExchange / set $ExchangeServerFqdn).'
}
# ============================================
@@ -367,12 +368,12 @@ function Test-MailboxInVipScope {
function Get-ExchangeInboxScanScopeLabel {
if (-not $VipMailboxesOnly) {
if ($MaxMailboxesPerRun -gt 0) { return "все ящики (лимит $MaxMailboxesPerRun)" }
return 'все ящики'
if ($MaxMailboxesPerRun -gt 0) { return "all mailboxes (limit $MaxMailboxesPerRun)" }
return 'all mailboxes'
}
$n = @($VipMailboxes | Where-Object { $_ }).Count
$p = @($VipMailboxPatterns | Where-Object { $_ }).Count
return "VIP: список=$n, шаблонов=$p"
return "VIP list=$n patterns=$p"
}
# ============================================
@@ -416,30 +417,30 @@ function Format-ForwardingFindingMessage {
$hSev = ConvertTo-TelegramHtml $Finding.Severity
$hostName = ConvertTo-TelegramHtml $env:COMPUTERNAME
$msg = "<b>📧 Exchange: пересылка на внешний адрес</b>`r`n"
$msg += "🖥️ Сервер: $hostName`r`n"
$msg += "📋 Тип: $hType`r`n"
$msg += "📬 Ящик: $hMb`r`n"
$msg = "<b>Exchange: external forward</b>`r`n"
$msg += "Host: $hostName`r`n"
$msg += "Type: $hType`r`n"
$msg += "Mailbox: $hMb`r`n"
if (-not [string]::IsNullOrWhiteSpace($Finding.RuleName)) {
$msg += "📎 Правило: $hRule`r`n"
$msg += "Rule: $hRule`r`n"
}
$msg += "➡️ Куда: $hTarget (внешний)`r`n"
$msg += "⚠️ Важность: $hSev`r`n"
$msg += "Target: $hTarget (external)`r`n"
$msg += "Severity: $hSev`r`n"
if ($Finding.Extra.ContainsKey('Enabled')) {
$msg += "✅ Включено: $(ConvertTo-TelegramHtml ([string]$Finding.Extra['Enabled']))`r`n"
$msg += "Enabled: $(ConvertTo-TelegramHtml ([string]$Finding.Extra['Enabled']))`r`n"
}
if ($Finding.Extra.ContainsKey('DeleteMessage')) {
$msg += "🗑️ DeleteMessage: $(ConvertTo-TelegramHtml ([string]$Finding.Extra['DeleteMessage']))`r`n"
$msg += "DeleteMessage: $(ConvertTo-TelegramHtml ([string]$Finding.Extra['DeleteMessage']))`r`n"
}
if ($Finding.Extra.ContainsKey('MarkAsRead')) {
$msg += "👁️ MarkAsRead: $(ConvertTo-TelegramHtml ([string]$Finding.Extra['MarkAsRead']))`r`n"
$msg += "MarkAsRead: $(ConvertTo-TelegramHtml ([string]$Finding.Extra['MarkAsRead']))`r`n"
}
if ($Finding.Extra.ContainsKey('DeliverToMailboxAndForward')) {
$msg += "📤 DeliverToMailboxAndForward: $(ConvertTo-TelegramHtml ([string]$Finding.Extra['DeliverToMailboxAndForward']))`r`n"
$msg += "DeliverToMailboxAndForward: $(ConvertTo-TelegramHtml ([string]$Finding.Extra['DeliverToMailboxAndForward']))`r`n"
}
if ($Finding.Extra.ContainsKey('Property')) {
$msg += "🔀 Поле правила: $(ConvertTo-TelegramHtml ([string]$Finding.Extra['Property']))`r`n"
$msg += "Rule property: $(ConvertTo-TelegramHtml ([string]$Finding.Extra['Property']))`r`n"
}
return $msg
@@ -455,7 +456,7 @@ function Get-ForwardingBaseline {
if ($null -ne $raw.FindingIds) { $ids = @($raw.FindingIds) }
return @{ FindingIds = $ids; LastScanUtc = $raw.LastScanUtc }
} catch {
Write-ExchLog "Baseline: не прочитан ($($_.Exception.Message))"
Write-ExchLog "Baseline: read failed ($($_.Exception.Message))"
return @{ FindingIds = @(); LastScanUtc = $null }
}
}
@@ -499,7 +500,7 @@ function Save-QueueAlertState {
function Invoke-ExchangeQueueScan {
Import-ExchangeManagementShell
Write-ExchLog "Queues: порог MessageCount > $QueueMessageCountThreshold"
Write-ExchLog "Queues: threshold MessageCount > $QueueMessageCountThreshold"
$queues = @(Get-Queue -ErrorAction Stop)
$hot = @($queues | Where-Object { $_.MessageCount -gt $QueueMessageCountThreshold })
@@ -507,7 +508,7 @@ function Invoke-ExchangeQueueScan {
$now = Get-Date
if ($hot.Count -eq 0) {
Write-ExchLog "Queues: OK (всего $($queues.Count), выше порога 0)"
Write-ExchLog "Queues: OK (total $($queues.Count), above threshold 0)"
Write-TextFileUtf8Bom -Path $QueuesHeartbeatFile -Text (Get-Date -Format 'yyyy-MM-dd HH:mm:ss')
return
}
@@ -518,21 +519,21 @@ function Invoke-ExchangeQueueScan {
if ($state.ContainsKey($qKey)) { $lastAlert = $state[$qKey] }
$cooldownOk = ($null -eq $lastAlert) -or (((Get-Date).ToUniversalTime() - $lastAlert.ToUniversalTime()).TotalSeconds -ge $QueueAlertCooldownSeconds)
if (-not $cooldownOk) {
Write-ExchLog "Queues: $($q.Identity) count=$($q.MessageCount) cooldown, пропуск алерта"
Write-ExchLog "Queues: $($q.Identity) count=$($q.MessageCount) - cooldown, skip alert"
continue
}
$hId = ConvertTo-TelegramHtml $q.Identity
$msg = "<b>📬 Exchange: очередь транспорта</b>`r`n"
$msg += "🖥️ Сервер: $(ConvertTo-TelegramHtml $env:COMPUTERNAME)`r`n"
$msg += "📋 Очередь: $hId`r`n"
$msg += "📊 Сообщений: <b>$($q.MessageCount)</b> (порог $QueueMessageCountThreshold)`r`n"
$msg += "📌 Статус: $(ConvertTo-TelegramHtml ([string]$q.Status))`r`n"
$msg += "🕐 $(ConvertTo-TelegramHtml (Get-Date -Format 'dd.MM.yyyy HH:mm:ss'))"
$msg = "<b>Exchange: transport queue</b>`r`n"
$msg += "Host: $(ConvertTo-TelegramHtml $env:COMPUTERNAME)`r`n"
$msg += "Queue: $hId`r`n"
$msg += "Messages: <b>$($q.MessageCount)</b> (threshold $QueueMessageCountThreshold)`r`n"
$msg += "Status: $(ConvertTo-TelegramHtml ([string]$q.Status))`r`n"
$msg += "Time: $(ConvertTo-TelegramHtml (Get-Date -Format 'dd.MM.yyyy HH:mm:ss'))"
if (Send-MonitorNotification -Message $msg -EmailSubject 'Exchange: transport queue') {
$state[$qKey] = $now
Write-ExchLog "Queues: алерт отправлен для $($q.Identity)"
Write-ExchLog "Queues: alert sent for $($q.Identity)"
}
}
@@ -549,7 +550,7 @@ function Get-MailboxListForScan {
if ($VipMailboxesOnly) {
if (-not (Test-VipMailboxScopeConfigured)) {
throw 'VipMailboxesOnly=$true, но VipMailboxes и VipMailboxPatterns пусты — задайте список в exchange_monitor.settings.ps1'
throw 'VipMailboxesOnly=$true but VipMailboxes and VipMailboxPatterns are empty - set them in exchange_monitor.settings.ps1'
}
$set = [System.Collections.Generic.HashSet[string]]::new([StringComparer]::OrdinalIgnoreCase)
foreach ($v in $VipMailboxes) {
@@ -611,7 +612,7 @@ function Scan-MailboxForwardingSettings {
if (-not (Test-IsExternalSmtpAddress -SmtpAddress $t -InternalDomains $InternalDomains -WhitelistDomains $ExternalDomainWhitelist)) {
continue
}
$sev = 'Высокая'
$sev = 'High'
$Findings.Add((New-ForwardingFinding -FindingType 'MailboxForwarding' -Mailbox $primary `
-RuleName '' -TargetAddress $t -Severity $sev -Extra @{
DeliverToMailboxAndForward = [string]$mb.DeliverToMailboxAndForward
@@ -640,11 +641,11 @@ function Add-InboxRuleExternalForwardFindings {
if (-not (Test-IsExternalSmtpAddress -SmtpAddress $addr -InternalDomains $InternalDomains -WhitelistDomains $ExternalDomainWhitelist)) {
continue
}
$sev = 'Высокая'
$sev = 'High'
if (-not $Rule.Enabled) {
$sev = 'Средняя (правило отключено)'
$sev = 'Medium (rule disabled)'
} elseif ($Rule.DeleteMessage -or $Rule.MarkAsRead) {
$sev = 'Критическая'
$sev = 'Critical'
}
$Findings.Add((New-ForwardingFinding -FindingType 'InboxRule' -Mailbox $Mailbox `
-RuleName [string]$Rule.Name -TargetAddress $addr -Severity $sev -Extra @{
@@ -697,7 +698,7 @@ function Scan-TransportRulesExternalForward {
continue
}
$Findings.Add((New-ForwardingFinding -FindingType 'TransportRule' -Mailbox '(transport)' `
-RuleName [string]$rule.Name -TargetAddress $addr -Severity 'Высокая' -Extra @{})) | Out-Null
-RuleName [string]$rule.Name -TargetAddress $addr -Severity 'High' -Extra @{})) | Out-Null
}
}
}
@@ -715,20 +716,20 @@ function Send-ExchangeInboxScanSummary {
if (-not $SendInboxScanSummary) { return }
$hHost = ConvertTo-TelegramHtml $env:COMPUTERNAME
$msg = "<b>📊 Exchange: итог скана пересылки</b>`r`n"
$msg += "🖥️ $hHost | v$ScriptVersion`r`n"
$msg += "🔎 Охват: $(ConvertTo-TelegramHtml $ScopeLabel)`r`n"
$msg += "📬 Ящиков (Inbox rules): $MailboxCount`r`n"
$msg += "📋 Находок всего: $TotalFindings | новых: $NewFindings`r`n"
$msg = "<b>Exchange: forwarding scan summary</b>`r`n"
$msg += "Host: $hHost | v$ScriptVersion`r`n"
$msg += "Scope: $(ConvertTo-TelegramHtml $ScopeLabel)`r`n"
$msg += "Mailboxes (Inbox rules): $MailboxCount`r`n"
$msg += "Findings total: $TotalFindings | new: $NewFindings`r`n"
if ($FirstBaselineSeeded) {
$msg += "<i>Первый baseline: алерты по существующим пересылкам подавлены (SuppressAlertsOnFirstBaselineRun).</i>`r`n"
$msg += "<i>First baseline: existing forwards suppressed (SuppressAlertsOnFirstBaselineRun).</i>`r`n"
}
Send-MonitorNotification -Message $msg -EmailSubject 'Exchange: scan summary' | Out-Null
}
function Invoke-ExchangeInboxAndForwardingScan {
$scopeLabel = Get-ExchangeInboxScanScopeLabel
Write-ExchLog "Inbox/Forwarding scan v$ScriptVersion; охват: $scopeLabel; каналы: $(Get-NotifyChainHuman)"
Write-ExchLog "Inbox/Forwarding scan v$ScriptVersion; scope: $scopeLabel; notify: $(Get-NotifyChainHuman)"
Import-ExchangeManagementShell
$internalDomains = Get-InternalAcceptedDomainNames
Write-ExchLog "Accepted domains (internal): $($internalDomains -join ', ')"
@@ -741,17 +742,17 @@ function Invoke-ExchangeInboxAndForwardingScan {
if ($ScanInboxRules) {
$mailboxes = @(Get-MailboxListForScan)
$mailboxCount = $mailboxes.Count
Write-ExchLog "Inbox rules: ящиков к скану: $mailboxCount ($scopeLabel)"
Write-ExchLog "Inbox rules: mailboxes to scan: $mailboxCount ($scopeLabel)"
$idx = 0
foreach ($mb in $mailboxes) {
$idx++
try {
Scan-InboxRulesForMailbox -Mailbox $mb -InternalDomains $internalDomains -Findings $findings
} catch {
Write-ExchLog "Inbox rules: ошибка $mb : $($_.Exception.Message)"
Write-ExchLog "Inbox rules: error $mb : $($_.Exception.Message)"
}
if ($idx % $InboxScanBatchSize -eq 0) {
Write-ExchLog "Inbox rules: обработано $idx / $($mailboxes.Count)"
Write-ExchLog "Inbox rules: processed $idx / $($mailboxes.Count)"
Start-Sleep -Seconds $InboxScanBatchDelaySeconds
}
}
@@ -765,14 +766,14 @@ function Invoke-ExchangeInboxAndForwardingScan {
foreach ($id in $baseline.FindingIds) { $null = $prevSet.Add($id) }
$newFindings = @($findings | Where-Object { -not $prevSet.Contains($_.Id) })
Write-ExchLog "Forwarding: всего $($findings.Count), новых $($newFindings.Count)"
Write-ExchLog "Forwarding: total $($findings.Count), new $($newFindings.Count)"
$isFirstBaseline = ($baseline.FindingIds.Count -eq 0) -and ($findings.Count -gt 0)
$firstBaselineSeeded = $false
$toAlert = if ($AlertOnlyOnNewForwardingFindings) { $newFindings } else { @($findings) }
if ($SuppressAlertsOnFirstBaselineRun -and $isFirstBaseline) {
Write-ExchLog 'Forwarding: первый baseline — алерты по находкам подавлены (SuppressAlertsOnFirstBaselineRun)'
Write-ExchLog 'Forwarding: first baseline - alerts suppressed (SuppressAlertsOnFirstBaselineRun)'
$firstBaselineSeeded = $true
$toAlert = @()
}
@@ -782,17 +783,17 @@ function Invoke-ExchangeInboxAndForwardingScan {
}
if ($findings.Count -eq 0 -and $NotifyWhenForwardingScanClean) {
$summary = "<b>Exchange: скан пересылки</b>`r`nВнешняя пересылка (Inbox / mailbox / transport) не обнаружена.`r`n🖥️ $(ConvertTo-TelegramHtml $env:COMPUTERNAME)"
$summary = "<b>Exchange: forwarding scan</b>`r`nNo external forward (Inbox / mailbox / transport).`r`nHost: $(ConvertTo-TelegramHtml $env:COMPUTERNAME)"
Send-MonitorNotification -Message $summary -EmailSubject 'Exchange: forward scan OK' | Out-Null
} elseif ($newFindings.Count -eq 0 -and $AlertOnlyOnNewForwardingFindings) {
Write-ExchLog 'Forwarding: изменений нет (только известные находки в baseline)'
Write-ExchLog 'Forwarding: no changes (known findings in baseline only)'
}
Save-ForwardingBaseline -FindingIds $allIds
Write-TextFileUtf8Bom -Path $InboxHeartbeatFile -Text (Get-Date -Format 'yyyy-MM-dd HH:mm:ss')
Send-ExchangeInboxScanSummary -TotalFindings $findings.Count -NewFindings $newFindings.Count `
-MailboxCount $mailboxCount -FirstBaselineSeeded $firstBaselineSeeded -ScopeLabel $scopeLabel
Write-ExchLog 'Inbox/Forwarding scan завершён'
Write-ExchLog 'Inbox/Forwarding scan finished'
}
# ============================================
@@ -816,12 +817,12 @@ function Invoke-ExchangeWatchdog {
$qAge = Get-HeartbeatAgeSeconds -Path $QueuesHeartbeatFile
if ($qAge -gt $QueuesHeartbeatStaleSeconds) {
$issues.Add("Очереди: нет успешного скана > $([int]$qAge) с (порог $QueuesHeartbeatStaleSeconds с)") | Out-Null
$issues.Add("Queues: no successful scan > $([int]$qAge) s (threshold $QueuesHeartbeatStaleSeconds s)") | Out-Null
}
$iAge = Get-HeartbeatAgeSeconds -Path $InboxHeartbeatFile
if ($iAge -gt $InboxHeartbeatStaleSeconds) {
$issues.Add("Inbox/Forwarding: нет успешного скана > $([int]$iAge) с (порог $InboxHeartbeatStaleSeconds с)") | Out-Null
$issues.Add("Inbox/Forwarding: no successful scan > $([int]$iAge) s (threshold $InboxHeartbeatStaleSeconds s)") | Out-Null
}
if ($issues.Count -eq 0) {
@@ -829,14 +830,14 @@ function Invoke-ExchangeWatchdog {
exit 0
}
$msg = "<b>⚠️ Exchange Mail Security: watchdog</b>`r`n"
$msg += "🖥️ $(ConvertTo-TelegramHtml $env:COMPUTERNAME)`r`n"
$msg = "<b>Exchange Mail Security: watchdog</b>`r`n"
$msg += "Host: $(ConvertTo-TelegramHtml $env:COMPUTERNAME)`r`n"
foreach ($iss in $issues) {
$msg += " $(ConvertTo-TelegramHtml $iss)`r`n"
$msg += "- $(ConvertTo-TelegramHtml $iss)`r`n"
}
Send-MonitorNotification -Message $msg -EmailSubject 'Exchange monitor: watchdog' | Out-Null
Write-WdLog "Watchdog: отправлено оповещение ($($issues.Count) проблем)"
Write-WdLog "Watchdog: alert sent ($($issues.Count) issue(s))"
exit 1
}
@@ -845,7 +846,7 @@ function Invoke-ExchangeWatchdog {
# ============================================
if (-not (Test-RunningElevated)) {
Write-ExchLog 'ПРЕДУПРЕЖДЕНИЕ: скрипт без прав администратора — EMS/задачи могут не работать.'
Write-ExchLog 'WARNING: not running elevated - EMS/tasks may fail.'
}
Write-ExchLog "=== Exchange-MailSecurity v$ScriptVersion Mode=$Mode ==="
@@ -855,10 +856,10 @@ try {
'Queues' { Invoke-ExchangeQueueScan }
'Inbox' { Invoke-ExchangeInboxAndForwardingScan }
'Watchdog' { Invoke-ExchangeWatchdog }
default { throw "Неизвестный Mode: $Mode" }
default { throw "Unknown Mode: $Mode" }
}
} catch {
Write-ExchLog "ОШИБКА: $($_.Exception.Message)"
Write-ExchLog "ERROR: $($_.Exception.Message)"
if ($_.ScriptStackTrace) { Write-ExchLog $_.ScriptStackTrace }
exit 1
}
+1 -1
View File
@@ -1,4 +1,4 @@
<#
<#
.SYNOPSIS
Register scheduled tasks for domain monitors (Exchange; AD later).
.PARAMETER Target
+8 -8
View File
@@ -1,4 +1,4 @@
<#
<#
.SYNOPSIS
Общие функции уведомлений (Telegram / SMTP) для скриптов RDP-login-monitor.
.DESCRIPTION
@@ -75,7 +75,7 @@ function Get-NotifyOrderChannels {
'^(tg|telegram)$' { 'telegram' }
'^(mail|email|e-mail)$' { 'email' }
default {
Write-NotifyLog "NotifyOrder: неизвестный канал '$part'"
Write-NotifyLog "NotifyOrder: unknown channel '$part'"
$null
}
}
@@ -89,7 +89,7 @@ function Get-NotifyOrderChannels {
function Get-NotifyChainHuman {
$channels = @(Get-NotifyOrderChannels)
if ($channels.Count -eq 0) { return 'нет (ни Telegram, ни SMTP не настроены)' }
if ($channels.Count -eq 0) { return 'none (Telegram and SMTP not configured)' }
$labels = foreach ($ch in $channels) {
switch ($ch) {
'telegram' { 'Telegram' }
@@ -110,7 +110,7 @@ function Send-TelegramMessage {
param([string]$Message)
if (-not (Test-NotifyTelegramConfigured)) {
Write-NotifyLog "Telegram: не задан токен/chat_id"
Write-NotifyLog 'Telegram: token or chat_id missing'
return $false
}
@@ -126,7 +126,7 @@ function Send-TelegramMessage {
$null = Invoke-RestMethod -Uri $uri -Method Post -Body $body -ErrorAction Stop -TimeoutSec 30
return $true
} catch {
Write-NotifyLog "Ошибка отправки в Telegram: $($_.Exception.Message)"
Write-NotifyLog "Telegram send error: $($_.Exception.Message)"
return $false
}
}
@@ -152,7 +152,7 @@ function Send-EmailNotification {
)
if (-not (Test-NotifyEmailConfigured)) {
Write-NotifyLog "Email: SMTP не настроен"
Write-NotifyLog 'Email: SMTP not configured'
return $false
}
@@ -184,7 +184,7 @@ function Send-EmailNotification {
Send-MailMessage @mailParams
return $true
} catch {
Write-NotifyLog "Ошибка отправки Email: $($_.Exception.Message)"
Write-NotifyLog "Email send error: $($_.Exception.Message)"
return $false
}
}
@@ -197,7 +197,7 @@ function Send-MonitorNotification {
$channels = @(Get-NotifyOrderChannels)
if ($channels.Count -eq 0) {
Write-NotifyLog "Оповещение не отправлено: нет каналов"
Write-NotifyLog 'Notification skipped: no channels configured'
return $false
}
+1 -1
View File
@@ -1 +1 @@
1.6.2
1.6.3