Design sans titre

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.

cap 1

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

YOUR COMP

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.

Ok 1

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.

OK 2

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

Ok 3

Choosing “Yes” will disconnect you from Exchange.

Ok 4

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.

f5

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.

processing
ddd

Here’s what the report looks like.

tableur

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

mailbox

Share This Post

More To Explore

Insights & Blogs

Cybersecurity directives: Get (and stay) compliant

Cybersecurity standards: Get (and stay) compliant For some companies, compliance to certain standards is key (or mandatory) to their business and reputation. International standard for