Note
Access to this page requires authorization. You can try signing in or changing directories.
Access to this page requires authorization. You can try changing directories.
Identifying users with large Exchange mailboxes is a task undertaken by most system administrators who are in need of freeing up space on their mail servers. While most search for mailboxes approaching a certain size, I wanted to take this a step further and identify the large folders within user mailboxes. An example of this would be to find all the users who have a large Deleted Items folder or Sent Items or Calendar that would be eligible to be cleaned out. It’s made to be run from a Remote Exchange Management Shell connection instead of by logging into an Exchange server via remote desktop and running such a shell manually.
Let’s get started by defining the function and parameters:
{
[CmdletBinding()]
param (
[Parameter(Mandatory = $False)]
[ValidateSet('All', 'Calendar', 'Contacts', 'ConversationHistory', 'DeletedItems', 'Drafts', 'Inbox', 'JunkEmail', 'Journal', 'LegacyArchiveJournals', 'ManagedCustomFolder', 'NonIpmRoot', 'Notes', 'Outbox', 'Personal', 'RecoverableItems', 'RssSubscriptions', 'SentItems', 'SyncIssues', 'Tasks')]
[string]$FolderScope = 'All',
[Parameter(Mandatory = $False)]
[int]$Top = 1,
[Parameter(Mandatory = $False,
Position = 1,
ValueFromPipeline = $True)]
[string]$Identity = '*'
)
}
This function is to be named Get-LargeFolder and takes three parameters.
- $FolderScope is used in the Get-MailboxFolderStatistics cmdlet and must belong to the set of values specified.
- $Top is an integer used to define how many results we’re going to return
- $Identity can be specified as an individual username to examine a specific mailbox, or left blank (defaulted to *) to examine the entire organization.
function Get-LargeFolder
{
[CmdletBinding()]
param (
[Parameter(Mandatory = $False)]
[ValidateSet('All', 'Calendar', 'Contacts', 'ConversationHistory', 'DeletedItems', 'Drafts', 'Inbox', 'JunkEmail', 'Journal', 'LegacyArchiveJournals', 'ManagedCustomFolder', 'NonIpmRoot', 'Notes', 'Outbox', 'Personal', 'RecoverableItems', 'RssSubscriptions', 'SentItems', 'SyncIssues', 'Tasks')]
[string]$FolderScope = 'All',
[Parameter(Mandatory = $False)]
[int]$Top = 1,
[Parameter(Mandatory = $False,
Position = 1,
ValueFromPipeline = $True)]
[string]$Identity = '*'
)
Get-Mailbox -Identity $Identity -ResultSize Unlimited |
Get-MailboxFolderStatistics -FolderScope $FolderScope
}
Next I’ve added a lines to retrieve all of my organizations mailboxes which I direct the data stream into a Get-MailboxFolderStatistics command with the FolderScope parameter set to the same value we passed to our function. Now we need to sort the results.
function Get-LargeFolder
{
[CmdletBinding()]
param (
[Parameter(Mandatory = $False)]
[ValidateSet('All', 'Calendar', 'Contacts', 'ConversationHistory', 'DeletedItems', 'Drafts', 'Inbox', 'JunkEmail', 'Journal', 'LegacyArchiveJournals', 'ManagedCustomFolder', 'NonIpmRoot', 'Notes', 'Outbox', 'Personal', 'RecoverableItems', 'RssSubscriptions', 'SentItems', 'SyncIssues', 'Tasks')]
[string]$FolderScope = 'All',
[Parameter(Mandatory = $False)]
[int]$Top = 1,
[Parameter(Mandatory = $False,
Position = 1,
ValueFromPipeline = $True)]
[string]$Identity = '*'
)
Get-Mailbox -Identity $Identity -ResultSize Unlimited |
Get-MailboxFolderStatistics -FolderScope $FolderScope |
Sort-Object -Property @{
e = {
$_.FolderSize.split('(').split(' ')[-2].replace(',','') -as [double]
}
} -Descending
}
The FolderSize parameter returns with a Get-MailboxFolderStatistics cmdlet which is a string to be split up to provide only the value in bytes which I am casting to a double. Once the stats have been gathered and set in order, they need to be selected so they can be returned.
The complete script is as follows:
function Get-LargeFolder
{
[CmdletBinding()]
param (
[Parameter(Mandatory = $False)]
[ValidateSet('All', 'Calendar', 'Contacts', 'ConversationHistory', 'DeletedItems', 'Drafts', 'Inbox', 'JunkEmail', 'Journal', 'LegacyArchiveJournals', 'ManagedCustomFolder', 'NonIpmRoot', 'Notes', 'Outbox', 'Personal', 'RecoverableItems', 'RssSubscriptions', 'SentItems', 'SyncIssues', 'Tasks')]
[string]$FolderScope = 'All',
[Parameter(Mandatory = $False)]
[int]$Top = 1,
[Parameter(Mandatory = $False,
Position = 1,
ValueFromPipeline = $True)]
[string]$Identity = '*'
)
Get-Mailbox -Identity $Identity -ResultSize Unlimited |
Get-MailboxFolderStatistics -FolderScope $FolderScope |
Sort-Object -Property @{
e = {
$_.FolderSize.split('(').split(' ')[-2].replace(',','') -as [double]
}
} -Descending |
Select-Object -Property @{
l = 'NameFolder'
e = {
$_.Identity.Split('/')[-1]
}
},
@{
l = 'FolderSize'
e = {
$_.FolderSize.split('(').split(' ')[-2].replace(',', '') -as [double]
}
} -First $Top
}
This can now be accomplished once completed:
#Get 25 largest Deleted Items folders in your organization
Get-LargeFolder -FolderScope 'DeletedItems' -Top 25
#Get my largest 10 folders
Get-LargeFolder -Identity ThmsRynr -Top 10
#Get the top 25 largest Deleted Items folder for users in a specific group
$arrLargeDelFolders = @()
(Get-ADGroupMember 'GroupName' -Recursive).SamAccountName | ForEach-Object -Process {
$arrLargeDelFolders += Get-LargeFolder -FolderScope 'DeletedItems' -Identity $_
}
$arrLargeDelFolders |
Sort-Object -Property FolderSize -Descending |
Select-Object -Property NameFolder, @{
l = 'FolderSize (Deleted Items)'
e = {
'{0:N0}' -f $_.FolderSize
}
} -First 25 |
Format-Table -AutoSize