Lucas Zuege's Blog

Using PowerShell to check the Mailbox size of a user in Exchange

As a Microsoft 365 Admin, dealing with Exchange is something that I do on a daily basis. As someone who doesn't like to use the Exchange Online Admin Center too often, I usually stick to using PowerShell to administrate the Exchange Online environment.

In this article, we will be discussing how to check Mailbox Size of a user, and create a nifty script that you can use!

Commands

Get-MailboxStatistics

This command is perfect for those who have an on-prem Exchange server. It can also be used with Exchange Online, though it is not preferred.

Get Mailbox Statistics of a single user

Get-MailboxStatistics -Identity <DisplayName or Email Address>

Using the above command, you can get the statistics of a single user's mailbox. You can pipe the command to Select-Object to better define what information you want to grab...

Get-MailboxStatistics -Identinty <DisplayName or Email Address> | Select DisplayName, TotalItemSize, TotalDeletedItemSize, ItemCount, DeletedItemCount

The above command will result in something that looks like...

PS C:\Users\<UserName> Get-MailboxStatistics -Identity user@email.com | Select DisplayName, TotalItemSize, TotalDeletedItemSize, ItemCount, DeletedItemCount


DisplayName          : User Email
TotalItemSize        : 3.311 GB (3,555,611,372 bytes)
TotalDeletedItemSize : 215.8 MB (226,242,911 bytes)
ItemCount            : 19868
DeletedItemCount     : 3499

As you can see, we can see the Total Item Size, which is the current size of the users mailbox. I also threw in a couple of other good-to-know statistics as well.

Get-EXOMailboxStatistics

This command is perfect for Exchange Online environments. If you are searching for a mailbox that is cloud-only, this command will work best. It works essentially the same as the Get-MailboxStatistics command, however, it is focused solely on Exchange Online.

Get Mailbox Statistics of a single user

Get-EXOMailboxStatistics -Identity <DisplayName or Email Address>

Using the above command will get you the statistics of the users mailbox. Much like the previous command, you can pipe the command and select specific properties to receive. If you want Mailbox size, you can utilize the same Properties as below...

Get-EXOMailboxStatistics -Identinty <DisplayName or Email Address> | Select DisplayName, TotalItemSize, TotalDeletedItemSize, ItemCount, DeletedItemCount

Which will result in...

PS C:\Users\<UserName> Get-EXOMailboxStatistics -Identity user@email.com | Select DisplayName, TotalItemSize, TotalDeletedItemSize, ItemCount, DeletedItemCount


DisplayName          : User Email
TotalItemSize        : 3.311 GB (3,555,611,372 bytes)
TotalDeletedItemSize : 215.8 MB (226,242,911 bytes)
ItemCount            : 19868
DeletedItemCount     : 3499

Creating a script

Now that we know what commands we need to run, we can go ahead and create a simple script.

The script we will be creating is specific to Exchange Online, however, it should be able to be used with an On-Prem Exchange Server as well. You will likely need to adjust the script.

The script will do the following...

Let us begin.

Connecting to Exchange Online

First, we will need to prompt the user to connect to Exchange Online. This can be done by utilizing the following.

# Check if Exchange Online Module is installed
Write-Host "Checking if Exchange Online PowerShell is loaded."

if (!(Get-InstalledModule -Name ExchangeOnlineManagement)){
        Write-Host "Exchange Online PowerShell is not installed. Please install the ExchangeOnlineManagement PowerShell module - https://www.powershellgallery.com/packages/ExchangeOnlineManagement/"
        Write-Warning "Pressing enter will exit the script."
        pause
        exit
}

# Import the Exchange Online PowerShell Module if it is installed
Import-Module -Name ExchangeOnlineManagement

# Connect to Exchange Online
Write-Host "Connecting to Exchange Online..."
Connect-ExchangeOnline

The above will check to see if the Exchange Online PowerShell module is installed. If it is not installed, it will prompt the user to install the PowerShell module and exit the script.

If Exchange Online PowerShell is installed, the script will go ahead and import it, and then run the command to initiate the connection to Exchange Online.

Get Mailbox Information

Now that we are connected to Exchange Online, we need to ask for the email address of the target mailbox, run the command against that target mailbox, and then display the results.

Input Email

# Ask for email address
$userToGetMailbox = Read-Host "Please enter in the email of the target Mailbox"

Looking at the above PowerShell, we start by asking the user to input the target's email address. This is done with Read-Host to a variable.

Running the command

