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.

This site uses Akismet to reduce spam. Learn how your comment data is processed.