ExchangeAdminToolkit.psm1

Function Get-DeletedMailboxList{  
<#
.Synopsis
   Gets a list of Deleted mailboxes from exchange and outputs into to a CSV file as well as console
.DESCRIPTION
   Gets a list of Hard deleted mailboxes (Remove-Mailbox, Disable-Mailbox) from all databases in the exchange organisation
   It then outputs them both to the console and to a CSV file which defaults to c:\temp\DeletedMailboxes.csv
.EXAMPLE
   Get-DeletedMailboxList
.EXAMPLE
   Get-DeletecMailboxList -CSVPath C:\MyDir\File.csv -SupressConsole
.LINK
    http://www.f-e-a-r.co.uk
.NOTES
    Author: Daniel Caulfield - 2017
#>

    [CmdletBinding(SupportsShouldProcess=$True)]    
    [OutputType([int])]
    Param
    (
        # Path to CSV File
        [Parameter(Mandatory=$false,
                   Position=0)]
        $CSVPath = "$env:TEMP\DeletedMailboxes.csv",

        # Supress output to the console and just create CSV
        [switch]$SupressConsole
    )
Begin{
    Write-Verbose "SupressConsole = $SupressConsole, CSVPath = $CSVPath"
    }
Process{
    Write-Verbose "Querying all databases for all mailboxes and filtering for deleted"
    $DeletedMailboxes = Get-mailboxdatabase |Get-MailboxStatistics | Where-Object{$_.DisconnectReason -eq 'Disabled'} | Select-Object DisplayName,TotalItemSize,Database,MailboxGuid,DisconnectDate,DisconnectReason,LastLogonTime,LegacyDN
    Write-Verbose "Data collected, writing outputs"
    if ($SupressConsole -eq $False) {Write-Output $DeletedMailboxes}
    $DeletedMailboxes | ConvertTo-Csv | Out-File $CSVPath
}
End{
    Write-Verbose "Command Complete"
    }
}

Function Invoke-LoopCheckMoveRequest {
<#
.Synopsis
   Starts a loop checking mailbox move request statistics
.DESCRIPTION
   Starts a loop checking mailbox move request statistics for all moves or optionally only ones not completed
   Use CTRL+C to end the loop
.EXAMPLE
   Start-LoopCheckMoveRequest
.EXAMPLE
   Start-LoopCheckMoveRequest -ExcludeComplete -Interval 120
.LINK
    http://www.f-e-a-r.co.uk
.NOTES
    Author: Daniel Caulfield - 2017
#>

    [CmdletBinding()]
    [OutputType([int])]
    Param
    (
        # Excludes moves with a ststus of Completed
        [switch]$ExcludeComplete,
        #Interval in seconds to run the check
        [int]$Interval = '60'
    )
Begin{
    Write-Verbose "Starting Loop with an interval of $interval and ExcludeComplete $ExcludeComplete"
    Write-Output "Starting loop use CTRL+C to stop"
    $a = '1'
    }
Process{
    While ($a = 1){
        Write-Verbose 'Running Loop'
        If ($ExcludeComplete -eq $False) {Get-MoveRequest | Get-MoveRequestStatistics -OutVariable Results}
        If ($ExcludeComplete -eq $True) {Get-MoveRequest | Where-Object{$_.status -ne 'Completed'} | Get-MoveRequestStatistics -OutVariable Results}
        $Completed = ($Results | Where-Object {$_.status -eq 'Completed'}).count
        $Queued  = ($Results | Where-Object {$_.status -eq 'queued'}).count
        $AS = ($Results | Where-Object {$_.status -eq 'AutoSuspended'}).count
        $Rel = ($Results | Where-Object {($_.status -like 'relinquished*') -or ($_.status -like 'stalled*')}).count
        $failed = ($Results | Where-Object {$_.status -like 'Failed*'}).count
        $prog = ($Results | Where-Object {($_.status -eq 'InProgress') -or ($_.status -like 'copying*') -or ($_.status -like 'loading*') -or ($_.status -like 'creating*') -or ($_.status -like 'initial*')}).count
        Write-Output ""
        Write-Output "Completed : $Completed"
        Write-Output "In Progress : $Prog"
        Write-Output "Queued : $Queued"
        Write-Output "Suspended : $AS"
        Write-Output "Stalled : $Rel"
        Write-Output "Failed : $Failed"
        
        Write-Output "Next Check $Interval seconds..."
        Write-Verbose "Going to sleep for $Interval Seconds"
        Start-Sleep $interval
        }
    }
}

