A client approached me with a need for some mailbox statistics. They wanted a script or some sort of PowerShell code to examine a few mailbox details for a migration from one environment to another that was being processed with third party tools. The source environment was running Exchange Server 2010. This means PowerShell 2.0. Now, I’ve written code for Exchange since Exchange 2007 came out. However, I learned a valuable lesson for these scripts. Test in the same version of Exchange. Yes. Obvious. Maybe even Captain Obvious level here…. However, I didn’t have an Exchange 2010 server with actual verifiable data I could use in my example.
So what did I do? I used Exchange 2013. I had data. I had calendar items, tasks, you name it. The cmdlets I was using are the same for both versions. Well “same” has a different meaning in Exchange PowerShell. So what happened? Lot’s of red. Basically Exchange 2010 wasn’t able to use the same parameters and switches like 2010 did. So I ended up rewriting the script to run on both 2010 and 2013, which would then make it more versatile. The script was also validated to run on Exchange 2016 in a lab.
Scripts
First is the script that will run on either 2010 or 2013. This script will provide a summary of all mailboxes in an environment.
### EXCHANGE 2010, EXCHANGE 2013 and EXCHANGE 2016 ###
$TotalSize = 0 $Mailboxes = Get-Mailbox -ResultSize Unlimited $Mailboxes | Foreach-Object { $Statistics = $Null $Size = $Null $Statistics = (Get-MailboxStatistics $_).TotalItemSize If ($Statistics -like '* B *') { $Bytes = $Statistics -Split " " $Byte = $Bytes[0] If ($Byte -ne 0) { $Size = $Byte/1024/1024 } } If ($Statistics -like '* KB *') { $KiloBytes = $Statistics -Split " " $KiloByte = $KiloBytes[0] If ($KiloByte -ne 0) { $Size = $KiloByte/1024 } } If ($Statistics -like '* MB *') { $MegaBytes = $Statistics -Split " " $MegaByte = $MegaBytes[0] If ($MEgaByte -ne 0) { $Size = $MegaByte } } If ($Statistics -like '* GB *') { $GigaBytes = $Statistics -Split " " $GigaByte = $GigaBytes[0] If ($GigaByte -ne 0) { $Size = [int]$GigaByte*1024 } } $TotalSize += $Size } # Round to two decimal places $Rounded = [math]::Round($TotalSize, 2) # Report size in MegaBytes Write-Host "All mailboxes are $Rounded MB in size."
This next script will provide task and calendar item totals for Exchange 2010 only:
### EXCHANGE 2010 ONLY ###
$Mailboxes = Get-Mailbox -ResultSize Unlimited $Mailboxes | Foreach-Object { $TotalItems = (Get-Mailbox $_ |Get-MailboxFolderStatistics –FolderScope ‘Calendar’).itemsinfolder $CalTotal += $TotalItems $TotalItems2 = (Get-Mailbox $_ |Get-MailboxFolderStatistics –FolderScope ‘Tasks’).itemsinfolder $TaskTotal += $TotalItems2 } } Write-Host "Total Calendar items is $CalTotal." Write-Host "Total Task items is $TaskTotal."
This next script will provide task and calendar item totals as well as total size for all mailboxes for Exchange 2013 only:
### EXCHANGE 2013/2016 ###
$CalItems = (Get-Mailbox |Get-MailboxFolderStatistics –FolderScope ‘Calendar’).itemsinfolder foreach ($item in $CalItems) {$CalTotal += $item} Write-Host "Total Calendar items is $CalTotal." $TaskItems = (Get-Mailbox |Get-MailboxFolderStatistics –FolderScope ‘Tasks’).itemsinfolder foreach ($item in $TaskItems) {$TaskTotal += $item} Write-Host "Total Task items is $TaskTotal." $totalsize = 0 $mbxs = Get-Mailbox $mbxs | Foreach-Object { $totalsize += (Get-MailboxStatistics $_).TotalItemSize } $Value = $totalsize.Value Write-Host "All mailboxes are $Value in size."
As you can see from the code, the syntax is a bit different between 2010 and 2013.