Featured image of extracting mailbox size using powershell

How to Extract the Mailbox Size using PowerShell

Get the mailbox size of an individual user

Copy the code below and paste it into PowerShell.

				
					param(
    [Parameter(
    Mandatory = $true,
    HelpMessage = "Enter the Exchange Online or Global admin username"
    )]
    [string]$adminUPN)
    
Function ConnectTo-EXO {
    <#
        .SYNOPSIS
        Connects to EXO when no connection exists. Checks for EXO v2 module
    #>

    process {
        # Check if EXO is installed and connect if no connection exists
        if ($null -eq (Get-Module -ListAvailable -Name ExchangeOnlineManagement)) {
            Write-Host "Exchange Online PowerShell v2 module is required, do you want to install it?" -ForegroundColor Yellow 
            $install = Read-Host Do you want to install the module? [Y] Yes [N] No 
            if($install -match "[yY]") { 
                Write-Host "Installing Exchange Online PowerShell v2 module" -ForegroundColor Cyan
                Install-Module ExchangeOnlineManagement -Repository PSGallery -AllowClobber -Force
            } 
            else {
                Write-Error "Please install EXO v2 module."
            }
        }

        if ($null -ne (Get-Module -ListAvailable -Name ExchangeOnlineManagement)) {
            # Check if there is an active EXO sessions
            $psSessions = Get-PSSession | Select-Object -Property State, Name
            If (((@($psSessions) -like '@{State=Opened; Name=ExchangeOnlineInternalSession*').Count -gt 0) -ne $true) {
                Connect-ExchangeOnline -UserPrincipalName $adminUPN
            }
        }
        else {
            Write-Error "Please install EXO v2 module."
        }
    }
}

Function Get-MailboxStat {
    $email = Read-Host "Please enter the email address"
    Get-MailboxFolderStatistics $email -FolderScope RecoverableItems | FL Name,FolderAndSubfolderSize,ItemsInFolderAndSubfolders
    # Close Exchange Online Connection
    $close = Read-Host Close Exchange Online connection? [Y] Yes [N] No
    if ($close -match "[yY]") {
        Disconnect-ExchangeOnline -Confirm:$false | Out-Null
    }
    else {
        Get-MailboxStat
    }
}

ConnectTo-EXO
Get-MailboxStat
				
			

The code above will automatically check if you have the modules required to run the script. If you haven’t installed it yet, it will prompt installation.

Once you pasted it, it will ask for the email that you will use.

Once pasted, PowerShell will ask for the email that you will use

A new window will pop up and it will ask you to enter your password.

A new window will pop up and it will ask you to enter your password.

Enter the email address of the user that you want to check the mailbox size. If the message “Please enter the email address” didn’t show, just press Enter on your keyboard.

Enter the email address of the user that you want to check the mailbox size. If the message "Please enter the email address" didn't show, just press Enter on your keyboard.

After that, it will show you all the details of the mailbox at that specific address. It will then ask you if you want to close now the Exchange connection.

After that, it will show you all the details of the mailbox at that specific address. It will then ask you if you want to close now the Exchange connection.

Choosing “No” will ask for the new email address that you want to check.

Choosing "No" will ask for the new email address that you want to check.

Choosing “Yes” will disconnect you from Exchange.

Choosing "Yes" will disconnect you from Exchange.

Get the mailbox size from the whole organization and save it as CSV

Copy the code below and paste it into PowerShell ISE.

				
					A few reminders:

The code below only works in IDE like Windows PowerShell ISE or Visual Studio Code. You will get an error if you run it in PowerShell CLI.
Make sure to change the path to your computer name.
[string]$path = "C:\Users\<Hostname>\Downloads\MailboxSizeReport-$((Get-Date -format "MMM-dd-yyyy").ToString()).csv"
Alternatively, you can also set where you want to save the file each time you run the script. Just set the parameter to true.
[Parameter(
    Mandatory = $true,
    HelpMessage = "Enter the path to save the CSV file"
)]
				
			
				
					param(
  [Parameter(
    Mandatory = $true,
    HelpMessage = "Enter the Exchange Online or Global admin username"
  )]
  [string]$adminUPN,

  [Parameter(
    Mandatory = $false,
    HelpMessage = "Get (only) Shared Mailboxes or not. The default include them"
  )]
  [ValidateSet("no", "only", "include")]
  [string]$sharedMailboxes = "include",

  [Parameter(
    Mandatory = $false,
    HelpMessage = "Include Archive mailboxes"
  )]
  [switch]$archive = $true,

  [Parameter(
    Mandatory = $false,
    HelpMessage = "Enter the path to save the CSV file"
  )]
  [string]$path = "C:\Users\AldrinRAMIREZ\Downloads\MailboxSizeReport-$((Get-Date -format "MMM-dd-yyyy").ToString()).csv"
)

