RecipientAddress.psm1

#region Functions
#region Get-RecipientAddress
Function Get-RecipientAddress
{
    <#
        .SYNOPSIS
        Gets a list of all the addresses assigned to a recipient.
 
        .DESCRIPTION
        The Get-RecipientAddress cmdlet returns a list of all the addresses assigned to a recipient including the SMTP, SIP, X400 and X500 addresses.
     
        .PARAMETER Recipient
        Specifies the identity of the recipient.
 
        .PARAMETER Type
        Specifies the type of the addresses to return.
 
        .EXAMPLE
        Get-RecipientAddress -Identity $Mailbox.Identity -Type SMTP
 
        This command will return all the SMTP addresses of the mailbox saved in the Mailbox variable
 
        .EXAMPLE
        Get-Mailbox User1 | Get-RecipientAddress -Type SMTP
 
        This command will return all the SMTP addresses on the User1's mailbox
 
    #>

 
    [cmdletBinding()]
    
    Param
    (
         [Parameter(
                   Position = 0,
                   Mandatory = $true,
                   ValueFromPipeline = $true,
                   ValueFromPipelineByPropertyName = $true
         )]  
        [string[]]$Identity,

        [ValidateSet('SIP','SMTP','X500', 'X400')]
        [String]$Type
    )
    Begin
    {
        # Check if Exchange cmdlets are available
        try
        {
            Get-Command "Get-MailboxServer" -ErrorAction Stop |
                Out-Null
            Write-Verbose "Exchange cmdlets are available."
        }
        catch
        {
            Throw "Exchange cmdlets are not available. Please use the Exchange Management Shell."
        }        
    }

    Process
    {
        foreach($i in $Identity)
        {
            # Get the recipient
            try
            {
                $r = Get-Recipient $i
                Write-Verbose ("Found object " + $r.Identity)
            }
            catch
            {
                Write-Error "Could not find a recipient with identity $i."
                continue
            }    
        
            # Loop through the addresses of the mailbox
            foreach($a in $r.EmailAddresses)
            {
                # Create new custom object
                $obj = New-Object psobject
                $obj | Add-Member -MemberType NoteProperty -Name "Identity" -Value $r.Identity

                $address = $a.ToString()

                $parts  = $address.Split(":")
                $obj | Add-Member -MemberType NoteProperty -Name "Type" $parts[0]
                $obj | Add-Member -MemberType NoteProperty -Name "Address" $parts[1]

                if($parts[0].ToLower() -eq "smtp")
                {
                    if($parts[0].Equals("SMTP"))
                    {
                        $obj | Add-Member -MemberType NoteProperty -Name "Primary" -Value $true
                    }
                    else
                    {
                        $obj | Add-Member -MemberType NoteProperty -Name "Primary" -Value $false
                    }
                }
                else
                {
                    $obj | Add-Member -MemberType NoteProperty -Name "Primary" -Value $null
                }

                $obj
            }
        }
    }

    End{}
}
#endregion

#region New-RecipientAddress
Function New-RecipientAddress
{
    <#
        .SYNOPSIS
        Adds an address to a recipient.
 
        .DESCRIPTION
        The New-RecipientAddress assigns a new address to a recipient.
     
        .PARAMETER Recipient
        Specifies the identity of the recipient on which the address will be assigned.
 
        .PARAMETER Address
        Specifies the address to be added.
 
        .PARAMETER Type
        Specifies the type of the address to be added.
 
        .PARAMETER UpdateMailAttribute
        Updates the mail attribute to match the new primary address.
 
        .PARAMETER Primary
        Specifies whether the new address will be marked as the primary address (SMTP Addresses only).
 
        .EXAMPLE
        New-RecipientAddress -Mailbox User1 -EmailAddress "user1@domain.com" -Primary
 
        This command will add the "user1@domain.com" email address to the User1 mailbox and will mark that address as the primary one.
    #>


    [cmdletBinding(
        SupportsShouldProcess = $true,
        ConfirmImpact = "High"
    )]

    Param
    (
        [Parameter(
            Mandatory = $true,
            Position = 0,
            ValueFromPipeline = $true,
            ValueFromPipelineByPropertyName = $true
        )]
        [string]$Identity,

        [Parameter(
            Mandatory = $true,
            Position = 1
        )]
        [string]$Address,

        [Parameter(
            Mandatory = $false
        )]
        [ValidateSet('SMTP')]
        [string]$Type = 'SMTP',
 
        [Parameter(
            Mandatory = $false
        )]
        [switch]$Primary,

        [Parameter(
            Mandatory = $false
        )]
        [switch]$UpdateMailAttribute
    )

    Begin {}

    Process
    {
        if($PSCmdlet.ShouldProcess($Identity))
        {
            # Get the recipient
            try
            {
                $r = Get-Recipient $Identity -ErrorAction Stop
                Write-Verbose ("Recipient " + $r.identity + " found.")
            }
            catch
            {
                Write-Error "Could not find a recipient with identity $Identity."
                return
            }

            # Check if the address is already assigned
            if($Type -eq "SMTP")
            {
                try
                {
                    $existingRecipient = Get-Recipient $Address -ErrorAction Stop
                    Write-Error ("The address $Address is already assigned to the object " + $existingRecipient.Identity + ".")
                    return
                }
                catch
                {
                }

                if($Primary)
                {
                    $AddressToAdd = "SMTP:"
                }
                else
                {
                    $AddressToAdd = "smtp:"
                }

                $AddressToAdd += $Address
            }

            # Find the object in Active Directory and add the address
            $dn = $r.DistinguishedName

            $LDAPFilter = "(distinguishedname=$dn)"

            $Domain = New-Object System.DirectoryServices.DirectoryEntry

            $Searcher = New-Object System.DirectoryServices.DirectorySearcher
            $Searcher.SearchRoot = $Domain
            $Searcher.PageSize = 10
            $Searcher.Filter = $LDAPFilter
            $Searcher.SearchScope = "Subtree"

            $Result = $Searcher.FindOne()

            $Object = [ADSI]$Result.GetDirectoryEntry()

            if(!$Object.proxyAddresses.Contains($AddressToAdd))
            {
                if($Primary)
                {
                    Write-Verbose ("Setting proxy address '" + $currentPrimaryAddress + "' to standard from primary.")
                    # get the current primary address
                    $currentPrimaryAddress = $Object.proxyAddresses | Where-Object {$_.StartsWith("SMTP:")}

                    if($Object.proxyAddresses.Count -le 1)
                    {
                        $array = New-Object System.Collections.ArrayList
                        $array.Add($AddressToAdd) |
                            Out-Null
                        $array.Add($currentPrimaryAddress.Replace("SMTP:","smtp:")) |
                            Out-Null
                        $Object.proxyAddresses = $array
                    }
                    else
                    {
                        # remove the current primary address
                        $Object.proxyAddresses.Remove($currentPrimaryAddress) |
                            Out-Null

                        Write-Verbose ("Adding proxy address '" + $AddressToAdd + "'")
                        # add the new primary address
                        $Object.proxyaddresses.Add($AddressToAdd) |
                            Out-Null

                        # add the old primary address as standard address
                        $Object.proxyAddresses.Add($currentPrimaryAddress.Replace("SMTP:","smtp:")) |
                            Out-Null
                    }

                    # set the mail attribute
                    if($UpdateMailAttribute)
                    {
                        Write-Verbose "Updating mail attribute..."
                        $Object.mail = $Address
                    }
                }
                else
                {
                    Write-Verbose ("Adding proxy address '" + $AddressToAdd + "'")

                    # add the new address
                    $Object.proxyaddresses.Add($AddressToAdd) |
                        Out-Null
                }
            }

            try
            {
                $Object.CommitChanges()
                Write-Verbose "Object updated successfully"
            }
            catch
            {
                Write-Error ("Could not update the object " + $Result.Properties.distinguishedname)
                $Error[0].ErrorDetails
            }
        }
    }

    End {}
}
#endregion

