Script: Sync Outlook contacts with Active Directory users

Ever wanted to make sure your Outlook contact list contain the current employees in your organization?

I made a script that does just that. I’d recommend that you make it run each time you log in (using Task Scheduler) with a delay of 60 sec.

The reason I wanted this, was because at the time I wrote the script I could not find a good way to sync my organizations employees contact details to my phone. This script solves that, since my phone syncs all my Outlook contacts via the exchange sync.


  • Adds new employees as contacts in Outlook
  • Updates contacts when info changes in AD
  • Removes employees no longer in search base
  • Excludes your own mail, so you are not added as a contact
  • Queries DC’s before trying to perform the sync


  • Outlook installed and configured for the user account that run the script
  • Connection and read rights to AD
  • Attribute UserPrincipalName equals the email address for each employee
  • PowerShell 2.0

One annoying thing I have not fixed is that the PowerShell window will be visible during the execution of this script.

$FQDN = "" # The full domain name. EX.
$SearchBase = "OU=Users,DC=local,DC=company,DC=com" # DN for the OU where the users of intereset are. Ex. "OU=Users,DC=local,DC=company,DC=com"
$EmailDomain = "*" # The domain name in UPN. EX.
$OwnEmail = "" # Your own email. This email will be excluded.

# Check if Outlook is running. If not, terminate. If it runs, wait a minute before action. This is to make sure Outlook is running and loaded.
$OutlookTest = Get-Process -Name "OUTLOOK" -ErrorAction SilentlyContinue
if ($OutlookTest -ne $null)
    Start-Sleep -Seconds 60

    # Ping to see if AD is responding, if not, terminate script
    $ADPing = Test-Connection $FQDN -Quiet
    if ($ADPing -eq $true)

        # Get enabled AD users with mobile numbers
        $ADUsers = Get-ADUser -SearchBase $SearchBase -Filter * -Property Enabled,Mobile,UserPrincipalName,Surname,GivenName,Name,ipPhone | Where-Object {$_.Enabled -eq $true -and $_.Mobile -ne $null -and $_.UserPrincipalName -ne $OwnEmail}

        # Get Outlook contacts in default contact folder with company emails
        $Outlook = New-Object –comobject Outlook.Application
        $OutlookContacts = $Outlook.session.GetDefaultFolder(10).items | Where-Object {$_.Email1Address -like ("*@" + $EmailDomain)}

        # Run trough all AD users and update the Outlook contacts list if needed.

        $ADUsers | ForEach-Object {

        $ADUser = $_
        $ADUserMail = $_.UserPrincipalName
        $ADUserFullName = $_.Name
        $ADUserGivenName = $_.GivenName
        $ADUserSurname = $_.Surname
        $ADUseripPhone = (($_.ipPhone) -replace ' ','')
        $ADUserMobile = (($_.Mobile) -replace ' ','')

        $OutlookContactFromADUser = $OutlookContacts | Where-Object {$_.Email1Address -eq $ADUserMail} -ErrorAction SilentlyContinue
        if ($OutlookContactFromADUser -eq $null)
            # Contact does not exist in Outlook, create it in Outlook.
            $OutlookNewContact = $Outlook.session.GetDefaultFolder(10).Items.Add()

            if ($ADUserMail -ne $null) {$OutlookNewContact.Email1Address = $ADUserMail}
            if ($ADUserGivenName -ne $null) {$OutlookNewContact.FirstName = $ADUserGivenName}
            if ($ADUserSurname -ne $null) {$OutlookNewContact.LastName = $ADUserSurname}
            if ($ADUseripPhone -ne $null) {$OutlookNewContact.BusinessTelephoneNumber = $ADUseripPhone}
            if ($ADUserMobile -ne $null) {$OutlookNewContact.MobileTelephoneNumber = $ADUserMobile}
            if ($ADUserFullName -ne $null) {$OutlookNewContact.FullName = $ADUserFullName}


            } # if ($OutlookContactFromADUser -eq $null)

            # Contact exists. Check if values are correct, and update if needed.
            $change = 0

            if ($ADUserMail -ne ($OutlookContactFromADUser.Email1Address)) {$OutlookContactFromADUser.Email1Address = $ADUserMail; $change = 1; Write-Host "01"}
            if ($ADUserGivenName -ne ($OutlookContactFromADUser.FirstName)) {$OutlookContactFromADUser.FirstName = $ADUserGivenName; $change = 1; Write-Host "02"}
            if ($ADUserSurname -ne ($OutlookContactFromADUser.LastName)) {$OutlookContactFromADUser.LastName = $ADUserSurname; $change = 1; Write-Host "03"}
            if ('' -eq ($OutlookContactFromADUser.BusinessTelephoneNumber) -and $ADUseripPhone -eq $null) {} else {if ($ADUseripPhone -ne (($OutlookContactFromADUser.BusinessTelephoneNumber) -replace ' ', '')) {Write-Host ($OutlookContactFromADUser.FullName + "1"); $OutlookContactFromADUser.BusinessTelephoneNumber = $ADUseripPhone; $change = 1}}
            if ('' -eq ($OutlookContactFromADUser.MobileTelephoneNumber) -and $ADUserMobile -eq $null) {} else {if ($ADUserMobile -ne (($OutlookContactFromADUser.MobileTelephoneNumber) -replace ' ', '')) {Write-Host ($OutlookContactFromADUser.FullName + "2"); $OutlookContactFromADUser.MobileTelephoneNumber = $ADUserMobile; $change = 1}}
            if ($ADUserFullName -ne ($OutlookContactFromADUser.FullName)) {$OutlookContactFromADUser.FullName = $ADUserFullName; $change = 1; Write-Host "04"}

            if ($change -eq 1) {$OutlookContactFromADUser.Save(); $change = 0; Write-Host "$ADUserFullName changed something"}
            } # else

        } # $ADUsers | ForEach-Object

        # Check if a contact is present in Outlook but not in AD. If it is, it means the person no longer work at the company. Delete in Outlook.

        $OutlookContacts | ForEach-Object {

        $OutlookContact = $_
        $OutlookContactMail = $_.Email1Address

        $ADUserFromOutlookContact = $ADUsers | Where-Object {$_.UserPrincipalName -eq $OutlookContactMail} -ErrorAction SilentlyContinue
        if ($ADUserFromOutlookContact -eq $null)
            # Contact dont exist in AD. Delete from Outlook.

            } # if ($ADUserFromOutlookContact -eq $null)

        } # $OutlookContacts | ForEach-Object

    } # if (ADPing -eq $True)

} # if ($OutlookTest -ne $null)

Disclaimer: You are responsible for what happens if you use this code. You should always read and understand any code found on the internet before running it.