# Run the command on the Email Address Provided
try {
    Write-Host "Mailbox Size of $userToGetMailbox"
    Get-EXOMailboxStatistics -Identity $userToGetMailbox | Select DisplayName, TotalItemSize, TotalDeletedItemSize
} catch {
    $currentPath = (Get-Location).Path
    Write-Host "Unable to get Mailbox Statistics of $userToGetMailbox. To see errors, Please check the log file -> $currentPath\Logs\Exchange\Get-MailboxSize.log."
    $path = ".\Logs\Exchange"
    if(-not (test-path $path)){
        New-Item -Path $path -ItemType Directory
    }
    $currentTime = Get-Date -Format "MM/dd/yyyy hh:mmtt"
    Write-Output "$currentTime : $_" | Out-file .\Logs\Exchange\Get-MailboxSize.log -Append
}

pause

After the email address is entered, it is time to run the Get-EXOMailboxStatistics command.

Since we want to have some error checking capabilities, we end up using a try/catch. We try to run Get-EXOMailboxStatistics, and if it succeeds, it will display the target's Display Name, Mailbox Size, and Deleted Items Size.

If Get-EXOMailboxStatistics is unable to run correctly, then we will catch the error. If you look at the above code, and look in the catch section of it, you will see the following:

$currentPath = (Get-Location).Path
Write-Host "Unable to get Mailbox Statistics of $userToGetMailbox. To see errors, Please check the log file -> $currentPath\Logs\Exchange\Get-MailboxSize.log."
$path = ".\Logs\Exchange"
if(-not (test-path $path)){
    New-Item -Path $path -ItemType Directory
}
$currentTime = Get-Date -Format "MM/dd/yyyy hh:mmtt"
Write-Output "$currentTime : $_" | Out-file .\Logs\Exchange\Get-MailboxSize.log -Append

Since all of my scripts are part of a bundle that my co-workers utilize, I dump errors to log files located in the scripts directories. These log files can then easily be shared to review and figure out why the script did not work correctly.

Firstly, I pull the current path of the scripts, and place it in the $currentPath variable.

$currentPath = (Get-Location).Path

After that, I write a message to the terminal, indicating there was an error, and where the person using the script can view the log file.

Write-Host "Unable to get Mailbox Statistics of $userToGetMailbox. To see errors, Please check the log file -> $currentPath\Logs\Exchange\Get-MailboxSize.log."

After that message is sent out, I create the $path variable, which is where the Log file will end up.

$path = ".\Logs\Exchange"

I test for the path, if it is not there, I create the directory.

if(-not (test-path $path)){
    New-Item -Path $path -ItemType Directory
}

Continuing on, I pull the current time as too when the script runs.

$currentTime = Get-Date -Format "MM/dd/yyyy hh:mmtt"

And then, I output everything to the log file.

Write-Output "$currentTime : $_" | Out-file .\Logs\Exchange\Get-MailboxSize.log -Append

After the script runs, whether it be successful or with errors, there is a pause at the end of the script. I put this there so that the one using my scripts can read all the terminal messages before exiting the script. It is up to you if you want to include it at the end or not.

Finalized Script

Fairly straight forward. Let us go ahead and put everything together.

# Check if Exchange Online Module is installed
Write-Host "Checking if Exchange Online PowerShell is loaded."

if (!(Get-InstalledModule -Name ExchangeOnlineManagement)){
        Write-Host "Exchange Online PowerShell is not installed. Please install the ExchangeOnlineManagement PowerShell module - https://www.powershellgallery.com/packages/ExchangeOnlineManagement/"
        Write-Warning "Pressing enter will exit the script."
        pause
        exit
}

# Import the Exchange Online PowerShell Module if it is installed
Import-Module -Name ExchangeOnlineManagement

# Connect to Exchange Online
Write-Host "Connecting to Exchange Online..."
Connect-ExchangeOnline

# Ask for email address
$userToGetMailbox = Read-Host "Please enter in the email of the target Mailbox"

# Run the command on the Email Address Provided
try {
    $mailboxInfo = Get-EXOMailboxStatistics -Identity $userToGetMailbox
} catch {
    $currentPath = (Get-Location).Path
    Write-Host "Unable to get Mailbox Statistics of $userToGetMailbox. To see errors, Please check the log file -> $currentPath\Logs\Exchange\Get-MailboxSize.log."
    $path = ".\Logs\Exchange"
    if(-not (test-path $path)){
        New-Item -Path $path -ItemType Directory
    }
    $currentTime = Get-Date -Format "MM/dd/yyyy hh:mmtt"
    Write-Output "$currentTime : $_" | Out-file .\Logs\Exchange\Get-MailboxSize.log -Append
}

# Display necessary information to the console
Write-Host "`nMailbox Size of $userToGetMailbox" `n
Write-Host "Display Name: " $mailboxInfo.DisplayName
Write-Host "Total Item Size: " $mailboxInfo.TotalItemSize
Write-Host "Total Deleted Item Size: " $mailboxInfo.TotalDeletedItemSize

pause

Feel free to modify it how you see fit! If you have any suggestions to making the script better, feel free to email me at lucas@zue.ge, or comment below! I am always learning better ways at making my scripts better, so I am always open to help!

#Guides #PowerShell #Programming