Exchange.Connection.Manager.psm1

$ErrorActionPreference = 'SilentlyContinue'
$pspp = $profile -replace 'Microsoft.PowerShell_profile.ps1'
$pspp = $pspp -replace 'Microsoft.PowerShellISE_profile.ps1'

function Connect-Exchange 
{
    <#
            .SYNOPSIS
            Connect to Exchange using a predefined connection.
            .DESCRIPTION
            Creates and imports a new PSSession. ConnectionUri: https://outlook.office365.com/powershell-liveid
            .EXAMPLE
            Choose your Connection from the connection menu.
            Connect-Exchange
            .EXAMPLE
            Start a connection skipping connection menu.
            Connect-Exchange -Connection 'PROD'
            .Example
            Choose your Connection from the simple connection menu.
            Connect-Exchange -SimpleMenu
    #>


    [CmdletBinding()]
    param
    (
        # Parameter description
        [Parameter(Mandatory = $false)]
        [string]
        $Connection,
        
        [Parameter(Mandatory = $false)]
        [switch]
        $SimpleMenu
    )

  
    if ($host.name -like '*ISE*')
    {
        $SimpleMenu = $true
    }
               
    Function Show-Menu 
    {
        param ($menuItems, $menuPosition, $menuTitel)
        $fcolor = $host.UI.RawUI.ForegroundColor
        $bcolor = $host.UI.RawUI.BackgroundColor


        $l = $menuItems.length + 1
        $menuwidth = $menuTitel.length + 4
        Clear-Host
        Write-Host -Object "`t" -NoNewline
        Write-Host -Object ('*' * $menuwidth) -ForegroundColor $fcolor -BackgroundColor $bcolor
        Write-Host -Object "`t" -NoNewline
        Write-Host -Object "* $menuTitel *" -ForegroundColor $fcolor -BackgroundColor $bcolor
        Write-Host -Object "`t" -NoNewline
        Write-Host -Object ('*' * $menuwidth) -ForegroundColor $fcolor -BackgroundColor $bcolor
        Write-Host -Object ''
        Write-Debug -Message "L: $l MenuItems: $menuItems MenuPosition: $menuPosition"
        for ($i = 0; $i -le $l;$i++) 
        {
            Write-Host -Object "`t" -NoNewline
            if ($i -eq $menuPosition) 
            {
                Write-Host -Object "$($menuItems[$i])" -ForegroundColor $bcolor -BackgroundColor $fcolor
            }
            else 
            {
                Write-Host -Object "$($menuItems[$i])" -ForegroundColor $fcolor -BackgroundColor $bcolor
            }
        }
    }

    Function Get-Menu 
    {
        param ([array]$menuItems, $menuTitel = 'MENU')
        $vkeycode = 0
        $pos = 0
        Show-Menu $menuItems $pos $menuTitel
        While ($vkeycode -ne 13) 
        {
            $press = $host.ui.rawui.readkey('NoEcho,IncludeKeyDown')
            $vkeycode = $press.virtualkeycode
            Write-Host -Object "$($press.character)" -NoNewline
            If ($vkeycode -eq 38) 
            {
                $pos--
            }
            If ($vkeycode -eq 40) 
            {
                $pos++
            }
            if ($pos -lt 0) 
            {
                $pos = 0
            }
            if ($pos -ge $menuItems.length) 
            {
                $pos = $menuItems.length -1
            }
            Show-Menu $menuItems $pos $menuTitel
        }
        Write-Output -InputObject $($menuItems[$pos])
    }

    Function Start-Menue 
    {
        param
        (
            [Object]
            $MenueOptions
        )

        $MenueSelection = Get-Menu $MenueOptions 'Choose your Exchange Connection'
        return $MenueSelection
    }


    function Disconnect-Connection 
    {
        $ConnectionDB = Import-Clixml ($pspp + 'ECM.pwd')
        $PSSessions = Get-PSSession |Select-Object -Property Name


        foreach ($Connection in $ConnectionDB)
        {
            foreach ($PSSession in $PSSessions)
            {
                if ($Connection.Connection -eq $PSSession.Name)
                {
                    Write-Host -Object ('[INFO] Removing existing Connection ' + $PSSession.Name) -ForegroundColor Yellow
                    Get-PSSession -Name $PSSession.Name |Remove-PSSession
                    $host.ui.RawUI.WindowTitle = $null
                }
            }
        }
    }




    function Start-ExchangeConnection  
    {
        param
        (
            [Object]
            $UserName,

            [Object]
            $Password,

            [Object]
            $ConnectionName,

            [string]
            $ConnectionURI
        )

        Disconnect-Connection

        $cred = New-Object -TypeName System.Management.Automation.PSCredential `
        -ArgumentList $Connect.UserName, ($Connect.Password| ConvertTo-SecureString)

        $ExchangeSession = New-PSSession -ConfigurationName Microsoft.Exchange -ConnectionUri $ConnectionURI -Credential $cred -Authentication Basic -AllowRedirection -Name $ConnectionName
        if ($ExchangeSession -eq $null)
        {
            Write-Host -Object ('[ERROR] Unable to connect to Session ' + $ConnectionName + ' ' + $ConnectionURI) -ForegroundColor red
            return 
        }
        Import-Module (Import-PSSession -Session $ExchangeSession -AllowClobber -DisableNameChecking) -Global -DisableNameChecking
    }


    function Start-FullMenueMode 
    {
        $ScriptMenueItems = @()
    
        foreach ($element in $ConnectionDB)
        {
            $ScriptMenueItems += $element.Connection
        }

        $choice = Start-Menue $ScriptMenueItems
        $Connect = $ConnectionDB |Where-Object -FilterScript {
            $_.Connection -eq $choice
        }


        Start-ExchangeConnection $Connect.Username $Connect.Password $Connect.Connection $Connect.ConnectionURI
        $host.ui.RawUI.WindowTitle = 'Exchange Connection Manager | ' + $Connect.Connection
    }
    

    function Start-SimpleMenuMode 
    {
        $i = 1
        foreach ($item in $ConnectionDB)
        {
            Write-Host -Object ('[' + $i + '] ' + $item.Connection)
            $i++
        }
        $choice = Read-Host -Prompt 'Choose Connection Number'
        if ($choice -gt $i)
        {
            Write-Host -Object '[ERROR] Connection Number invalid.' -ForegroundColor Red
            return
        }

        $Connect = $ConnectionDB[($choice -1)]
        Start-ExchangeConnection $Connect.UserName $Connect.Password $Connect.Connection $Connect.ConnectionURI
    }


    try
    {
        if ((Test-Path -Path ($pspp + 'ECM.pwd')) -ne $false)
        {
            $ConnectionDB = Import-Clixml ($pspp + 'ECM.pwd')

            if ($Connection -ne $null -and $Connection -notlike '')
            {
                $Connect = $ConnectionDB |Where-Object -FilterScript {
                    $_.Connection -eq $Connection
                }
                if ($Connect -eq $null)
                {
                    Write-Host '[ERROR] Connection Name (' $Connection ') not found.' -ForegroundColor Red
                    return
                }
            
                Start-ExchangeConnection $Connect.UserName $Connect.Password $Connection
            }
            else
            {
                if ($SimpleMenu -eq $true)
                {
                    Start-SimpleMenuMode
                }
                else
                {
                    Start-FullMenueMode
                }
            }
        }
        else
        {
            Write-Host '[ERROR] Connection Database not found. '($pspp + 'ECM.pwd') -ForegroundColor Red
            Write-Host -Object 'Use New-ExchangeCredentials to create a new database. ' -ForegroundColor Red
        }
    }
    catch
    {
        Write-Host -Object $_ -ForegroundColor Red
    }
}




Function New-ExchangeCredentials 
{
    <#
            .SYNOPSIS
            Add a new Exchange Connection to use with Connect-Exchange
            .DESCRIPTION
            Add a new Exchange Connection to use with Connect-Exchange
            .EXAMPLE
            Connect-Exchange -ConnectionName 'Customer Exchange PROD'
 
    #>


    [CmdletBinding(DefaultParametersetName = 'None')]
    param
    (
        # Parameter description
        [Parameter(Mandatory = $true)]
        [string]
        $ConnectionName,

        [Parameter(ParameterSetName = 'ConnectionType',Mandatory = $false)][switch]$OnPrem,
        [Parameter(ParameterSetName = 'ConnectionType',Mandatory = $true)][string]$URI

    )

    
    Write-Host -Object '[INFO] Enter credentials for your new connection' -ForegroundColor Yellow 
    $ConnectionCredentials = Get-Credential -Message ('Credentials for connection ' + $ConnectionName)
    $ConnectionDB = @()
    $NewConnectionDB = @()

    if ($URI -like '')
    {
        $URI = 'https://outlook.office365.com/powershell-liveid/'
    }

    if ((Test-Path -Path ($pspp + 'ECM.pwd')) -eq $false)
    {
        $ConnectionDBProperties = @{
            'Connection'  = $ConnectionName
            'UserName'    = $ConnectionCredentials.UserName
            'Password'    = ($ConnectionCredentials.Password |ConvertFrom-SecureString)
            'ConnectionURI' = $URI
        }
        $ConnectionDB += New-Object -TypeName pscustomobject -Property $ConnectionDBProperties
        $ConnectionDB | Export-Clixml ($pspp + 'ECM.pwd')
    }
    else
    {
        $ConnectionDB = Import-Clixml ($pspp + 'ECM.pwd')
        
        foreach ($element in $ConnectionDB)
        {
            if ($element.Connection -eq $ConnectionName)
            {
                Write-Host '[ERROR] A Connection with that name is already present (' $ConnectionName '). Please specify another name.' -ForegroundColor Red
                return 
            }


            $ConnectionDBProperties = @{
                'Connection'  = $element.Connection
                'UserName'    = $element.UserName
                'Password'    = $element.Password
                'ConnectionURI' = $element.ConnectionURI
            }
            $NewConnectionDB += New-Object -TypeName pscustomobject -Property $ConnectionDBProperties
        }


        $ConnectionDBProperties = @{
            'Connection'  = $ConnectionName
            'UserName'    = $ConnectionCredentials.UserName
            'Password'    = ($ConnectionCredentials.Password |ConvertFrom-SecureString)
            'ConnectionURI' = $URI
        }
        $NewConnectionDB += New-Object -TypeName pscustomobject -Property $ConnectionDBProperties
        $NewConnectionDB | Export-Clixml ($pspp + 'ECM.pwd') 
    }
    Write-Host -Object '[INFO] Connection Database updated.' -ForegroundColor Yellow
}


function Get-ExchangeCredentials
{
    <#
            .SYNOPSIS
            List all available Exchange connections.
            .DESCRIPTION
            List all available Exchange connections.
            .EXAMPLE
            Get-ExchangeCredentials
 
    #>


    
    if ((Test-Path -Path ($pspp + 'ECM.pwd')) -ne $false)
    {
        $ConnectionDB = Import-Clixml ($pspp + 'ECM.pwd')
        $ConnectionDB |Select-Object -Property Connection, UserName, ConnectionURI
    }
    else
    {
        Write-Host '[ERROR] Connection Database not found. '($pspp + 'ECM.pwd') -ForegroundColor Red
        Write-Host -Object 'Use New-ExchangeCredentials to create a new database. ' -ForegroundColor Red
    }
}


function Remove-ExchangeCredentials
{
    <#
            .SYNOPSIS
            Removes a connection from the connection menu.
            .DESCRIPTION
            Removes a connection from the connection menu.
            .EXAMPLE
            Remove-ExchangeCredentials -Connection 'Customer Exchange DEV'
 
    #>


    [CmdletBinding()]
    param
    (
        # Parameter description
        [Parameter(
                Mandatory = $true,
                ValueFromPipeline = $true,
                ValueFromPipelineByPropertyName = $true
        )]
        [string]
        $Connection,
        [switch]
        $NoConfirm
    )
    process {
  
        if ((Test-Path -Path ($pspp + 'ECM.pwd')) -ne $false)
        {
            $ConnectionDB = Import-Clixml ($pspp + 'ECM.pwd')

            if ( ($NewConnectionDB = $ConnectionDB |Where-Object -FilterScript {
                        $_.Connection -eq $Connection
            }) -eq $null)
            {
                Write-Host '[ERROR] Connection Name ' $Connection ' not found.' -ForegroundColor Red
                return
            }

            if ($NoConfirm -eq $false)
            {
                Write-Host 'Do you really want to permanently remove the connection '$Connection -ForegroundColor Yellow
                Write-Host -Object '[Y] Yes [N] No (default is "N"): ' -NoNewline -ForegroundColor Yellow
                $cv = Read-Host
            }

            if ($cv -eq 'Y' -or $NoConfirm -eq $true)
            {
                $NewConnectionDB = $ConnectionDB |Where-Object -FilterScript {
                    $_.Connection -ne $Connection
                }

                $NewConnectionDB | Export-Clixml ($pspp + 'ECM.pwd') 
                Write-Host -Object '[INFO] Connection Database updated.' -ForegroundColor Yellow
            }
        }
        else
        {
            Write-Host '[ERROR] Connection Database not found. '($pspp + 'ECM.pwd') -ForegroundColor Red
        }
    }
}

function Update-ExchangeCredentials
{
    <#
            .SYNOPSIS
            Update your connection credentials.
            .DESCRIPTION
            Update username and password for an Exchange connection used with Connect-Exchange.
            .EXAMPLE
            Update-ExchangeCredentials -Connection 'Exchange PROD'
    #>


    [CmdletBinding()]
    param
    (
        # Parameter description
        [Parameter(
                Mandatory = $true,
                ValueFromPipeline = $true,
                ValueFromPipelineByPropertyName = $true
        )]
        [string]
        $Connection
    )

    process {


        if ((Test-Path -Path ($pspp + 'ECM.pwd')) -ne $false)
        {
            $ConnectionDB = Import-Clixml ($pspp + 'ECM.pwd')
            $found = $ConnectionDB |Where-Object -FilterScript {
                $_.Connection -eq $Connection
            }

            if ($found -ne $null)
            {
                Write-Host '[INFO] Enter new Credentials for Connection: '$Connection -ForegroundColor yellow
                $cred = Get-Credential -Message ('Credentials for Connection: ' + $Connection)


                $ConnectionDB |
                Where-Object -FilterScript {
                    $_.Connection -eq $Connection
                }|
                ForEach-Object -Process {
                    $_.Username = $cred.UserName
                    $_.Password = ($cred.Password |
                    ConvertFrom-SecureString)
                }

                $ConnectionDB | Export-Clixml ($pspp + 'ECM.pwd')




                Write-Host '[INFO] Credentials updatet for Connection: '$Connection -ForegroundColor yellow
                return
            }
            else
            {
                Write-Host '[ERROR] Connection not found: '$Connection -ForegroundColor Red
                return
            }
        }
        else
        {
            Write-Host '[ERROR] Connection Database not found. '($pspp + 'ECM.pwd') -ForegroundColor Red
            Write-Host -Object 'Use New-ExchangeCredentials to create a new database. ' -ForegroundColor Red
        }
    }
}

Export-ModuleMember -Function Connect-Exchange, Update-ExchangeCredentials, New-ExchangeCredentials, Get-ExchangeCredentials, Remove-ExchangeCredentials