CCCPaste

Sync-GAL.ps1

[CmdletBinding()] 
param(
	[Parameter(Mandatory=$true)][string]$RemoteDC,
	[Parameter(Mandatory=$true)][string]$RemoteOU,
	[Parameter(Mandatory=$true)][string]$LocalOU,
	[Parameter(Mandatory=$false)][System.Management.Automation.PSCredential]$RemoteCred,
	[Parameter(Mandatory=$false)][string]$AddressList,
	[Parameter(Mandatory=$false)][int]$MaxDeletions = 64,
	[Parameter(Mandatory=$false)][switch]$ScheduledTask = $false,
    [Parameter(Mandatory=$false)][string]$TargetDomain
	)
If($ScheduledTask) { Start-Transcript -Path .\Sync-GAL-$AddressList.log -Append }

Import-Module ActiveDirectory

#Get active remote users
Try {
    if($null -ne $RemoteCred) {
        $RUsers = Get-ADUser -Server $RemoteDC -Credential $RemoteCred -LDAPFilter "(&(objectClass=user)(mail=*)(userAccountControl:1.2.840.113556.1.4.803:=512)(!userAccountControl:1.2.840.113556.1.4.803:=2))" `
        -SearchBase $RemoteOU -Properties company, department, displayName, givenName, mail, physicalDeliveryOfficeName, sn, telephoneNumber, title, pager, ipPhone, legacyExchangeDN

        $RGroups = Get-ADGroup -Server $RemoteDC -Credential $RemoteCred -LDAPFilter "(mail=*)" -Properties displayname, mail, department, company, telephoneNumber, legacyExchangeDN
    }
    else {
        $RUsers = Get-ADUser -Server $RemoteDC -LDAPFilter "(&(objectClass=user)(mail=*)(userAccountControl:1.2.840.113556.1.4.803:=512)(!userAccountControl:1.2.840.113556.1.4.803:=2))" `
        -SearchBase $RemoteOU -Properties company, department, displayName, givenName, mail, physicalDeliveryOfficeName, sn, telephoneNumber, title, pager, ipPhone, legacyExchangeDN

        $RGroups = Get-ADGroup -Server $RemoteDC -LDAPFilter "(mail=*)" -Properties displayname, mail, department, company, telephoneNumber, legacyExchangeDN
    }
} Catch {
    Write-Output "Cant's connect to Remote DC!"
    break
}

#Generate list of remote users with local OU
$RCheck = $RUsers | select @{e={"CN=$($_.Name),$LocalOU"};Label="DistinguishedName"}
$RCheck += $RGroups | select @{e={"CN=$($_.Name),$LocalOU"};Label="DistinguishedName"}

#Get local contacts
$LUsers = Get-ADObject -LDAPFilter "(mail=*)" -SearchBase $LocalOU -prop mail

#Remove local contacts that no longer exist in remote OU
$Remove = $LUsers | ?{$RCheck.DistinguishedName -notcontains $_.DistinguishedName}
If($Remove.Count -gt $MaxDeletions) {
    Write-Output "Too many deletions $($Remove.Count), something may be wrong!"
    break
} 
$LUsers | ?{$RCheck.DistinguishedName -notcontains $_.DistinguishedName} | %{ Remove-MailContact $_.DistinguishedName -confirm:$false }

