PowerShell · 26.12.2022

Кто, кому, когда (Часть II)

Здесь я уже писал о логах почтового сервера, но там вывод предполагался в файл csv. Все посты о Exchange можно найти по этому тегу.

В продолжение темы, выкладываю скрипт, с помощью которого можно сохранить лог почтового сервера Exchange за определённую дату. Скрипт предоставляет интерактивный выбор даты в виде формы с календарем и двумя клавишами. Если отменить выбор даты — консоль будет закрыта.

Окно с выбором даты

Метод вывода формы с календарём я подсмотрел здесь и немного его подрихтовал для косметических нужд.

В итоге получилась вот такая красота:

## Заголовок окна консоли ##
[System.Console]::Title = "Логи почтового сервера"

## Имя почтового сервера (IP не указывать) ##
Write-Host "Рекомендуется указывать DNS имя почтового сервера Exchange!" -ForegroundColor Yellow -BackgroundColor Black
Write-Host
$server = Read-Host "Имя почтового сервера Exchange"
$ping = Test-Connection -ComputerName $server -Count 1 -Quiet

## Header HTML ##
$header = @"
<title>Журнал с сервера $server</title>
<style>
  TABLE {border-width: 1px; border-style: solid; border-color: black; border-collapse: collapse; margin-left:auto; margin-right:auto;}
  TH {border-width: 1px; padding: 3px; border-style: solid; border-color: black; background-color: #87cefa;} 
  TD {border-width: 1px; padding: 3px; border-style: solid; border-color: black;}
  H1 {text-align: center;}
</style>
"@

## Получение текущих даты/времени ##
$getdate = [DateTime]::Now.ToString("yyyyMMdd-HHmmss")

## Подключение к серверу ##
if ($ping) 
{
    $session = New-PSSession -ConfigurationName Microsoft.Exchange -ConnectionUri http://$server/PowerShell/ -Authentication Kerberos
    Import-PSSession $session

    ## Открытие формы выбора даты ##
    Add-Type -AssemblyName System.Windows.Forms
    Add-Type -AssemblyName System.Drawing
	
    $form = New-Object Windows.Forms.Form -Property @{
    StartPosition = [Windows.Forms.FormStartPosition]::CenterScreen
	FormBorderStyle = [Windows.Forms.FormBorderStyle]::FixedSingle
    Size          = New-Object Drawing.Size 243, 230
    Text          = 'Выбор даты'
	AutoSize 	  = $true
	MaximizeBox   = $false
	MinimizeBox   = $false
    Topmost       = $true }

    $calendar = New-Object Windows.Forms.MonthCalendar -Property @{
    ShowTodayCircle   = $false
    MaxSelectionCount = 1 }
    
    $form.Controls.Add($calendar)
    $okButton    = New-Object Windows.Forms.Button -Property @{
    Location     = New-Object Drawing.Point 38, 165
    Size         = New-Object Drawing.Size 75, 23
    Text         = 'OK'
    DialogResult = [Windows.Forms.DialogResult]::OK }
    $form.AcceptButton = $okButton
    $form.Controls.Add($okButton)

    $cancelButton = New-Object Windows.Forms.Button -Property @{
    Location      = New-Object Drawing.Point 113, 165
    Size          = New-Object Drawing.Size 75, 23
    Text          = 'Отмена'
    DialogResult  = [Windows.Forms.DialogResult]::Cancel }
    $form.CancelButton = $cancelButton
    $form.Controls.Add($cancelButton)
    $result = $form.ShowDialog()
    if ($result -eq [Windows.Forms.DialogResult]::OK)
    {
        $date = $calendar.SelectionStart
        $styledate = $date.ToShortDateString()
        $formatdate = $date.ToString("MM/dd/yyyy")
        $begindate = "$formatdate 00:00:00"
        $enddate = "$formatdate 23:59:59"
	Write-Host
        Write-Host "Выбрана дата: $styledate" -ForegroundColor Cyan
    }
	else { exit }
    
    ## Цикл вывода меню ##
    while($true)
    {
        Write-Host
        Write-Host "1. Вывод лога получателя за $styledate" -ForegroundColor Green
        Write-Host "2. Вывод лога отправителя за $styledate" -ForegroundColor Green
        Write-Host "3. Вывод лога отправителя и получателя за $styledate" -ForegroundColor Green
        Write-Host "4. Завершить работу скрипта" -ForegroundColor Red
        Write-Host

        $choice = Read-Host "Выберите вариант"
        Write-Host

        Switch($choice)
        {
            ## Вывод лога получателя ##
            1{
                $filtermail = Read-Host "Почтовый ящик получателя"
                $path = [Environment]::GetFolderPath("Desktop") + "\$getdate-$server-$filtermail-archive-$styledate.html"
                Get-MessageTrackingLog -Start $begindate -End $enddate -ResultSize unlimited |
                Where-Object {[string]$_.recipients -like "$filtermail"} | 
                Sort-Object Timestamp | ## <== Сортировка по дате/времени
                Select-Object @{Label="Дата/Время события"; Expression={$_.Timestamp}}, `
                @{Label="Событие"; Expression={$_.EventId}}, `
                @{Label="Источник"; Expression={$_.Source}}, `
                @{Label="Отправитель"; Expression={$_.Sender}}, `
                @{Label="Получатель"; Expression={$_.Recipients}}, `
                @{Label="Тема письма"; Expression={$_.MessageSubject}} |
                ConvertTo-Html -Head $header `
                -PreContent "<H1>Журнал получения почтового ящика $filtermail за $styledate</H1>" |
                Out-File $path -Verbose
            }

            ## Вывод лога отправителя ##
            2{
                $filtermail = Read-Host "Почтовый ящик отправителя"
                $path = [Environment]::GetFolderPath("Desktop") + "\$getdate-$server-$filtermail-archive-$styledate.html"
                Get-MessageTrackingLog -Start $begindate -End $enddate -ResultSize unlimited |
                Where-Object {[string]$_.sender -like "$filtermail"} | 
                Sort-Object Timestamp | ## <== Сортировка по дате/времени
                Select-Object @{Label="Дата/Время события"; Expression={$_.Timestamp}}, `
                @{Label="Событие"; Expression={$_.EventId}}, `
                @{Label="Источник"; Expression={$_.Source}}, `
                @{Label="Отправитель"; Expression={$_.Sender}}, `
                @{Label="Получатель"; Expression={$_.Recipients}}, `
                @{Label="Тема письма"; Expression={$_.MessageSubject}} |
                ConvertTo-Html -Head $header `
                -PreContent "<H1>Журнал отправки почтового ящика $filtermail за $styledate</H1>" |
                Out-File $path -Verbose                
            }

            ## Вывод лога отправителя и получателя ##
            3{
                $sender = Read-Host "Почтовый ящик отправителя"
                $recipient = Read-Host "Почтовый ящик получателя"
                $path = [Environment]::GetFolderPath("Desktop") + "\$getdate-$server-$sender-TO-$recipient-archive-$styledate.html"

                Get-MessageTrackingLog -Start $begindate -End $enddate -ResultSize unlimited `
                -Sender $sender -Recipients $recipient |
                Sort-Object Timestamp | ## <== Сортировка по дате/времени
                Select-Object @{Label="Дата/Время события"; Expression={$_.Timestamp}}, `
                @{Label="Событие"; Expression={$_.EventId}}, `
                @{Label="Источник"; Expression={$_.Source}}, `
                @{Label="Отправитель"; Expression={$_.Sender}}, `
                @{Label="Получатель"; Expression={$_.Recipients}}, `
                @{Label="Тема письма"; Expression={$_.MessageSubject}} |
                ConvertTo-Html -Head $header `
                -PreContent "<H1>Журнал отправки от отправителя $sender получателю $recipient за $styledate</H1>" |
                Out-File $path -Verbose 
            }

            ## Завершить работу скрипта ##
            4{ Exit }

            ## Неверный выбор ##
            default { Write-Host "Неверный выбор. Попробуйте снова." -ForegroundColor Red }
        }
    }
}
else
{
    Write-Host "Сервер $server недоступен!" -ForegroundColor Red
    Write-Host
    Read-Host "Нажмите любую клавишу для выхода..."
}

Первую часть поста читать здесь.