Get-MailboxSize.psm1

function Get-MailboxSize {
    [cmdletbinding(DefaultParameterSetName = 'All Mailboxes')]
    <#
    .SYNOPSIS
    Retrieves mailbox size information for individual or all mailboxes in the organization,
    with options to filter and format the output.
 
    .DESCRIPTION
    The Get-MailboxSize function provides mailbox size information by leveraging Exchange Online cmdlets.
    It supports retrieving the size of a specific mailbox or all mailboxes, with the ability to filter results
    based on recipient type or minimum total item size. The output size format can be customized to various units,
    such as GB, MB, KB, Bytes, or TB.
 
    .PARAMETER Identity
    Specifies the identity of the individual mailbox to retrieve size information.
    The Identity can be the mailbox's Name, Alias, DN, Email address, LegacyExchangeDN, or SamAccountName.
 
    .PARAMETER ItemSizeFormat
    Specifies the format for the total item size output. Available formats include Bytes, KB, MB, GB, and TB.
    The default is 'GB'. This parameter works with both individual and all mailboxes.
 
    .PARAMETER RecipientTypeDetails
    Specifies the recipient type to filter mailboxes. Options include UserMailbox, RoomMailbox, SharedMailbox,
    DiscoveryMailbox, and SchedulingMailbox. The default is 'UserMailbox'.
    This parameter is only available when querying all mailboxes.
 
    .PARAMETER TotalItemSizeMinimum
    Specifies the minimum total item size (in GB) for filtering mailboxes.
    Only mailboxes with a total item size greater than or equal to this value will be included in the results.
    This parameter is only available when querying all mailboxes.
 
    .EXAMPLE
    Get-MailboxSize -Identity "johndoe@example.com"
 
    Retrieves the size information for the mailbox associated with the
    user "johndoe@example.com" in the default size format (GB).
 
    .EXAMPLE
    Get-MailboxSize -ItemSizeFormat MB
 
    Retrieves size information for all user mailboxes, with the output size formatted in MB.
 
    .EXAMPLE
    Get-MailboxSize -RecipientTypeDetails SharedMailbox -TotalItemSizeMinimum 50
 
    Retrieves size information for all shared mailboxes with a total item size of 50 GB or more,
    with the output size formatted in the default unit (GB).
 
    .NOTES
    This function requires Exchange Online PowerShell module. The function performs filtering and
    formatting operations, and progress is displayed when querying all mailboxes.
    #>

    param(
        [parameter(
            Position = 0,
            ParameterSetName = 'Individual Mailbox',
            HelpMessage = "Specify the identity (Name, DN, Email address, or SamAccountName) of the individual mailbox to retrieve size information."
        )]
        [string]$Identity,

        [parameter(
            ParameterSetName = 'Individual Mailbox',
            HelpMessage = "Specify the format for the total item size output. The default is 'GB'."
        )]
        [parameter(ParameterSetName = 'All Mailboxes')]
        [parameter(ParameterSetName = 'Filter')]
        [validateset('Bytes', 'TB', 'GB', 'KB', 'MB')]
        $ItemSizeFormat,

        [parameter(
            ParameterSetName = 'All Mailboxes',
            HelpMessage = "Filter mailboxes by recipient type. Default is UserMailBox."
        )]
        [validateset('UserMailbox', 'RoomMailbox', 'SharedMailbox', 'DiscoveryMailbox', 'SchedulingMailbox')]
        $RecipientTypeDetails,

        [parameter(
            ParameterSetName = 'All Mailboxes',
            HelpMessage = "Specify the minimum total item size (in GB) to filter mailboxes."
        )]
        [parameter(ParameterSetName = 'Filter')]
        [int]$TotalItemSizeMinimum,
        [parameter(ParameterSetName = 'All Mailboxes')]
        [parameter(ParameterSetName = 'Filter')]
        $Filter
    )


    function Add-ConvertedSizeToProperties {
        param(
            $obj,
            $itemSize,
            $deletedItemSize,
            $format
        )

        $obj | ForEach-Object {
            $_.PSObject.Properties.Remove('TotalItemSize')
            $_.PSObject.Properties.Remove('TotalDeletedItemSize')
            $_ | Add-Member -MemberType NoteProperty -Name "TotalItemSize" -Value $itemSize
            $_ | Add-Member -MemberType NoteProperty -Name "TotalDeletedItemSize" -Value $deletedItemSize
        }
        return $obj
    }
    

    function ConvertTo-FormattedSize {
        param(
            $mailbox
        )

        $conversionMethods = @{
            'Bytes' = 'ToBytes'
            'KB' = 'ToKB'
            'MB' = 'ToMB'
            'GB' = 'ToGB'
            'TB' = 'ToTB'
        }

        $selectedConversionMethod = $conversionMethods[$ItemSizeFormat]
        $convertedItemSize = $mailbox.TotalItemSize.Value.$selectedConversionMethod()
        $convertedDeletedItemSize = $mailbox.TotalDeletedItemSize.Value.$selectedConversionMethod()
        Add-ConvertedSizeToProperties -obj $mailbox -itemSize $convertedItemSize -deletedItemSize $convertedDeletedItemSize -format $ItemSizeFormat  
    }


    $output = if ($PSBoundParameters.Keys -eq "Identity") {
        Get-EXOMailboxStatistics -Identity $Identity -PropertySets Minimum
    }
    else {
        Write-Verbose "Retrieving all mail boxes. Running: Get-EXOMailbox"
        $mailbox = if ($PSBoundParameters.Keys -eq "Filter") {
            Get-EXOMailbox -ResultSize Unlimited -Filter $Filter
        }
        else {
            if ($PSBoundParameters.Keys -eq "RecipientTypeDetails") {
                Get-EXOMailbox -ResultSize Unlimited -RecipientTypeDetails $RecipientTypeDetails
            }
            else { Get-EXOMailbox -ResultSize Unlimited }
        }
        [int]$mailboxCount = $mailbox.Count
        $i = 1
        $results = $mailbox | ForEach-Object {
            Write-Progress -Id 1 -Activity "$i of $mailboxCount"
            Get-EXOMailboxStatistics -Identity $_.Guid -PropertySets Minimum
            $i++
        }

        if ($PSBoundParameters.Keys -eq "TotalItemSizeMinimum") {
            $results | Where-Object { $_.TotalItemSize.Value -ge "${TotalItemSizeMinimum}GB" }
        }
        else { $results }
    }

    if ($PSBoundParameters.Keys -eq "ItemSizeFormat") {
        $output | ForEach-Object {
            ConvertTo-FormattedSize -mailbox $_
        }
    }
    else { return $output }
}