Пришла задачка получить данные о входящих письмах с одного из ящиков Exchange. Использование Get-MessageTrackingLog не помогло, так как период оказался слишком большой, часть логов уже удалена. Однако сами письма во входящих лежат, можно получить информацию напрямую из ящика.
Для этого подключаем ящик к своему Outlook, дожидаемся синхронизации. Писем много, вручную не обработаешь, дальше действуем через PowerShell. При этом Outlook должен быть запущен. Более того, когда мы через скрипт будем запрашивать данные, Outlook попросит подтверждение действия. Это происходит при отключенном или устаревшем антивирусе.
Проверка, запущен ли Outlook.
Get-Process | where { $_.Name -eq "OUTLOOK" }
Если по каким-то причинам вы не можете или не хотите запускать Outlook вручную, то можно запустить Outlook в фоновом режиме.
$OutlookProc = ( Get-Process | where { $_.Name -eq "OUTLOOK" } )
if ( $OutlookProc -eq $null ) { Start-Process outlook.exe -WindowStyle Hidden; Start-Sleep -Seconds 5 }
Создаём экземпляр доступа к Outlook.
Add-Type -Assembly "Microsoft.Office.Interop.Outlook"
$Outlook = New-Object -ComObject Outlook.Application
Для доступа к содержимому ящика используется пространство имен протокола MAPI.
$namespace = $Outlook.GetNameSpace("MAPI")
Вывести список папок в первом ящике.
$NameSpace.Folders.Item(1).Folders | FT FolderPath
Ящиков может быть много, так что можно определить нужный по очереди.
$NameSpace.Folders.Item(2).Folders | FT FolderPath
$NameSpace.Folders.Item(3).Folders | FT FolderPath
$NameSpace.Folders.Item(4).Folders | FT FolderPath
...
Аналогично можно вычислить нужную папку в ящике.
$NameSpace.Folders.Item(1).Folders.Item(2) | FT FolderPath
Можно вывести список папок в древовидном виде и посчитать количество писем в каждой папке.
Function Listfolders
{
param($Folders, $Indent)
ForEach ($Folder in $Folders | sort-object name)
{
write-host $Indent$($Folder.Name)" ("$($Folder.Items.Count)")"
Listfolders $Folder.Folders $Indent" "
}
}
ListFolders $namespace.Folders ""
Если у нас один ящик, то можно определить папку для входящих, папка может называться Inbox или Входящие, это зависит от региональных настроек.
$inbox = $namespace.GetDefaultFolder([Microsoft.Office.Interop.Outlook.OlDefaultFolders]::olFolderInbox)
Если ящиков много, или требуется другая папка, то указываем целевую папку, которую мы определили ранее.
$inbox = $NameSpace.Folders.Item(1).Folders.Item(2)
Вывести список писем в выбранной папке, выбираем поля: отправитель, получатель, тема письма, размер, дата получения.
$inbox.Items | ft SenderEmailAddress, To, Subject, Size, ReceivedTime
Выгрузить в CSV.
$inbox.Items | select-object SenderEmailAddress, To, Subject, Size, ReceivedTime | Export-Csv -Path "C:\tmpext\5.csv" -Encoding Default -Delimiter ";"
Полученную задачу я выполнил.
Ещё полезный код с просторов сети
Все письма сегодня от указанного отправителя:
$currentDate = Get-Date -Format "MM/dd/yyyy"
$inbox.Items | Where-Object { $_.ReceivedTime -like "*$currentDate*" -and $_.SenderEmailAddress -eq "user@examle.com"}
Текст последнего письма:
$inbox.Items($inbox.Items.Count) | select SenderEmailAddress, subject, Body, HTMLBody | fl
Сохранить первое вложение последнего письма на диск:
$email= $inbox.Items($inbox.Items.Count)
if ($Email.Attachments.Count -gt 0) {
$Attachment = $Email.Attachments.Item(1)
$Attachment.SaveAsFile("C:\Downloads\$($Email.Attachments.Item(1).FileName)")
}
Удалить из ящика последнее полученное письмо:
$email= $inbox.Items($inbox.Items.Count)
$Email.Delete()
Способы применения работы с Outlook через PowerShell достаточно обширные. Проверка ящика по расписания, отправка писем в телеграм, формирование отчётов, автоматизация работы с почтой. Всё зависит от ваших требований и фантазии.