MailboxDistribution.psm1
#region Get-MailboxesPerServer Function Get-MailboxesPerServer { <# .SYNOPSIS Get the number of mailboxes per server. .DESCRIPTION The Get-MailboxesPerServer cmdlet returns the total number of mailboxes per server. .PARAMETER Server The name of the exchange server. .EXAMPLE Get-MailboxesPerServer -Server Exchange2013 This command will return the number of mailboxes on server Exchange2013 .EXAMPLE Get-MailboxServer | Get-MailboxesPerServer This command will return the number of mailboxes on all mailbox servers, per server. #> [cmdletBinding()] Param ( [Parameter(Mandatory = $false, Position = 0, ValueFromPipeline = $true, ValueFromPipelineByPropertyName = $true)] [Alias('Name')] [string[]]$Server = $env:COMPUTERNAME, # Include AutoSuspended mailboxes [Parameter(Mandatory = $false, Position = 1)] [switch]$IncludeAutoSuspended ) Begin { try { Get-Command "Get-Mailbox" -ErrorAction Stop | Out-Null } catch { Throw "Could not find the Exchange cmdlets." } #region Get the move requests if($IncludeAutoSuspended) { Write-Verbose "Getting AutoSuspended move requests." $moveRequests = Get-MoveRequest -MoveStatus "AutoSuspended" -ResultSize Unlimited } #endregion } Process { # Loop through the servers foreach($s in $Server) { # Get the databases Write-Verbose ("Getting databases of server " + $s) $databases = Get-MailboxDatabaseCopyStatus -Server $s | Where-Object {$_.Status -eq "Mounted"} # Get the mailboxes on throse databases Write-Verbose ("Getting mailboxes of databases") $mailboxes = @() $autosuspended = 0 foreach($d in $databases) { Write-Verbose ("`tGetting mailboxes of database " + $d.DatabaseName) $mailboxes += Get-Mailbox -Database $d.DatabaseName if($IncludeAutoSuspended) { $autosuspended += @($moveRequests | Where-Object {$_.TargetDatabase -eq $d.DatabaseName}).Count } } # Create a custom object $obj = New-Object PSObject -Property @{ "Server" = $s "Mailboxes" = $mailboxes.Count } #region Get the autosuspended mailboxes of the server if($IncludeAutoSuspended) { Write-Verbose "Getting AutoSuspended mailboxes of $s" if($autosuspended -eq $null) { $autosuspended = 0 } $obj | Add-Member NoteProperty "AutoSuspendedMailboxes" $autosuspended } #endregion $obj } } End {} } #endregion #region Get-MailboxesPerDatabase Function Get-MailboxesPerDatabase { <# .SYNOPSIS Get the number of mailboxes per database. .DESCRIPTION The Get-MailboxesPerDatabase cmdlet returns the total number of mailboxes per database on an exchange server. .PARAMETER Server The name of the exchange server. .EXAMPLE Get-MailboxesPerDatabase -Server Exchange2013 This command will return the number of mailboxes per database on server Exchange2013 .EXAMPLE Get-MailboxServer | Get-MailboxesPerDatabase This command will return the number of mailboxes per database on all mailbox servers. #> [cmdletBinding()] Param ( [Parameter(Mandatory = $false, Position = 0, ValueFromPipeline = $true, ValueFromPipelineByPropertyName = $true)] [string[]]$Server = $env:COMPUTERNAME, # Include AutoSuspended mailboxes [Parameter(Mandatory = $false, Position = 1)] [switch]$IncludeAutoSuspended ) Begin { try { Get-Command "Get-Mailbox" -ErrorAction Stop | Out-Null } catch { Throw "Could not find the Exchange cmdlets." } #region Get the move requests if($IncludeAutoSuspended) { Write-Verbose "Getting AutoSuspended move requests." $moveRequests = Get-MoveRequest -MoveStatus "AutoSuspended" -ResultSize Unlimited } #endregion } Process { # Loop through the servers foreach($s in $Server) { # Get the databases Write-Verbose ("Getting databases of server " + $s) $databases = Get-MailboxDatabaseCopyStatus -Server $s | Where-Object {$_.Status -eq "Mounted"} # Loop through databases Write-Verbose ("Getting mailboxes of databases") foreach($d in $databases) { # Get the mailboxes Write-Verbose ("`tGetting mailboxes of database " + $d.DatabaseName) $mailboxes = @(Get-Mailbox -Database $d.DatabaseName) # The autosuspended mailboxes $autosuspended = 0 # Create a custom object $obj = New-Object PSObject $obj | Add-Member NoteProperty "Server" $s $obj | Add-Member NoteProperty "Database" $d.databasename $obj | Add-Member NoteProperty "Mailboxes" $mailboxes.Count if($IncludeAutoSuspended) { $autosuspended = @($moveRequests | Where-Object {$_.TargetDatabase -eq $d.DatabaseName}).Count if($autosuspended -eq $null) { $autosuspended = 0 } $obj | Add-Member NoteProperty "AutoSuspendedMailboxes" $autosuspended } $obj } } } End {} } #endregion #region Get-MilboxesPerDatabaseAvailabilityGroup Function Get-MailboxesPerDatabaseAvailabilityGroup { <# .Synopsis Get the mailbox distribution on DAGs .DESCRIPTION Get the mailbox distribution on Database Availability Groups, optionaly including AutoSuspended mailboxes. .EXAMPLE [PS] C:\>Get-MailboxesPerDatabaseAvailabilityGroup -DatabaseAvailabilityGroup DAG1 DAG Servers Databases Mailboxes --- ------- --------- --------- DAG1 8 18 851 Get the mailboxes on DAG1. .EXAMPLE [PS] C:\>Get-DatabaseAvailabilityGroup | Get-MailboxesPerDatabaseAvailabilityGroup DAG Servers Databases Mailboxes --- ------- --------- --------- DAG1 8 18 851 DAG2 4 9 259 Get the mailboxes on all Database Availability Groups .EXAMPLE [PS] C:\>Get-DatabaseAvailabilityGroup DAG1 | Get-MailboxesPerDatabaseAvailabilityGroup -IncludeAutoSuspended | Format-Table DAG Servers Databases Mailboxes AutoSuspendedMailboxes --- ------- --------- --------- ---------------------- DAG1 8 18 851 34 Get the mailboxes on DAG1 including the AutoSuspended. .NOTES The AutoSuspended mailboxes are not included in the database mailboxes. #> [cmdletBinding()] Param ( # The DAG to query [Parameter(Mandatory = $false, Position = 0, ValueFromPipeline = $true, ValueFromPipelineByPropertyName = $true)] [Alias('Name')] [string[]]$DatabaseAvailabilityGroup, # Include AutoSuspended mailboxes [Parameter(Mandatory = $false, Position = 1)] [switch]$IncludeAutoSuspended ) Begin { #region Environment Check # Check if Exchange cmdlets are available Write-Verbose "Checking for Exchange cmdlets." try { Get-Command "Get-DatabaseAvailabilityGroup" -ErrorAction Stop | Out-Null } catch { Throw "Could not find Exchange cmdlets." } #endregion #region Get the move requests if($IncludeAutoSuspended) { Write-Verbose "Getting AutoSuspended move requests." $moveRequests = Get-MoveRequest -MoveStatus "AutoSuspended" -ResultSize Unlimited } #endregion } Process { #region Get Database Availability Groups if($DatabaseAvailabilityGroup) { $dags = @() foreach($dagp in $DatabaseAvailabilityGroup) { try { Write-Verbose "Getting Database Availability Group $dagp." $dags += Get-DatabaseAvailabilityGroup $dagp -ErrorAction Stop } catch { Write-Error "Could not find a Database Availability Group for $dagp" } } } else { Write-Verbose "Getting Database Availability Groups." $dags = Get-DatabaseAvailabilityGroup } #endregion #region Process Each DAG foreach($d in $dags) { Write-Verbose "`tProcessing DAG $($d.Name)" #region Create a custom object per DAG $obj = New-Object psObject $obj | Add-Member NoteProperty "DAG" $d.Name #endregion #region Get the servers of the DAG Write-Verbose "`tGetting servers of $($d.Name)" # Exchange Shell and Implicit Remoting return different objects # and we need to check both $srvs = $d.Servers if($srvs.Name -ne $null) { $servers = $srvs.Name } else { $servers = $srvs } $obj | Add-Member NoteProperty "Servers" $servers.Count #endregion #region Get the databases on these servers Write-Verbose "`tGetting databases of $($d.Name)" $databases = $servers | %{ Get-MailboxDatabaseCopyStatus -Server $_ | Where-Object {$_.Status -eq "Mounted"} } | % DatabaseName $obj | Add-Member NoteProperty "Databases" $databases.count #endregion #region Get the mailboxes of the database Write-Verbose "`tGetting mailboxes of $($d.Name)" $mailboxes = $databases | %{ Get-mailbox -Database $_ -ResultSize unlimited} $obj | Add-Member NoteProperty "Mailboxes" $mailboxes.count #endregion #region Get the autosuspended mailboxes of the dag if($IncludeAutoSuspended) { Write-Verbose "Getting AutoSuspended mailboxes of $($d.Name)" $autosuspended = $moveRequests | Where-Object {$_.TargetDatabase -in $databases} $obj | Add-Member NoteProperty "AutoSuspendedMailboxes" $autosuspended.Count } #endregion # Send the custom object to the pipeline $obj } #endregion } End{} } #endregion #region Exports Export-ModuleMember -Function Get-MailboxesPerDatabase Export-ModuleMember -Function Get-MailboxesPerServer Export-ModuleMember -Function Get-MailboxesPerDatabaseAvailabilityGroup #endregion |