The is the first of my samples based on the EWS Managed API and Powershell how to series I've been writing. This one is actually an update to a script i wrote a few years ago to find unused mailboxes on Exchange 2007. This script is designed to be run from within a Remote Powershell session that is already connected to your Exchange 2010 org (or from a Exchange Online/Office365 remote powershell session).
It uses Get-Mailbox to get all the mailboxes in your org and then it uses the EWS Managed API to connect to each mailbox and makes a query of the Inbox (using a AQS query String) to get all the Email in the mailbox for the last 6 months, then it queries for all email in the last 6 months that is still marked unread. Then it queries the Sent Email folder for how many email where sent for the last 6 months. (this would only be accurate based on the user behavior of moving messages). Its combines this with the statistics from Get-MailboxStatistics to produce a csv file that would give you a report that looks like
If you want to understand how it works have a read of the How To Series posts and hopefully you should be able to work out how to customize it if you need to for your own environment. The Script as posted uses EWS Impersonation
If you want to customize which mailboxes it reports on then just change the Get-Mailbox line
Get-Mailbox -ResultSize Unlimited | ForEach-Object{
eg if you want to limit to only checking one server you could use
Get-Mailbox -ResultSize Unlimited -Server servernameblah | ForEach-Object{
You could do similar with other filter properties such as Database or OU
I've posted a downloadable version here
The script itself looks like
It uses Get-Mailbox to get all the mailboxes in your org and then it uses the EWS Managed API to connect to each mailbox and makes a query of the Inbox (using a AQS query String) to get all the Email in the mailbox for the last 6 months, then it queries for all email in the last 6 months that is still marked unread. Then it queries the Sent Email folder for how many email where sent for the last 6 months. (this would only be accurate based on the user behavior of moving messages). Its combines this with the statistics from Get-MailboxStatistics to produce a csv file that would give you a report that looks like
If you want to understand how it works have a read of the How To Series posts and hopefully you should be able to work out how to customize it if you need to for your own environment. The Script as posted uses EWS Impersonation
If you want to customize which mailboxes it reports on then just change the Get-Mailbox line
Get-Mailbox -ResultSize Unlimited | ForEach-Object{
eg if you want to limit to only checking one server you could use
Get-Mailbox -ResultSize Unlimited -Server servernameblah | ForEach-Object{
You could do similar with other filter properties such as Database or OU
I've posted a downloadable version here
The script itself looks like
- ## EWS Managed API Connect Module Script written by Glen Scales
- ## Requires the EWS Managed API and Powershell V2.0 or greator
- $RptCollection = @()
- ## Load Managed API dll
- Add-Type -Path "C:\Program Files\Microsoft\Exchange\Web Services\1.2\Microsoft.Exchange.WebServices.dll"
- ## Set Exchange Version
- $ExchangeVersion = [Microsoft.Exchange.WebServices.Data.ExchangeVersion]::Exchange2010_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
- $psCred = Get-Credential
- $creds = New-Object System.Net.NetworkCredential($psCred.UserName.ToString(),$psCred.GetNetworkCredential().password.ToString())
- $service.Credentials = $creds
- #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
- function CovertBitValue($String){
- $numItempattern = '(?=\().*(?=bytes)'
- $matchedItemsNumber = [regex]::matches($String, $numItempattern)
- $Mb = [INT64]$matchedItemsNumber[0].Value.Replace("(","").Replace(",","")
- return [math]::round($Mb/1048576,0)
- }
- Get-Mailbox -ResultSize Unlimited | ForEach-Object{
- $MailboxName = $_.PrimarySMTPAddress.ToString()
- "Processing Mailbox : " + $MailboxName
- if($service.url -eq $null){
- ## 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
- }
- $rptObj = "" | select MailboxName,Mailboxsize,LastLogon,LastLogonAccount,Last6MonthsTotal,Last6MonthsUnread,LastMailRecieved,Last6MonthsSent,LastMailSent
- $rptObj.MailboxName = $MailboxName
- $service.ImpersonatedUserId = new-object Microsoft.Exchange.WebServices.Data.ImpersonatedUserId([Microsoft.Exchange.WebServices.Data.ConnectingIdType]::SmtpAddress, $MailboxName)
- $Range = [system.DateTime]::Now.AddMonths(-6).ToString("MM/dd/yyyy") + ".." + [system.DateTime]::Now.ToString("MM/dd/yyyy")
- $AQSString1 = "System.Message.DateReceived:" + $Range
- $AQSString2 = $AQSString1 + " and isread:false"
- $folderid= new-object Microsoft.Exchange.WebServices.Data.FolderId([Microsoft.Exchange.WebServices.Data.WellKnownFolderName]::Inbox,$MailboxName)
- $Inbox = [Microsoft.Exchange.WebServices.Data.Folder]::Bind($service,$folderid)
- $folderid= new-object Microsoft.Exchange.WebServices.Data.FolderId([Microsoft.Exchange.WebServices.Data.WellKnownFolderName]::SentItems,$MailboxName)
- $SentItems = [Microsoft.Exchange.WebServices.Data.Folder]::Bind($service,$folderid)
- $ivItemView = New-Object Microsoft.Exchange.WebServices.Data.ItemView(1)
- $MailboxStats = Get-MailboxStatistics $MailboxName
- $ts = CovertBitValue($MailboxStats.TotalItemSize.ToString())
- "Total Size : " + $MailboxStats.TotalItemSize
- $rptObj.MailboxSize = $ts
- "Last Logon Time : " + $MailboxStats.LastLogonTime
- $rptObj.LastLogon = $MailboxStats.LastLogonTime
- "Last Logon Account : " + $MailboxStats.LastLoggedOnUserAccount
- $rptObj.LastLogonAccount = $MailboxStats.LastLoggedOnUserAccount
- $fiResults = $Inbox.findItems($AQSString1,$ivItemView)
- $rptObj.Last6MonthsTotal = $fiResults.TotalCount
- "Last 6 Months : " + $fiResults.TotalCount
- if($fiResults.TotalCount -gt 0){
- "Last Mail Recieved : " + $fiResults.Items[0].DateTimeReceived
- $rptObj.LastMailRecieved = $fiResults.Items[0].DateTimeReceived
- }
- $ivItemView = New-Object Microsoft.Exchange.WebServices.Data.ItemView(1)
- $fiResults = $Inbox.findItems($AQSString2,$ivItemView)
- "Last 6 Months Unread : " + $fiResults.TotalCount
- $rptObj.Last6MonthsUnread = $fiResults.TotalCount
- $ivItemView = New-Object Microsoft.Exchange.WebServices.Data.ItemView(1)
- $fiResults = $SentItems.findItems($AQSString1,$ivItemView)
- "Last 6 Months Sent : " + $fiResults.TotalCount
- $rptObj.Last6MonthsSent = $fiResults.TotalCount
- if($fiResults.TotalCount -gt 0){
- "Last Mail Sent Date : " + $fiResults.Items[0].DateTimeSent
- $rptObj.LastMailSent = $fiResults.Items[0].DateTimeSent
- }
- $RptCollection +=$rptObj
- }
- $RptCollection | Export-Csv -NoTypeInformation c:\temp\unreadReport.csv