Function ConnectTo-EXO {
  <#
    .SYNOPSIS
        Connects to EXO when no connection exists. Checks for EXO v2 module
  #>
  
  process {
    # Check if EXO is installed and connect if no connection exists
    if ($null -eq (Get-Module -ListAvailable -Name ExchangeOnlineManagement))
    {
      Write-Host "Exchange Online PowerShell v2 module is required, do you want to install it?" -ForegroundColor Yellow
      
      $install = Read-Host Do you want to install the module? [Y] Yes [N] No 
      if($install -match "[yY]") 
      { 
        Write-Host "Installing Exchange Online PowerShell v2 module" -ForegroundColor Cyan
        Install-Module ExchangeOnlineManagement -Repository PSGallery -AllowClobber -Force
      } 
      else
      {
       Write-Error "Please install EXO v2 module."
      }
    }


    if ($null -ne (Get-Module -ListAvailable -Name ExchangeOnlineManagement)) 
    {
     # Check if there is an active EXO sessions
     $psSessions = Get-PSSession | Select-Object -Property State, Name
     If (((@($psSessions) -like '@{State=Opened; Name=ExchangeOnlineInternalSession*').Count -gt 0) -ne $true) {
      Connect-ExchangeOnline -UserPrincipalName $adminUPN
     }
    }
    else{
      Write-Error "Please install EXO v2 module."
    }
  }
}

Function Get-Mailboxes {
  <#
    .SYNOPSIS
        Get all the mailboxes for the report
  #>
  process {
    switch ($sharedMailboxes)
    {
      "include" {$mailboxTypes = "UserMailbox,SharedMailbox"}
      "only" {$mailboxTypes = "SharedMailbox"}
      "no" {$mailboxTypes = "UserMailbox"}
    }

    Get-EXOMailbox -ResultSize unlimited -RecipientTypeDetails $mailboxTypes -Properties IssueWarningQuota, ProhibitSendReceiveQuota, ArchiveQuota, ArchiveWarningQuota, ArchiveDatabase | 
      Select-Object UserPrincipalName, DisplayName, PrimarySMTPAddress, RecipientType, RecipientTypeDetails, IssueWarningQuota, ProhibitSendReceiveQuota, ArchiveQuota, ArchiveWarningQuota, ArchiveDatabase
  }
}

Function ConvertTo-Gb {
  <#
    .SYNOPSIS
        Convert mailbox size to Gb for uniform reporting.
  #>
  param(
    [Parameter(
      Mandatory = $true
    )]
    [string]$size
  )
  process {
    if ($size -ne $null) {
      $value = $size.Split(" ")

      switch($value[1]) {
        "GB" {$sizeInGb = ($value[0])}
        "MB" {$sizeInGb = ($value[0] / 1024)}
        "KB" {$sizeInGb = ($value[0] / 1024 / 1024)}
      }

      return [Math]::Round($sizeInGb,2,[MidPointRounding]::AwayFromZero)
    }
  }
}


