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,

        [Parameter()]
        [string]$DomainController
    )
    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
            {
                if($DomainController)
                {                    
                    $r = Get-Recipient $i -DomainController $DomainController -ErrorAction Stop
                }
                else
                {
                    $r = Get-Recipient $i -ErrorAction Stop
                }
                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
                }

                if($Type)
                {
                    if($Type -contains $obj.type)
                    {
                        $obj
                    }
                }
                else
                {
                    $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', 'X400', 'X500', 'SIP')]
        [string]$Type = 'SMTP',
 
        [Parameter(
            Mandatory = $false
        )]
        [switch]$Primary,

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

        [Parameter()]
        [string]$DomainController
    )

    Begin {}

    Process
    {
        if($PSCmdlet.ShouldProcess($Identity))
        {
            # Get the recipient
            try
            {
                if($DomainController)
                {
                    $r = Get-Recipient $Identity -ErrorAction Stop -DomainController $DomainController
                }
                else
                { 
                    $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")
            {
                if($Primary)
                {
                    $AddressToAdd = "SMTP:"
                }
                else
                {
                    $AddressToAdd = "smtp:"
                }
            }
            else
            {
                $AddressToAdd = $Type + ":"
            }

            $AddressToAdd += $Address

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

            $LDAPFilter = "(distinguishedname=$dn)"


            if($DomainController)
            {
                try
                {
                    $Domain = New-Object System.DirectoryServices.DirectoryEntry -ArgumentList "LDAP://$DomainController"
                    $Searcher = New-Object System.DirectoryServices.DirectorySearcher -ArgumentList $Domain
                }
                catch
                {
                    Write-Error "Could not contact the domain controller."
                    return
                }
            }
            else
            {
                $Domain = New-Object System.DirectoryServices.DirectoryEntry
                $Searcher = New-Object System.DirectoryServices.DirectorySearcher
            }

            $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', 'SIP', 'X400', 'X500')]
        [string]$Type = 'SMTP',

        [Parameter()]
        [string]$DomainController
     )

    Begin {}

    Process
    {
        if($PSCmdlet.ShouldProcess($Identity))
        {
            # Get the recipient
            try
            {
                if($DomainController)
                {
                    $r = Get-Recipient $Identity -ErrorAction Stop -DomainController $DomainController
                }
                else
                {
                    $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)"

            if($DomainController)
            {
                try
                {
                    $Domain = New-Object System.DirectoryServices.DirectoryEntry -ArgumentList "LDAP://$DomainController"
                    $Searcher = New-Object System.DirectoryServices.DirectorySearcher -ArgumentList $Domain
                }
                catch
                {
                    Write-Error "Could not contact the domain controller."
                    return
                }
            }
            else
            {
                $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
                }
            }
            else
            {
                foreach($pa in $Object.proxyAddresses)
                {
                    if($pa -eq ($Type + ":" + $Address))
                    {
                        # remove the current primary address
                        $Object.proxyAddresses.Remove($Type + ":" + $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

#region Copy-RecipientAddress
Function Copy-RecipientAddress
{
    <#
        .SYNOPSIS
        Copy the addresses between recipients.
 
        .DESCRIPTION
        The Copy-RecipientAddress cmdlet copies the addresses assigned to a recipient including the SMTP, SIP, X400 and X500 addresses to another recipient.
     
        .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(SupportsShouldProcess=$true, 
                  ConfirmImpact='High')]
    
    Param
    (
         [Parameter(
                   Position = 0,
                   Mandatory = $true,
                   ValueFromPipeline = $true,
                   ValueFromPipelineByPropertyName = $true
         )]  
        [string]$SourceObject,

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

        [ValidateSet('All', 'SIP','SMTP','X500', 'X400', 'LDN')]
        [String]$Type = 'All',

        [Parameter()]
        $DomainController
    )
    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
    {
        if ($pscmdlet.ShouldProcess("$TargetObject", "Copy-RecipientAddress"))
        {
            #region Get the recipients
            Write-Verbose "Getting the recipients."
            # Get the source recipient
            try
            {
                if($DomainController)
                {
                    $sourceRecipient = Get-Recipient $SourceObject -DomainController $DomainController -ErrorAction Stop
                }
                else
                {
                    $sourceRecipient = Get-Recipient $SourceObject -ErrorAction Stop
                }
                Write-Verbose ("Found source object " + $sourceRecipient.Identity)
            }
            catch
            {
                Write-Error "Could not find a recipient with identity $SourceObject."
                continue
            }    

            # Get the destination recipient
            try
            {
                if($DomainController)
                {
                    $targetRecipient = Get-Recipient $TargetObject -ErrorAction Stop -DomainController $DomainController
                }
                else
                {
                    $targetRecipient = Get-Recipient $TargetObject -ErrorAction Stop
                }
                Write-Verbose ("Found target object " + $targetRecipient.Identity)
            }
            catch
            {
                Write-Error "Could not find a recipient with identity $TargetObject."
                continue
            }    
            #endregion

            #region Process the addresses

            Write-Verbose "Getting the recipients' addresses."

            # Temporarily set the verbose preference
            $vp = $VerbosePreference
            $VerbosePreference = 'SilentlyContinue'

            if($DomainController)
            {
                $sourceAddresses = Get-RecipientAddress -Identity $sourceRecipient.distinguishedName -DomainController $DomainController

                $targetAddresses = Get-RecipientAddress -Identity $targetRecipient.distinguishedName -DomainController $DomainController
            }
            else
            {
                $sourceAddresses = Get-RecipientAddress -Identity $sourceRecipient.distinguishedName

                $targetAddresses = Get-RecipientAddress -Identity $targetRecipient.distinguishedName
            }

            # Restore the verbose preference
            $VerbosePreference = $vp

            foreach($sa in $sourceAddresses)
            {
                #region Decide to add the address or not
                $add = $false

                if($Type -eq 'All')
                {
                    $add = $true
                }
                else
                {
                    if($Type -eq $sa.Type)
                    {
                        $add = $true
                    }
                    else
                    {
                        $add = $false
                    }
                }

                if($add -eq $true)
                {
                    # Check if the address is already assigned
                    $exists = $targetAddresses |
                                Where-Object {$_.type -eq $sa.Type -and $_.address -eq $sa.Address}

                    if($exists -ne $null)
                    {
                        $add = $false
                        Write-Verbose "The $($sa.Type) address $($sa.Address) already exists on target object."
                    }
                }

                #endregion

                #region Add the address
                if($add -eq $true)
                {
                    Write-Verbose "Adding $($sa.Type) address $($sa.Address) to target object."

                    # Temporarily set the verbose preference
                    $vp = $VerbosePreference
                    $VerbosePreference = 'SilentlyContinue'

                    # Add the address
                    if($DomainController)
                    {
                        New-RecipientAddress -Identity $targetRecipient.distinguishedname -Address $sa.Address -Type $sa.Type -Confirm:$false -DomainController $DomainController
                    }
                    else
                    {
                        New-RecipientAddress -Identity $targetRecipient.distinguishedname -Address $sa.Address -Type $sa.Type -Confirm:$false
                    }

                    # Restore the verbose preference
                    $VerbosePreference = $vp
                }
                #endregion
            }

            # Copy the Legacy-Exchange-DN
            if($Type -in ("All", "LDN"))
            {
                Write-Verbose "Copying Legacy-Exchange-DN as X500 address."

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

                $LDAPFilter = "(distinguishedname=$dn)"

                if($DomainController)
                {
                    try
                    {
                        $Domain = New-Object System.DirectoryServices.DirectoryEntry -ArgumentList "LDAP://$DomainController"
                        $Searcher = New-Object System.DirectoryServices.DirectorySearcher -ArgumentList $Domain
                    }
                    catch
                    {
                        Write-Error "Could not contact the domain controller."
                        return
                    }
                }
                else
                {
                    $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()

                # Temporarily set the verbose preference
                $vp = $VerbosePreference
                $VerbosePreference = 'SilentlyContinue'

                # Add the address
                if($DomainController)
                {
                    New-RecipientAddress -Identity $targetRecipient.distinguishedname -Address $Object.LegacyExchangeDN -Type X500 -DomainController $DomainController -Confirm:$false
                }
                else
                {
                    New-RecipientAddress -Identity $targetRecipient.distinguishedname -Address $Object.LegacyExchangeDN -Type X500 -Confirm:$false
                }

                # Restore the verbose preference
                $VerbosePreference = $vp                
            }

            #endregion
        }
    }

    End{}
}
#endregion

#endregion

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