It seems that you can never have too many ways of reading the number of Unread messages in a Inbox so here is another method. The following script uses two AQS queries to work out first the number of messages in the Inbox from a prescribed period eg the last 30 days and then the number of these that are then unread. It then works out the percentage of unread using of the two values and then creates a graph to display in the Console using Alt-ASCII characters which produces a pretty nifty output eg
It also produces a CSV output eg
AQS queries will work in Exchange 2010 and 2013 so this script should work okay in those environments as well as ExchangeOnline.
I've created two versions of this script, the first version just reports on one user so you run it with the email of the users you want to report on and the number of days to query back. eg
.\AQSUsr.ps1 gscales1@msgdevelop.onmicrosoft.com 30
the second version reports on all of the users in a CSV file and uses EWS Impersonation to access the Mailboxes. To use the script you need to have configured EWS Impersonation and feed the script a CSV file of the users you want to report on eg the CSV file should look like
smtpaddress
user1@domain.com
user2@domain.com
and you run it like
.\AQSAllUsr.ps1 ./users.csv 30
I've put a download of both scripts here the code look like
It also produces a CSV output eg
AQS queries will work in Exchange 2010 and 2013 so this script should work okay in those environments as well as ExchangeOnline.
I've created two versions of this script, the first version just reports on one user so you run it with the email of the users you want to report on and the number of days to query back. eg
.\AQSUsr.ps1 gscales1@msgdevelop.onmicrosoft.com 30
the second version reports on all of the users in a CSV file and uses EWS Impersonation to access the Mailboxes. To use the script you need to have configured EWS Impersonation and feed the script a CSV file of the users you want to report on eg the CSV file should look like
smtpaddress
user1@domain.com
user2@domain.com
and you run it like
.\AQSAllUsr.ps1 ./users.csv 30
I've put a download of both scripts here the code look like
- ## Get the Mailbox to Access from the 1st commandline argument
- $csvFileName = $args[0]
- $DaysBack = $args[1]
- ## Load Managed API dll
- Add-Type -Path "C:\Program Files\Microsoft\Exchange\Web Services\2.0\Microsoft.Exchange.WebServices.dll"
- ## Set Exchange Version
- $ExchangeVersion = [Microsoft.Exchange.WebServices.Data.ExchangeVersion]::Exchange2010_SP2
- ## 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
- ## 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
- $Script:rptCollection = @()
- function Process-Mailbox{
- param (
- $SmtpAddress = "$( throw 'SMTPAddress is a mandatory Parameter' )"
- )
- process{
- Write-Host ("Processing Mailbox : " + $SmtpAddress)
- # Bind to the Inbox Folder
- $folderid= new-object Microsoft.Exchange.WebServices.Data.FolderId([Microsoft.Exchange.WebServices.Data.WellKnownFolderName]::Inbox,$SmtpAddress)
- $Inbox = [Microsoft.Exchange.WebServices.Data.Folder]::Bind($service,$folderid)
- $Range = [system.DateTime]::Now.AddDays(-$DaysBack).ToString("MM/dd/yyyy") + ".." + [system.DateTime]::Now.AddDays(1).ToString("MM/dd/yyyy")
- $AQSString1 = "System.Message.DateReceived:" + $Range
- $AQSString2 = "(" + $AQSString1 + ") AND (isread:false)"
- $ivItemView = New-Object Microsoft.Exchange.WebServices.Data.ItemView(1)
- $allMail = $Inbox.FindItems($AQSString1,$ivItemView)
- $ivItemView = New-Object Microsoft.Exchange.WebServices.Data.ItemView(1)
- $unread = $Inbox.FindItems($AQSString2,$ivItemView)
- $rptObj = "" | Select MailboxName,TotalCount,Unread,PercentUnread,PercentGraph
- #Write-Host ("All Mail " + $allMail.TotalCount)
- #Write-Host ("Unread " + $unread.TotalCount)
- $rptObj.MailboxName = $SmtpAddress
- $rptObj.TotalCount = $allMail.TotalCount
- $rptObj.Unread = $unread.TotalCount
- $PercentUnread = 0
- if($unread.TotalCount -gt 0){
- $PercentUnread = [Math]::round((($unread.TotalCount/$allMail.TotalCount) * 100))
- }
- $rptObj.PercentUnread = $PercentUnread
- #Write-Host ("Percent Unread " + $PercentUnread)
- $ureadGraph = ""
- for($intval=0;$intval -lt 100;$intval+=4){
- if($PercentUnread -gt $intval){
- $ureadGraph += "▓"
- }
- else{
- $ureadGraph += "░"
- }
- }
- #Write-Host $ureadGraph
- $rptObj.PercentGraph = $ureadGraph
- $rptObj | fl
- $Script:rptCollection +=$rptObj
- }
- }
- Import-Csv -Path $csvFileName | ForEach-Object{
- if($service.url -eq $null){
- $service.AutodiscoverUrl($_.SmtpAddress,{$true})
- "Using CAS Server : " + $Service.url
- }
- Try{
- $service.ImpersonatedUserId = new-object Microsoft.Exchange.WebServices.Data.ImpersonatedUserId([Microsoft.Exchange.WebServices.Data.ConnectingIdType]::SmtpAddress, $_.SmtpAddress)
- Process-Mailbox -SmtpAddress $_.SmtpAddress
- }
- catch{
- Write-host ("Error processing Mailbox : " + $_.SmtpAddress + $_.Exception.Message.ToString())
- $Error.Clear()
- }
- }
- $Script:rptCollection | ft
- $Script:rptCollection | Export-Csv -NoTypeInformation -Path c:\temp\InboxUnreadReport.csv -Encoding UTF8