#Create/update local contacts with values from remote users
ForEach ($RUser in $RUsers) {
    If(!$ScheduledTask) { Write-Host $RUser.DistinguishedName }
    $ContactDN = "CN={0},{1}" -f $RUser.Name, $LocalOU
    $contact = Get-MailContact -Identity $ContactDN -ErrorAction SilentlyContinue
    $recip = Get-Recipient $ruser.mail -ErrorAction SilentlyContinue
    $targetAddress = $ruser.mail
    if($TargetDomain -ne $null) {
        $targetAddress = "$($ruser.samAccountName)@$TargetDomain"
    }
    If($null -eq $contact -and $null -eq $recip) {
        Write-Host "Creating contact $($RUser.DistinguishedName)" -ForegroundColor Cyan
        $contact = New-MailContact -OrganizationalUnit $LocalOU -FirstName $RUser.givenName -LastName $RUser.sn -Name $RUser.Name -DisplayName $RUser.Name -ExternalEmailAddress $targetAddress -PrimarySmtpAddress $RUser.mail
        #Start-Sleep 10
    }
    If($null -ne $contact) {
        $recip = Get-Recipient $ruser.mail -ErrorAction SilentlyContinue
        If($null -eq $recip) {
            Set-ADObject -identity $contact.DistinguishedName -add @{'proxyAddresses'="smtp:$($ruser.mail)"}
            #Start-Sleep 10
            $recip = Get-Recipient $ruser.mail -ErrorAction SilentlyContinue
        } 
        if($null -ne $recip) {
            if($recip.RecipientType -eq "MailContact") {
                $adobjfound = $false
                Try {
                    $ado = Get-ADObject -Identity $contact.DistinguishedName -ErrorAction SilentlyContinue
                    $adobjfound = $true
                }
                Catch {
                    #Can't get AD Object yet, try again later.
                }
                if ($adobjfound) {
                    $DisplayName = $RUser.displayName
                    if($null -eq $DisplayName) { $DisplayName = $RUser.Name}
                    $X500 = $RUser.legacyExchangeDN.Replace("'", "")
                    Set-MailContact $contact.DistinguishedName -EmailAddressPolicyEnabled:$false -DisplayName $DisplayName -WarningAction SilentlyContinue
                    Set-Contact $contact.DistinguishedName -Company $RUser.company -Department $RUser.department -FirstName $RUser.givenName -LastName $RUser.sn -Office $RUser.physicalDeliveryOfficeName -Phone $RUser.telephoneNumber -Title $RUser.title -Pager $RUser.pager -WarningAction SilentlyContinue
                    if($null -ne $ado) {
                        if($null -ne $RUser.legacyExchangeDN) { Set-ADObject $ado -add @{'proxyAddresses'="x500:$X500"} }
                        if($null -ne $RUser.ipPhone -and $contact.ipPhone -ne $RUser.ipPhone) {
                            Set-ADObject $ado -clear ipPhone -ErrorAction SilentlyContinue
                            Set-ADObject $ado -add @{'ipPhone'=$RUser.ipPhone} 
                        }
                    }
                }
            }
        }
    } 
}

ForEach($RGroup in $RGroups) {
    If(!$ScheduledTask) { Write-Host $RGroup.DistinguishedName }
    $ContactDN = "CN={0},{1}" -f $RGroup.Name, $LocalOU
    $contact = Get-MailContact -Identity $ContactDN -ErrorAction SilentlyContinue
    $recip = Get-Recipient $RGroup.mail -ErrorAction SilentlyContinue
    $targetAddress = $RGroup.mail
    $samAccountName = $RGroup.samAccountName.Replace(" ", "")
    if($TargetDomain -ne $null) {
        $targetAddress = "$samAccountName@$TargetDomain"
    }
    If($null -eq $contact -and $null -eq $recip) {
        Write-Host "Creating contact $($RGroup.DistinguishedName)" -ForegroundColor Cyan
        $contact = New-MailContact -OrganizationalUnit $LocalOU -FirstName $RGroup.Name -Name $RGroup.Name -DisplayName $RGroup.Name -ExternalEmailAddress $targetAddress -PrimarySmtpAddress $RGroup.mail
        #Start-Sleep 10
    }
    If($null -ne $contact) {
        $recip = Get-Recipient $RGroup.mail -ErrorAction SilentlyContinue
        If($null -eq $recip) {
            Set-ADObject -identity $contact.DistinguishedName -add @{'proxyAddresses'="smtp:$($RGroup.mail)"}
            #Start-Sleep 10
            $recip = Get-Recipient $RGroup.mail -ErrorAction SilentlyContinue
        } 
        if($null -ne $recip) {
            if($recip.RecipientType -eq "MailContact") {
                $adobjfound = $false
                Try {
                    $ado = Get-ADObject -Identity $contact.DistinguishedName -ErrorAction SilentlyContinue
                    $adobjfound = $true
                }
                Catch {
                    #Can't get AD Object yet, try again later.
                }
                if ($adobjfound) {
                    $DisplayName = $RGroup.displayName
                    $X500 = $RGroup.legacyExchangeDN.Replace("'", "")
                    if($null -eq $DisplayName) { $DisplayName = $RGroup.Name}
                    Set-MailContact $contact.DistinguishedName -EmailAddressPolicyEnabled:$false -DisplayName $DisplayName -WarningAction SilentlyContinue
                    Set-Contact $contact.DistinguishedName -Company $RGroup.company -Department $RGroup.department -FirstName $RGroup.DisplayName -Phone $RGroup.telephoneNumber -WarningAction SilentlyContinue
                    if($null -ne $ado) {
                        if($null -ne $RGroup.legacyExchangeDN) { Set-ADObject $ado -add @{'proxyAddresses'="x500:$X500"} }
                    }
                }
            }
        }
    } 
}

#Update address list (if supplied)
if($AddressList -ne "") {
    Get-AddressList -Identity $AddressList | Update-AddressList 
}

If($ScheduledTask) { Stop-Transcript }