#region Remove-RecipientAddress
Function Remove-RecipientAddress
{
    <#
        .SYNOPSIS
        Removes an address from a recipient.
 
        .DESCRIPTION
        The Remove-RecipientAddress removes an address from a recipient.
     
        .PARAMETER Identity
        Specifies the identity of the recipient from which the address will be removed.
 
        .PARAMETER Address
        Specifies the address to be removed.
 
        .PARAMETER Type
        Specifies the type of the address to be removed.
 
        .EXAMPLE
        Remove-RecipientAddress -Identity $mailbox.Identity -Address "user1@domain.com" -Type SMTP
 
        This command will remove the "user1@domain.com" email address from the $mailbox.
    #>


    [cmdletBinding(
        SupportsShouldProcess = $true,
        ConfirmImpact = "High"
    )]

    Param
    (
        [Parameter(
            Mandatory = $true,
            Position = 0,
            ValueFromPipeline = $true,
            ValueFromPipelineByPropertyName = $true
        )]
        [string]$Identity,

        [Parameter(
            Mandatory = $true,
            Position = 1
        )]
        [string]$Address,

        [Parameter(
            Mandatory = $false
        )]
        [ValidateSet('SMTP')]
        [string]$Type = 'SMTP'
     )

    Begin {}

    Process
    {
        if($PSCmdlet.ShouldProcess($Identity))
        {
            # Get the recipient
            try
            {
                $r = Get-Recipient $Identity -ErrorAction Stop
                Write-Verbose ("Recipient " + $r.identity + " found.")
            }
            catch
            {
                Write-Error "Could not find a recipient with identity $Identity."
                return
            }

            # Find the object in Active Directory
            $dn = $r.DistinguishedName

            $LDAPFilter = "(distinguishedname=$dn)"

            $Domain = New-Object System.DirectoryServices.DirectoryEntry

            $Searcher = New-Object System.DirectoryServices.DirectorySearcher
            $Searcher.SearchRoot = $Domain
            $Searcher.PageSize = 10
            $Searcher.Filter = $LDAPFilter
            $Searcher.SearchScope = "Subtree"

            $Result = $Searcher.FindOne()

            $Object = [ADSI]$Result.GetDirectoryEntry()

            if($Type -eq "SMTP")
            {
                # check if the address is assigned to the user and is primary
                if($Object.proxyAddresses.Contains("SMTP:" + $Address))
                {
                    Write-Error ("The address " + $Address + " is the primary SMTP address of the object " + $Identity)
                    return
                }

                # check if the address is assigned to the user
                if(!$Object.proxyAddresses.Contains("smtp:" + $Address))
                {
                    Write-Error ("The address " + $Address + " is not assigned to the object " + $Identity)
                    return
                }
                else
                {
                    Write-Verbose ("Removing proxy address 'smtp:" + $Address + "'")

                    # remove the current primary address
                    $Object.proxyAddresses.Remove("smtp:" + $Address) |
                        Out-Null
                }
            }

            try
            {
                $Object.CommitChanges()
                Write-Verbose "Object updated successfully"
            }
            catch
            {
                Write-Error ("Could not update the object " + $Result.Properties.distinguishedname)
                $Error[0].ErrorDetails
            }
        }
    }

    End {}
}
#endregion

#endregion

#region Exports
Export-ModuleMember -Function Get-RecipientAddress
Export-ModuleMember -Function New-RecipientAddress
Export-ModuleMember -Function Remove-RecipientAddress
#endregion