Function Invoke-LoopCheckRestoreRequest {
<#
.Synopsis
   Starts a loop checking mailbox Restore request statistics
.DESCRIPTION
   Starts a loop checking mailbox Restore request statistics for all moves or optionally only ones not completed (default 60 second interval)
   Use CTRL+C to end the loop
.EXAMPLE
   Start-LoopCheckRestoreRequest
.EXAMPLE
   Start-LoopCheckRestoreRequest -ExcludeComplete -Interval 120
.LINK
    http://www.f-e-a-r.co.uk
.NOTES
    Author: Daniel Caulfield - 2017
#>

    [CmdletBinding()]
    [OutputType([int])]
    Param
    (
        # Excludes moves with a ststus of Completed
        [switch]$ExcludeComplete,
        #Interval in seconds to run the check
        [int]$Interval = '60'
    )
Begin{
    Write-Verbose "Starting Loop with an interval of $interval and ExcludeComplete $ExcludeComplete"
    Write-Output "Starting loop use CTRL+C to stop"
    $a = '1'
    }
process{
    While ($a = 1){
        Write-Verbose 'Running Loop'
        If ($ExcludeComplete -eq $False) {Get-MailboxRestoreRequest | Get-MailboxRestoreRequestStatistics}
        If ($ExcludeComplete -eq $True) {Get-MailboxRestoreRequest | Where-Object{$_.status -ne 'Completed'} | Get-MailboxRestoreRequestStatistics}
        Write-Output "Next Check $Interval seconds..."
        Write-Verbose "Going to sleep for $Interval Seconds"
        Start-Sleep $interval
        }
    }
}

Function Add-EXPSSnapin {
<#
.Synopsis
   Adds the Exchange Management PowerShell Snapin
.DESCRIPTION
   Adds the Exchange Management PowerShell Snapin, This requires the management tools for Exchange 2010 (or later) to be installed.
.EXAMPLE
   Add-EXPSSnapin
#>

    [CmdletBinding()]
    [OutputType([int])]
    Param
    (
        # Skips checking that the PSSnapin loaded
        [Switch]$SkipConfirmation
    )
    Add-PSSnapin 'Microsoft.Exchange.Management.PowerShell.E2010'
    If ($SkipConfirmation -eq $False) {If ((Get-PSSnapin 'Microsoft.Exchange.Management.PowerShell.E2010').Name -eq 'Microsoft.Exchange.Management.PowerShell.E2010') {Write-Output 'PSSnapin loaded'} }
}

Function Invoke-LoopCheckMailboxRepairRequest {
<#
.Synopsis
   Starts a loop checking mailbox Repair request statistics
.DESCRIPTION
   Starts a loop checking mailbox Repair request statistics for all repairs or optionally only ones not completed (default 60 second interval)
   Use CTRL+C to end the loop
.EXAMPLE
   Start-LoopCheckMailboxRepairRequest
.EXAMPLE
   Start-LoopCheckMailboxRepairRequest -ExcludeComplete -Interval 120
.LINK
    http://www.f-e-a-r.co.uk
.NOTES
    Author: Daniel Caulfield - 2017
#>

    [CmdletBinding()]
    [OutputType([int])]
    Param
    (
        # Excludes moves with a ststus of Completed
        [switch]$ExcludeComplete,
        #Interval in seconds to run the check
        [int]$Interval = '60'
    )
Begin{
    Write-Verbose "Starting Loop with an interval of $interval and ExcludeComplete $ExcludeComplete"
    Write-Output "Starting loop use CTRL+C to stop"
    $a = '1'
    }
process{
    While ($a = 1){
        Write-Verbose 'Running Loop'
        If ($ExcludeComplete -eq $False) {Get-MailboxRpairRequest}
        If ($ExcludeComplete -eq $True) {Get-MailboxRepairRequest | Where-Object{$_.status -ne 'Completed'}}
        Write-Output "Next Check $Interval seconds..."
        Write-Verbose "Going to sleep for $Interval Seconds"
        Start-Sleep $interval
        }
    }
}