by

Making a Mailbox alias utilization report with EWS and Powershell

Making a Mailbox alias utilization report with EWS and Powershell Earlier than beginning this one I wish to level out the strategy I will exhibit on this submit just isn’t the very best technique to make use of to do that. If in case you have Message Monitoring out there then you are able to do this rather more precisely utilizing the Message monitoring logs.  But when you do not have this out there to you otherwise you simply wish to see what you are able to do with EWS then that is the submit for you.

Many individuals have a number of electronic mail addresses assigned to their mailboxes (they get referred to utilizing completely different names alias’s, proxyaddress’s, secondary handle’s, alternate handle’s and many others) however in Outlook and OWA it may be laborious to see what electronic mail handle has been used to ship you a mail due to the supply course of and the best way the addresses are resolved. To get the precise electronic mail handle a specific electronic mail was despatched to at least one workaround you need to use in EWS is to make use of the PidTagTransportMessageHeaders property after which parse the TO, CC and BCC Headers (observe typically the BCC header will not be there even you probably have been BCC’d) from the transport headers.

So what this script does is first it makes use of the Trade Administration Shell’s get-mailbox cmdlet to seize all proxyaddresses for the goal account. That is wanted as a result of there may be noway in EWS to get all of the Mailbox proxy addresses (you need to use ResolveName to get the Mailbox Contact from AD however you’ll solely get returned the primary three addresses for the mailbox). It shops these addresses in a hashtable that may then be utilized in to do lookups so when processing all of the emailaddress in header we are able to filter to solely construct a report of the present mailboxes addresses getting used. The subsequent a part of the code is a few regular EWS honest to seize all of the messages within the Inbox for the final 7 days after which seize the PidTagTransportMessageHeaders  property and parse the TO,CC and BCC addresses from the headers utilizing a linear parser and a few RegEX (I do know some folks do not like linear parsing however I all the time discover they work effectively).  The script then builds two reviews the primary report is a abstract report exhibiting every of the alias’s that the place used and what number of TO,CC and BCC the place used eg

The opposite report that the script builds is an Merchandise Report which reveals for every Merchandise within the Inbox which technique was used eg

Now as I discussed there are a number of issues with the strategy used within the script you probably have been BCC’d on a message typically there will not be any data within the headers to mirror which electronic mail handle was used. Additionally if the message was despatched to a Distribution record or it is a piece of GrayMail relying on no matter technique the mailer has used there perhaps no header. So on this case it should present different within the technique and the final parsed TO handle.

To run this script it’s good to have a Distant Powershell session open so you possibly can run Get-Mailbox after which simply run the script with the PrimaryEmaillAddress of the mailbox you wish to run the script in opposition to as a parameter. The script will output the 2 reviews to the temp listing

