Recently we had a need to query emails sent to an Inbox and find out who the emails had been BCC’ed to. These would then need to be filed into folders based on the BCC address. When an email arrived in the inbox , the server striped the BCC field ( as normal ) so we had to find a way to get this value.
There are a few ways to get the BCC from a message in Exchange
- Envelope Journaling ( Setting up a rule to copy the whole email that was sent into a folder which still kept the BCC fields )
- You can build yourself a Transport Agent Dll http://gsexdev.blogspot.com.au/2011/06/processing-bccs-in-exchange-transport.html
- You can query the Exchange tracking logs based on MessageID
We opted for the third option and below is the scheduled task
# Connect to Exchange server and load Exchange powershell modules
. 'C:\Program Files\Microsoft\Exchange Server\V14\bin\RemoteExchange.ps1'
Connect-ExchangeServer -auto
$mailbox = Get-Mailbox -id mailboxname
$mailAddress = $mailbox.PrimarySmtpAddress.ToString();
[Reflection.Assembly]::LoadFile("C:\Program Files (x86)\Microsoft\Exchange\Web Services\2.1\Microsoft.Exchange.WebServices.dll") | Out-Null
$s = New-Object Microsoft.Exchange.WebServices.Data.ExchangeService([Microsoft.Exchange.WebServices.Data.ExchangeVersion]::Exchange2007_SP1)
$s.AutodiscoverUrl($mailAddress);
#Bind Root of Mailbox
$folderid = new-object Microsoft.Exchange.WebServices.Data.FolderId([Microsoft.Exchange.WebServices.Data.WellKnownFolderName]::MsgFolderRoot,$mailAddress)
$MailboxRoot = [Microsoft.Exchange.WebServices.Data.Folder]::Bind($s,$folderid)
# Function to Get Folder ID from Folder Path
Function GetFolder()
{
# Return a reference to a folder specified by path
$RootFolder, $FolderPath = $args[0];
$Folder = $RootFolder;
if ($FolderPath -ne '\')
{
$PathElements = $FolderPath -split '\\';
For ($i=0; $i -lt $PathElements.Count; $i++)
{
if ($PathElements[$i])
{
$View = New-Object Microsoft.Exchange.WebServices.Data.FolderView(2,0);
$View.Traversal = [Microsoft.Exchange.WebServices.Data.FolderTraversal]::Deep;
$View.PropertySet = [Microsoft.Exchange.WebServices.Data.BasePropertySet]::IdOnly;
$SearchFilter = New-Object Microsoft.Exchange.WebServices.Data.SearchFilter+IsEqualTo([Microsoft.Exchange.WebServices.Data.FolderSchema]::DisplayName, $PathElements[$i]);
$FolderResults = $Folder.FindFolders($SearchFilter, $View);
if ($FolderResults.TotalCount -ne 1)
{
# We have either none or more than one folder returned... Either way, we can't continue
$Folder = $null;
Write-Host "Failed to find " $PathElements[$i];
Write-Host "Requested folder path: " $FolderPath;
break;
}
$Folder = [Microsoft.Exchange.WebServices.Data.Folder]::Bind($s, $FolderResults.Folders[0].Id)
}
}
}
$Folder;
}
#Bind Inbox of Mailbox
$Inboxid = new-object Microsoft.Exchange.WebServices.Data.FolderId([Microsoft.Exchange.WebServices.Data.WellKnownFolderName]::Inbox,$mailAddress)
$InboxFolder = [Microsoft.Exchange.WebServices.Data.Folder]::Bind($s,$Inboxid)
# Get x Items in Inbox
$mails = $InboxFolder.FindItems(5)
foreach($Item in $mails.Items)
{
# Get list of Reciepients from Message ID that has been BCC'ed
$mailrecipeients = Get-MessageTrackingLog -MessageID $item.InternetMessageId | where{$_.RecipientStatus -eq "Bcc"} |% {$_.recipients}
if ($mailrecipeients -match "[email protected]")
{
$FolderObject = GetFolder($MailboxRoot, "\Moved\Folder");
try
{
$Item.Move($FolderObject.Id) | out-null;
}
catch
{
Write-Host "Failed to move item", $Item.Id.UniqueId
}
}
}