One of the features of eDiscovery in Exchange 2013 and greater is the ability to do a search of Mailbox and just return the statistics on particular Items (or searches). This allows you to do a really quick search without the need to process any of the ResultSet of the Search. To limit the Items types returned by an eDiscovery query you can use the kind Keyword property in a KQL query. The feature set of which has recently been updated https://technet.microsoft.com/en-us/library/dn508399(v=exchg.150).aspx to now allow you to include Lync (or IM) items. So one little cool thing you can do with this using a multiple OR logic query with eDiscovery is get a quick list of the number of exchange Items by type in a Mailbox eg the KQL for this would look like
"kind:email OR kind:meetings OR kind:contacts OR kind:tasks OR kind:notes OR kind:IM OR kind:rssfeeds OR kind:voicemail"
and this would produce a report that looks like
I've put together a sample of a script to do this which you can download form here. To run the script use
Get-MailboxItemTypeStats -MailboxName user@domain.com -OutputFileName reportfile.csv
The code itself looks like
"kind:email OR kind:meetings OR kind:contacts OR kind:tasks OR kind:notes OR kind:IM OR kind:rssfeeds OR kind:voicemail"
and this would produce a report that looks like
I've put together a sample of a script to do this which you can download form here. To run the script use
Get-MailboxItemTypeStats -MailboxName user@domain.com -OutputFileName reportfile.csv
The code itself looks like
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 | ####################### <# .SYNOPSIS Performs an eDiscovery Search using Powershell and the Exchange Web Services API in a Mailbox and produces a CSV report of ItemType in that Mailbox .DESCRIPTION Performs an eDiscovery Search using Powershell and the Exchange Web Services API in a Mailbox and produces a CSV report of ItemType in that Mailbox Requires the EWS Managed API from https://www.microsoft.com/en-us/download/details.aspx?id=42951 .EXAMPLE PS C:\>Get-MailboxItemTypeStats -MailboxName user.name@domain.com -OutputFileName Report.csv This Example Performs an eDiscovery Search using Powershell and the Exchange Web Services API in a Mailbox and produces a CSV report of ItemType in that Mailbox #> function Get-MailboxItemTypeStats { [CmdletBinding()] param( [Parameter(Position=0, Mandatory=$true)] [string]$MailboxName, [Parameter(Position=1, Mandatory=$true)] [PSCredential]$Credentials, [Parameter(Position=2, Mandatory=$true)] [string]$OutputFileName ) Begin { $KQL = "kind:email OR kind:meetings OR kind:contacts OR kind:tasks OR kind:notes OR kind:IM OR kind:rssfeeds OR kind:voicemail"; $SearchableMailboxString = $MailboxName; ## Load Managed API dll ###CHECK FOR EWS MANAGED API, IF PRESENT IMPORT THE HIGHEST VERSION EWS DLL, ELSE EXIT $EWSDLL = (($(Get-ItemProperty -ErrorAction SilentlyContinue -Path Registry::$(Get-ChildItem -ErrorAction SilentlyContinue -Path 'Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Exchange\Web Services'|Sort-Object Name -Descending| Select-Object -First 1 -ExpandProperty Name)).'Install Directory') + "Microsoft.Exchange.WebServices.dll") if (Test-Path $EWSDLL) { Import-Module $EWSDLL } else { "$(get-date -format yyyyMMddHHmmss):" "This script requires the EWS Managed API 1.2 or later." "Please download and install the current version of the EWS Managed API from" "http://go.microsoft.com/fwlink/?LinkId=255472" "" "Exiting Script." exit } ## Set Exchange Version $ExchangeVersion = [Microsoft.Exchange.WebServices.Data.ExchangeVersion]::Exchange2013_SP1 ## Create Exchange Service Object $service = New-Object Microsoft.Exchange.WebServices.Data.ExchangeService($ExchangeVersion) ## Set Credentials to use two options are availible Option1 to use explict credentials or Option 2 use the Default (logged On) credentials #Credentials Option 1 using UPN for the windows Account $creds = New-Object System.Net.NetworkCredential($Credentials.UserName.ToString(),$Credentials.GetNetworkCredential().password.ToString()) $service.Credentials = $creds #$service.TraceEnabled = $true #Credentials Option 2 #service.UseDefaultCredentials = $true ## Choose to ignore any SSL Warning issues caused by Self Signed Certificates ## Code From http://poshcode.org/624 ## Create a compilation environment $Provider=New-Object Microsoft.CSharp.CSharpCodeProvider $Compiler=$Provider.CreateCompiler() $Params=New-Object System.CodeDom.Compiler.CompilerParameters $Params.GenerateExecutable=$False $Params.GenerateInMemory=$True $Params.IncludeDebugInformation=$False $Params.ReferencedAssemblies.Add("System.DLL") | Out-Null $TASource=@' namespace Local.ToolkitExtensions.Net.CertificatePolicy{ public class TrustAll : System.Net.ICertificatePolicy { public TrustAll() { } public bool CheckValidationResult(System.Net.ServicePoint sp, System.Security.Cryptography.X509Certificates.X509Certificate cert, System.Net.WebRequest req, int problem) { return true; } } } '@ $TAResults=$Provider.CompileAssemblyFromSource($Params,$TASource) $TAAssembly=$TAResults.CompiledAssembly ## We now create an instance of the TrustAll and attach it to the ServicePointManager $TrustAll=$TAAssembly.CreateInstance("Local.ToolkitExtensions.Net.CertificatePolicy.TrustAll") [System.Net.ServicePointManager]::CertificatePolicy=$TrustAll ## end code from http://poshcode.org/624 ## Set the URL of the CAS (Client Access Server) to use two options are availbe to use Autodiscover to find the CAS URL or Hardcode the CAS to use #CAS URL Option 1 Autodiscover $service.AutodiscoverUrl($MailboxName,{$true}) "Using CAS Server : " + $Service.url #CAS URL Option 2 Hardcoded #$uri=[system.URI] "https://casservername/ews/exchange.asmx" #$service.Url = $uri ## Optional section for Exchange Impersonation #$service.ImpersonatedUserId = new-object Microsoft.Exchange.WebServices.Data.ImpersonatedUserId([Microsoft.Exchange.WebServices.Data.ConnectingIdType]::SmtpAddress, $MailboxName) $gsMBResponse = $service.GetSearchableMailboxes($SearchableMailboxString, $false); $msbScope = New-Object Microsoft.Exchange.WebServices.Data.MailboxSearchScope[] $gsMBResponse.SearchableMailboxes.Length $mbCount = 0; foreach ($sbMailbox in $gsMBResponse.SearchableMailboxes) { $msbScope[$mbCount] = New-Object Microsoft.Exchange.WebServices.Data.MailboxSearchScope($sbMailbox.ReferenceId, [Microsoft.Exchange.WebServices.Data.MailboxSearchLocation]::All); $mbCount++; } $smSearchMailbox = New-Object Microsoft.Exchange.WebServices.Data.SearchMailboxesParameters $mbq = New-Object Microsoft.Exchange.WebServices.Data.MailboxQuery($KQL, $msbScope); $mbqa = New-Object Microsoft.Exchange.WebServices.Data.MailboxQuery[] 1 $mbqa[0] = $mbq $smSearchMailbox.SearchQueries = $mbqa; $smSearchMailbox.PageSize = 100; $smSearchMailbox.PageDirection = [Microsoft.Exchange.WebServices.Data.SearchPageDirection]::Next; $smSearchMailbox.PerformDeduplication = $false; $smSearchMailbox.ResultType = [Microsoft.Exchange.WebServices.Data.SearchResultType]::StatisticsOnly; $srCol = $service.SearchMailboxes($smSearchMailbox); $rptCollection = @() if ($srCol[0].Result -eq [Microsoft.Exchange.WebServices.Data.ServiceResult]::Success) { foreach($KeyWorkdStat in $srCol[0].SearchResult.KeywordStats){ if($KeyWorkdStat.Keyword.Contains(" OR ") -eq $false){ $rptObj = "" | Select ItemType,ItemHits,Size $rptObj.ItemType = $KeyWorkdStat.Keyword.Replace("Kind:","") $rptObj.ItemHits = $KeyWorkdStat.ItemHits $rptObj.Size = [System.Math]::Round($KeyWorkdStat.Size /1024/1024,2) $rptCollection += $rptObj } } } Write-Output $rptCollection $rptCollection | Export-Csv -NoTypeInformation -Path $OutputFileName } } |