В работе системного администратора бывают случаи проведения служебного расследования по деятельности сотрудников компании. Например, когда служба безопасности компании подозревает кого-то из работников в "сливе" информации конкурентам. Обычно в этом случае служба безопасности просит сделать выгрузку почтового ящика сотрудника в файл.
На первом этапе расследования службе безопасности требуется общая информация о деятельности сотрудника: контакты, названия писем, названия файлов на компьютере, распечатка звонков с корпоративного телефона и прочая общая информация.
То есть в случае с почтой полная выгрузка почтового ящика, которая описана в статье Exchange - Выгрузка почтового ящика в PST-файл не подходит. Необходимо просто сформировать таблицу из писем в почтовом ящике, а для этой задачи больше подходят программные средства, чем клиент Outlook и PST-файлы. Например, можно обработать почтовый ящик с помощью PowerShell.
Для подключения к почтовому серверу Exchange из PowerShell используются библиотеки Exchange Web Services Managed API 2.0, которые можно найти на сайте Microsoft. Подробные примеры использования Exchange Web Services (EWS) можно найти в блоге Glen Scales.
Для выгрузки почтового ящика с сервера Exchange в CSV-файл я написал PowerShell-скрипт, который получает письма из папок "Входящие" и "Отправленные", извлекает из писем необходимые поля ("От кого", "Кому", "Тема", "Дата", "Размер") и записывает результат в CSV-таблицу на рабочем столе текущего пользователя.
Итак, текст скрипта:
# Полезные статьи по теме Exchange Web Services # Part 1 http://gsexdev.blogspot.ru/2012/01/ews-managed-api-and-powershell-how-to.html # Part 2 http://gsexdev.blogspot.ru/2012/01/ews-managed-api-and-powershell-how-to_23.html # Part 3 http://gsexdev.blogspot.ru/2012/02/ews-managed-api-and-powershell-how-to.html # Part 4 http://gsexdev.blogspot.ru/2012/02/ews-managed-api-and-powershell-how-to_22.html # Part 5 http://gsexdev.blogspot.ru/2012/05/ews-managed-api-and-powershell-how-to_28.html # Part 6 http://gsexdev.blogspot.ru/2012/03/ews-managed-api-and-powershell-how-to_27.html # Part 7 http://gsexdev.blogspot.ru/2012/04/ews-managed-api-and-powershell-how-to.html # Part 8 http://gsexdev.blogspot.ru/2012/05/ews-managed-api-and-powershell-how-to.html # Part 9 http://gsexdev.blogspot.ru/2012/05/ews-managed-api-and-powershell-how-to_28.html # Part 10 http://gsexdev.blogspot.ru/2012/06/ews-managed-api-and-powershell-how-to.html # Этот скрипт использует Microsoft Exchange Web Services Managed API 2.0 # http://www.microsoft.com/en-us/download/details.aspx?id=35371 # Почтовый ящик для выгрузки # - перед открытием чужого почтового ящика необходимо выдать текущему пользователю полные права на него и # перевойти в сессию почтового сервера $MailboxName = "VBochkarev@domain.com" # Очистка переменной ScriptResult Remove-Variable ScriptResult -ErrorAction SilentlyContinue $ScriptResult = @() # Загрузка библиотек Microsoft Exchange Web Services DLL $DllPath = "C:\Program Files\Microsoft\Exchange\Web Services\2.0\Microsoft.Exchange.WebServices.dll" [void][Reflection.Assembly]::LoadFile($DllPath) # Подключение к серверу Exchange 2010 с текущими правами пользователя $Service = New-Object Microsoft.Exchange.WebServices.Data.ExchangeService ` ([Microsoft.Exchange.WebServices.Data.ExchangeVersion]::Exchange2010) $WindowsIdentity = [System.Security.Principal.WindowsIdentity]::GetCurrent() $SidBind = "LDAP://<SID=" + $WindowsIdentity.user.Value.ToString() + ">" $AceUser = [ADSI]$SidBind $Service.AutodiscoverUrl($AceUser.mail.ToString()) # Открытие папки Inbox почтового ящика $FolderId = new-object Microsoft.Exchange.WebServices.Data.FolderId ` ([Microsoft.Exchange.WebServices.Data.WellKnownFolderName]::Inbox,$MailboxName) $InboxFolder = [Microsoft.Exchange.WebServices.Data.Folder]::Bind($Service,$FolderId) # Создание фильтра поиска писем $SearchFilterRead = new-object Microsoft.Exchange.WebServices.Data.SearchFilter+IsEqualTo ` ([Microsoft.Exchange.WebServices.Data.EmailMessageSchema]::IsRead, $True) $SearchFilterNotRead = new-object Microsoft.Exchange.WebServices.Data.SearchFilter+IsEqualTo ` ([Microsoft.Exchange.WebServices.Data.EmailMessageSchema]::IsRead, $False) $SearchFilterCollection = ` new-object Microsoft.Exchange.WebServices.Data.SearchFilter+SearchFilterCollection ` ([Microsoft.Exchange.WebServices.Data.LogicalOperator]::Or); $SearchFilterCollection.add($SearchFilterRead) $SearchFilterCollection.add($SearchFilterNotRead) # Задание начальной позиции и количества писем в коллекции $offset = 0; $view = new-object Microsoft.Exchange.WebServices.Data.ItemView(100, $offset) # Задание расширенных свойств для подгрузки $psPropset = new-object Microsoft.Exchange.WebServices.Data.PropertySet ` ([Microsoft.Exchange.WebServices.Data.BasePropertySet]::FirstClassProperties) While (($results = $InboxFolder.FindItems($SearchFilterCollection, $view)).Items.Count -gt 0) { # Подгрузка расширенных свойств текущей коллекции писем [Void]$service.LoadPropertiesForItems($results,$psPropset) # Наполнение рабочей переменной свойствами писем из коллекции ForEach ($item in $results) { $MailboxContent = New-Object System.Object $MailboxContent | Add-Member -MemberType NoteProperty -Name Folder -Value $InboxFolder.Displayname $MailboxContent | Add-Member -MemberType NoteProperty -Name FromAddress -Value $item.From.Address $MailboxContent | Add-Member -MemberType NoteProperty -Name ToRecipients -Value ` ([string]$item.ToRecipients) # преобразование массива в строку $MailboxContent | Add-Member -MemberType NoteProperty -Name CcRecipients -Value ` ([string]$item.CcRecipients) # преобразование массива в строку $MailboxContent | Add-Member -MemberType NoteProperty -Name BccRecipients -Value ` ([string]$item.BccRecipients) # преобразование массива в строку $MailboxContent | Add-Member -MemberType NoteProperty -Name Subject -Value $item.Subject $MailboxContent | Add-Member -MemberType NoteProperty -Name Received -Value $item.DateTimeReceived $MailboxContent | Add-Member -MemberType NoteProperty -Name Sent -Value $item.DateTimeSent $MailboxContent | Add-Member -MemberType NoteProperty -Name Size -Value $item.Size $ScriptResult += $MailboxContent } # Перемещение курсора текущей позиции и настроек количества писем следующей коллекции $offset += $results.Items.Count $view = new-object Microsoft.Exchange.WebServices.Data.ItemView(100, $offset) } # Получение списка подпапок $fvFolderView = New-Object Microsoft.Exchange.WebServices.Data.FolderView(1000); $fvFolderView.Traversal = [Microsoft.Exchange.WebServices.Data.FolderTraversal]::Deep $ffResponse= $InboxFolder.FindFolders($fvFolderView); # Получение писем подпапок ForEach ($folder in $ffResponse.Folders) { # Задание начальной позиции и количества писем в коллекции $offset = 0; $view = new-object Microsoft.Exchange.WebServices.Data.ItemView(100, $offset) # Задание расширенных свойств для подгрузки $psPropset = new-object Microsoft.Exchange.WebServices.Data.PropertySet ` ([Microsoft.Exchange.WebServices.Data.BasePropertySet]::FirstClassProperties) While (($results = $InboxFolder.FindItems($SearchFilterCollection, $view)).Items.Count -gt 0) { # Подгрузка расширенных свойств текущей коллекции писем [Void]$service.LoadPropertiesForItems($results,$psPropset) # Наполнение рабочей переменной свойствами писем из коллекции ForEach ($item in $results) { # Write Information regarding every e-mail in the folder $MailboxContent = New-Object System.Object $MailboxContent | Add-Member -MemberType NoteProperty -Name Folder -Value ` $InboxFolder.Displayname $MailboxContent | Add-Member -MemberType NoteProperty -Name FromAddress -Value ` $item.From.Address $MailboxContent | Add-Member -MemberType NoteProperty -Name ToRecipients -Value ` ([string]$item.ToRecipients) # преобразование массива в строку $MailboxContent | Add-Member -MemberType NoteProperty -Name CcRecipients -Value ` ([string]$item.CcRecipients) # преобразование массива в строку $MailboxContent | Add-Member -MemberType NoteProperty -Name BccRecipients -Value ` ([string]$item.BccRecipients) # преобразование массива в строку $MailboxContent | Add-Member -MemberType NoteProperty -Name Subject -Value $item.Subject $MailboxContent | Add-Member -MemberType NoteProperty -Name Received -Value ` $item.DateTimeReceived $MailboxContent | Add-Member -MemberType NoteProperty -Name Sent -Value $item.DateTimeSent $MailboxContent | Add-Member -MemberType NoteProperty -Name Size -Value $item.Size $ScriptResult += $MailboxContent } # Перемещение курсора текущей позиции и настроек количества писем следующей коллекции $offset += $results.Items.Count $view = new-object Microsoft.Exchange.WebServices.Data.ItemView(100, $offset) } } # Открытие папки SentItems почтового ящика $FolderId = new-object Microsoft.Exchange.WebServices.Data.FolderId ` ([Microsoft.Exchange.WebServices.Data.WellKnownFolderName]::SentItems,$MailboxName) $InboxFolder = [Microsoft.Exchange.WebServices.Data.Folder]::Bind($Service,$FolderId) # Задание начальной позиции и количества писем в коллекции $offset = 0; $view = new-object Microsoft.Exchange.WebServices.Data.ItemView(100, $offset) # Задание расширенных свойств для подгрузки $psPropset = new-object Microsoft.Exchange.WebServices.Data.PropertySet ` ([Microsoft.Exchange.WebServices.Data.BasePropertySet]::FirstClassProperties) While (($results = $InboxFolder.FindItems($SearchFilterCollection, $view)).Items.Count -gt 0) { # Подгрузка расширенных свойств текущей коллекции писем [Void]$service.LoadPropertiesForItems($results,$psPropset) # Наполнение рабочей переменной свойствами писем из коллекции ForEach ($item in $results) { # Write Information regarding every e-mail in the folder $MailboxContent = New-Object System.Object $MailboxContent | Add-Member -MemberType NoteProperty -Name Folder -Value $InboxFolder.Displayname $MailboxContent | Add-Member -MemberType NoteProperty -Name FromAddress -Value $item.From.Address $MailboxContent | Add-Member -MemberType NoteProperty -Name ToRecipients -Value ` ([string]$item.ToRecipients) # преобразование массива в строку $MailboxContent | Add-Member -MemberType NoteProperty -Name CcRecipients -Value ` ([string]$item.CcRecipients) # преобразование массива в строку $MailboxContent | Add-Member -MemberType NoteProperty -Name BccRecipients -Value ` ([string]$item.BccRecipients) # преобразование массива в строку $MailboxContent | Add-Member -MemberType NoteProperty -Name Subject -Value $item.Subject $MailboxContent | Add-Member -MemberType NoteProperty -Name Received -Value $item.DateTimeReceived $MailboxContent | Add-Member -MemberType NoteProperty -Name Sent -Value $item.DateTimeSent $MailboxContent | Add-Member -MemberType NoteProperty -Name Size -Value $item.Size $ScriptResult += $MailboxContent } # Перемещение курсора текущей позиции и настроек количества писем следующей коллекции $offset += $results.Items.Count $view = new-object Microsoft.Exchange.WebServices.Data.ItemView(100, $offset) } $ScriptResult | Export-Csv ((Get-Childitem env:USERPROFILE).Value + "\Desktop\PSOutput.csv") ` -Delimiter "`t" -Encoding UTF8