I’ve put a download of this script right here the code seems to be like

  1. ## Get the Mailbox to Entry from the 1st commandline argument  
  2.   
  3. $MailboxName = $args[0]  
  4.   
  5. $Mailbox = get-mailbox $MailboxName  
  6. $mbAddress = @{}  
  7. foreach($emEmail in $Mailbox.EmailAddresses){  
  8.     if($emEmail.Tolower().Incorporates(“smtp:”)){  
  9.         $mbAddress.Add($emEmail.SubString(5).Tolower(),0)  
  10.     }  
  11. }  
  12.   
  13. ## Load Managed API dll    
  14.   
  15. ###CHECK FOR EWS MANAGED API, IF PRESENT IMPORT THE HIGHEST VERSION EWS DLL, ELSE EXIT  
  16. $EWSDLL = (($(Get-ItemProperty -ErrorAction SilentlyContinue -Path Registry::$(Get-ChildItem -ErrorAction SilentlyContinue -Path ‘Registry::HKEY_LOCAL_MACHINESOFTWAREMicrosoftExchangeWeb Companies’|Kind-Object Title -Descending| Choose-Object -First 1 -ExpandProperty Title)).‘Set up Listing’) + “Microsoft.Exchange.WebServices.dll”)  
  17. if (Take a look at-Path $EWSDLL)  
  18.     {  
  19.     Import-Module $EWSDLL  
  20.     }  
  21. else  
  22.     {  
  23.     “$(get-date -format yyyyMMddHHmmss):”  
  24.     “This script requires the EWS Managed API 1.2 or later.”  
  25.     “Please download and install the current version of the EWS Managed API from”  
  26.     “http://go.microsoft.com/fwlink/?LinkId=255472”  
  27.     “”  
  28.     “Exiting Script.”  
  29.     exit  
  30.     }  
  31.     
  32. ## Set Trade Model    
  33. $ExchangeVersion = [Microsoft.Exchange.WebServices.Data.ExchangeVersion]::Trade2010_SP2    
  34.     
  35. ## Create Trade Service Object    
  36. $service = New-Object Microsoft.Trade.WebServices.Information.ExchangeService($ExchangeVersion)    
  37.     
  38. ## Set Credentials to use two choices are availible Option1 to use explict credentials or Choice 2 use the Default (logged On) credentials    
  39.     
  40. #Credentials Choice 1 utilizing UPN for the home windows Account    
  41. $psCred = Get-Credential    
  42. $creds = New-Object System.Web.NetworkCredential($psCred.UserName.ToString(),$psCred.GetNetworkCredential().password.ToString())    
  43. $service.Credentials = $creds        
  44.     
  45. #Credentials Choice 2    
  46. #service.UseDefaultCredentials = $true    
  47.     
  48. ## Select to ignore any SSL Warning points precipitated by Self Signed Certificates    
  49.     
  50. ## Code From http://poshcode.org/624  
  51. ## Create a compilation setting  
  52. $Supplier=New-Object Microsoft.CSharp.CSharpCodeProvider  
  53. $Compiler=$Supplier.CreateCompiler()  
  54. $Params=New-Object System.CodeDom.Compiler.CompilerParameters  
  55. $Params.GenerateExecutable=$False  
  56. $Params.GenerateInMemory=$True  
  57. $Params.IncludeDebugInformation=$False  
  58. $Params.ReferencedAssemblies.Add(“System.DLL”) | Out-Null  
  59.   
  60. $TASource=@ 
  61.   namespace Native.ToolkitExtensions.Web.CertificatePolicy{ 
  62.     public class TrustAll : System.Web.ICertificatePolicy { 
  63.       public TrustAll() {  
  64.       } 
  65.       public bool CheckValidationResult(System.Web.ServicePoint sp, 
  66.         System.Safety.Cryptography.X509Certificates.X509Certificates cert,  
  67.         System.Web.WebRequest req, int downside) { 
  68.         return true; 
  69.       } 
  70.     } 
  71.   } 
  72. @   
  73. $TAResults=$Supplier.CompileAssemblyFromSource($Params,$TASource)  
  74. $TAAssembly=$TAResults.CompiledAssembly  
  75.   
  76. ## We now create an occasion of the TrustAll and connect it to the ServicePointManager  
  77. $TrustAll=$TAAssembly.CreateInstance(“Local.ToolkitExtensions.Net.CertificatePolicy.TrustAll”)  
  78. [System.Net.ServicePointManager]::CertificatePolicy=$TrustAll  
  79.   
  80. ## finish code from http://poshcode.org/624  
  81.     
  82. ## Set the URL of the CAS (Shopper Entry Server) to use two choices are availbe to use Autodiscover to discover the CAS URL or Hardcode the CAS to use    
  83.     
  84. #CAS URL Choice 1 Autodiscover    
  85. $service.AutodiscoverUrl($MailboxName,{$true})    
  86. “Using CAS Server : “ + $Service.url     
  87.      
  88. #CAS URL Choice 2 Hardcoded    
  89.     
  90. #$uri=[system.URI] “https://casservername/ews/exchange.asmx”    
  91. #$service.Url = $uri      
  92.     
  93. ## Elective part for Trade Impersonation    
  94.     
  95. #$service.ImpersonatedUserId = new-object Microsoft.Trade.WebServices.Information.ImpersonatedUserId([Microsoft.Exchange.WebServices.Data.ConnectingIdType]::SmtpAddress, $MailboxName)   
  96.   
  97. # Bind to the Inbox Folder  
  98. $folderid= new-object Microsoft.Trade.WebServices.Information.FolderId([Microsoft.Exchange.WebServices.Data.WellKnownFolderName]::Inbox,$MailboxName)     
  99. $Inbox = [Microsoft.Exchange.WebServices.Data.Folder]::Bind($service,$folderid)  
  100. $PR_TRANSPORT_MESSAGE_HEADERS = new-object Microsoft.Trade.WebServices.Information.ExtendedPropertyDefinition(0x007D,[Microsoft.Exchange.WebServices.Data.MapiPropertyType]::String);  
  101. $psPropset= new-object Microsoft.Trade.WebServices.Information.PropertySet([Microsoft.Exchange.WebServices.Data.BasePropertySet]::IdOnly)    
  102. $psPropset.Add($PR_TRANSPORT_MESSAGE_HEADERS)  
  103. $psPropset.Add([Microsoft.Exchange.WebServices.Data.ItemSchema]::Topic)  
  104. $psPropset.Add([Microsoft.Exchange.WebServices.Data.ItemSchema]::Measurement)  
  105. $psPropset.Add([Microsoft.Exchange.WebServices.Data.ItemSchema]::DateTimeReceived)  
  106. #Outline ItemView to retrive simply 1000 Objects      
  107. $ivItemView =  New-Object Microsoft.Trade.WebServices.Information.ItemView(1000)    
  108. $ivItemView.PropertySet = $psPropset  
  109. $rptCollection = @()  
  110. $rptcntCount = @{}  
  111. #Discover Objects that are unread  
  112. $sfItemSearchFilter = new-object Microsoft.Trade.WebServices.Information.SearchFilter+IsGreaterThan([Microsoft.Exchange.WebServices.Data.ItemSchema]::DateTimeReceived, (Get-Date).AddDays(-7));   
  113. $fiItems = $null      
  114. do{      
  115.     $fiItems = $service.FindItems($Inbox.Id,$sfItemSearchFilter,$ivItemView)      
  116.     [Void]$service.LoadPropertiesForItems($fiItems,$psPropset)    
  117.     foreach($Merchandise in $fiItems.Objects){      
  118.         $Headers = $null;  
  119.         $Deal with = “”;  
  120.         $Technique = “”  
  121.         if($Merchandise.TryGetProperty($PR_TRANSPORT_MESSAGE_HEADERS,[ref]$Headers)){  
  122.             $slen = $Headers.ToLower().IndexOf(“`nto: “)  
  123.             if($slen -gt 0){  
  124.                 $elen = $Headers.IndexOf(“`r`n”,$slen)                
  125.                 $ToAddressParsed = $Headers.SubString(($slen+4),$elen-($slen+4))  
  126.                 whereas($Headers.Substring($elen+2,1) -eq [char]9){  
  127.                     $slen = $elen+2  
  128.                     $elen = $Headers.IndexOf(“`r`n”,$slen)    
  129.                     $ToAddressParsed += $Headers.SubString(($slen),$elen-($slen))  
  130.                 }  
  131.                 $emailRegex = new-object System.Textual content.RegularExpressions.Regex(“w+([-+.]w+)*@w+([-.]w+)*.w+([-.]w+)*”,[System.Text.RegularExpressions.RegexOptions]::IgnoreCase);  
  132.                 $emailMatches = $emailRegex.Matches($ToAddressParsed);  
  133.                 foreach($Match in $emailMatches){  
  134.                     if($mbAddress.Incorporates($Match.Worth.Tolower())){  
  135.                         $Deal with = $Match  
  136.                         $Technique = “To”  
  137.                         if($rptcntCount.ContainsKey($Match.Worth)){  
  138.                             $rptcntCount[$Match.Worth].To +=1  
  139.                         }  
  140.                         else Choose Deal with,To,CC,BCC  
  141.                             $rptObj.Deal with = $Match.Worth  
  142.                             $rptObj.To = 1  
  143.                             $rptObj.CC = 0  
  144.                             $rptObj.BCC = 0  
  145.                             $rptcntCount.Add($Match.Worth,$rptObj)                    
  146.                           
  147.                     }  
  148.                     else{  
  149.                         if($Deal with -eq “”){  
  150.                             $Deal with = $Match  
  151.                             $Technique = “Other”  
  152.                         }  
  153.                     }  
  154.                 }  
  155.             }  
  156.             $slen = $Headers.ToLower().IndexOf(“`ncc: “)  
  157.             if($slen -gt 0){  
  158.                 $elen = $Headers.IndexOf(“`r`n”,$slen)  
  159.                 $ccAddressParsed = $Headers.SubString(($slen+4),$elen-($slen+4))  
  160.                 whereas($Headers.Substring($elen+2,1) -eq [char]9){  
  161.                     $slen = $elen+2  
  162.                     $elen = $Headers.IndexOf(“`r`n”,$slen)    
  163.                     $ccAddressParsed += $Headers.SubString(($slen),$elen-($slen))  
  164.                 }  
  165.                 $emailRegex = new-object System.Textual content.RegularExpressions.Regex(“w+([-+.]w+)*@w+([-.]w+)*.w+([-.]w+)*”,[System.Text.RegularExpressions.RegexOptions]::IgnoreCase);  
  166.                 $emailMatches = $emailRegex.Matches($ccAddressParsed);  
  167.                 foreach($Match in $emailMatches){  
  168.                     if($mbAddress.Incorporates($Match.Worth.Tolower())){  
  169.                         $Deal with = $Match  
  170.                         $Technique = “CC”  
  171.                         if($rptcntCount.ContainsKey($Match.Worth)){  
  172.                             $rptcntCount[$Match.Worth].CC +=1  
  173.                         }  
  174.                         else Choose Deal with,To,CC,BCC  
  175.                             $rptObj.Deal with = $Match.Worth  
  176.                             $rptObj.To = 0  
  177.                             $rptObj.CC = 1  
  178.                             $rptObj.BCC = 0  
  179.                             $rptcntCount.Add($Match.Worth,$rptObj)                    
  180.                           
  181.                     }  
  182.                 }  
  183.             }  
  184.             $slen = $Headers.ToLower().IndexOf(“`nbcc: “)  
  185.             if($slen -gt 0){  
  186.                 $elen = $Headers.IndexOf(“`r`n”,$slen)  
  187.                 $bccAddressParsed = $Headers.SubString(($slen+4),$elen-($slen+4))  
  188.                 whereas($Headers.Substring($elen+2,1) -eq [char]9){  
  189.                     $slen = $elen+2  
  190.                     $elen = $Headers.IndexOf(“`r`n”,$slen)    
  191.                     $bccAddressParsed += $Headers.SubString(($slen),$elen-($slen))  
  192.                 }  
  193.                 $emailRegex = new-object System.Textual content.RegularExpressions.Regex(“w+([-+.]w+)*@w+([-.]w+)*.w+([-.]w+)*”,[System.Text.RegularExpressions.RegexOptions]::IgnoreCase);  
  194.                 $emailMatches = $emailRegex.Matches($bccAddressParsed);  
  195.                 foreach($Match in $emailMatches){  
  196.                     if($mbAddress.Incorporates($Match.Worth.Tolower())){  
  197.                         $Deal with = $Match  
  198.                         $Technique = “BCC”  
  199.                         if($rptcntCount.ContainsKey($Match.Worth)){  
  200.                             $rptcntCount[$Match.Worth].BCC +=1  
  201.                         }  
  202.                         else Choose Deal with,To,CC,BCC  
  203.                             $rptObj.Deal with = $Match.Worth  
  204.                             $rptObj.To = 0  
  205.                             $rptObj.CC = 0  
  206.                             $rptObj.BCC = 1  
  207.                             $rptcntCount.Add($Match.Worth,$rptObj)                    
  208.                           
  209.                     }  
  210.                 }  
  211.             }  
  212.         }  
  213.         $ItemReport = “” | Choose DateTimeReceived,Technique,Deal with,Topic,Measurement  
  214.         $ItemReport.DateTimeReceived = $Merchandise.DateTimeReceived  
  215.         $ItemReport.Topic = $Merchandise.Topic  
  216.         $ItemReport.Measurement = $Merchandise.Measurement  
  217.         $ItemReport.Technique = $Technique  
  218.         $ItemReport.Deal with = $Deal with  
  219.         $rptCollection += $ItemReport  
  220.           
  221.     }      
  222.     $ivItemView.Offset += $fiItems.Objects.Rely  
  223.     Write-Host (“Processed “ + $ivItemView.Offset + ” of “ + $fiItems.TotalCount)  
  224. }whereas($fiItems.MoreAvailable -eq $true)   
  225. $rptcntCount.Values | ft  
  226. $rptcntCount.Values | Export-Csv -NoTypeInformation -path “c:Temp$MailboxName-MHSummaryReport.csv”  
  227. $rptCollection | Export-Csv -NoTypeInformation -path “c:Temp$MailboxName-MHItemReport.csv”