Function Get-MailboxStats {
  <#
    .SYNOPSIS
        Get the mailbox size and quota
  #>
  process {
    $mailboxes = Get-Mailboxes
    $i = 0

    $mailboxes | ForEach-Object {

      # Get mailbox size     
      $mailboxSize = Get-MailboxStatistics -identity $_.UserPrincipalName | Select-Object TotalItemSize,TotalDeletedItemSize,ItemCount,DeletedItemCount,LastUserActionTime

      if ($null -ne $mailboxSize) {
      
        # Get archive size if it exists and is requested
        $archiveSize = 0
        $archiveResult = $null

        if ($archive.IsPresent -and ($null -ne $_.ArchiveDatabase)) {
          $archiveResult = Get-EXOMailboxStatistics -UserPrincipalName $_.UserPrincipalName -Archive | Select-Object ItemCount,DeletedItemCount,@{Name = "TotalArchiveSize"; Expression = {$_.TotalItemSize.ToString().Split("(")[0]}}
          if ($null -ne $archiveResult) {
            $archiveSize = ConvertTo-Gb -size $archiveResult.TotalArchiveSize
          }else{
            $archiveSize = 0
          }
        }  
    
        [pscustomobject]@{
          "Display Name" = $_.DisplayName
          "Email Address" = $_.PrimarySMTPAddress
          "Mailbox Type" = $_.RecipientTypeDetails
          "Last User Action Time" = $mailboxSize.LastUserActionTime
          "Total Size (GB)" = ConvertTo-Gb -size $mailboxSize.TotalItemSize.ToString().Split("(")[0]
          "Deleted Items Size (GB)" = ConvertTo-Gb -size $mailboxSize.TotalDeletedItemSize.ToString().Split("(")[0]
          "Item Count" = $mailboxSize.ItemCount
          "Deleted Items Count" = $mailboxSize.DeletedItemCount
          "Mailbox Warning Quota (GB)" = $_.IssueWarningQuota.ToString().Split("(")[0]
          "Max Mailbox Size (GB)" = $_.ProhibitSendReceiveQuota.ToString().Split("(")[0]
          "Archive Size (GB)" = $archiveSize
          "Archive Items Count" = $archiveResult.ItemCount
          "Archive Deleted Items Count" = $archiveResult.DeletedItemCount
          "Archive Warning Quota (GB)" = $_.ArchiveWarningQuota.ToString().Split("(")[0]
          "Archive Quota (GB)" = ConvertTo-Gb -size $_.ArchiveQuota.ToString().Split("(")[0]
        }

        $currentUser = $_.DisplayName
        Write-Progress -Activity "Collecting mailbox status" -Status "Current Count: $i" -PercentComplete (($i / $mailboxes.Count) * 100) -CurrentOperation "Processing mailbox: $currentUser"
        $i++;
      }
    }
  }
}

# Connect to Exchange Online
ConnectTo-EXO

# Get mailbox status
Get-MailboxStats | Export-CSV -Path $path -NoTypeInformation -Encoding UTF8

if ((Get-Item $path).Length -gt 0) {
  Write-Host "Report finished and saved in $path" -ForegroundColor Green
  $prompt = New-Object -ComObject wscript.shell
  $userInput = $prompt.Popup("Do you want to open the CSV file?",0,"Mailbox Size Report",4)   
  If ($userInput -eq 6)   
  {   
   Invoke-Item "$path"
  } 
}else{
  Write-Host "Failed to create report" -ForegroundColor Red
}


# Close Exchange Online Connection
$close = Read-Host Close Exchange Online connection? [Y] Yes [N] No 

if ($close -match "[yY]") {
  Disconnect-ExchangeOnline -Confirm:$false | Out-Null
}
				
			

The code above will automatically check if you have the modules required to run the script. If you haven’t installed it yet, it will prompt installation.

After pasting the code, you need to either press F5 or click on the Play button.

After pasting the code, you need to either press F5 or click on the Play button.

The login is the same as the screenshots above. After that, it will now get all the mailbox sizes from all the users. It will take some time depending on the number of users in the organization. Do not close the Window and just wait for it.

Once it’s done, it will ask if you want to open the file.

After that, it will now get all the mailbox sizes from all the users. It will take some time depending on the number of users in the organization. Do not close the Window and just wait for it. Once it's done, it will ask if you want to open the file part 1.
After that, it will now get all the mailbox sizes from all the users. It will take some time depending on the number of users in the organization. Do not close the Window and just wait for it. Once it's done, it will ask if you want to open the file part 2.

Here’s what the report looks like.

Here's what the report looks like.

Once you’re done, kindly disconnect your connection to Exchange Online.

Once you're done, kindly disconnect your connection to Exchange Online.

Share This Post

More To Explore

Insights & Blogs

Debunking Myths About Co-Managed IT Support

Dive into the reality behind common misconceptions about co-managed IT support and why companies with in-house IT teams should readily adopt it. Contrary to popular belief, teaming up with an IT partner doesn’t entail outsourcing your entire IT department. Learn about the myths hindering the optimization of your IT strategy.

Insights & Blogs

Vital Role of Reliable Help Desk Support for Businesses

A reliable help desk support team is paramount for businesses of all sizes. Efficient IT systems are the backbone of operations, and when issues arise, a dependable help desk swiftly resolves them, minimizing disruptions. Moreover, quick access to assistance enhances customer satisfaction, fostering loyalty and repeat business. It’s the backbone of operational excellence.