Exporting Outlook contacts with PowerShell

Who new you could utilise PowerShell to drill into Outlook (while running) and pull out tons of stuff, awesome. I have documented a script which can be used to do just this, a couple of caveats…

*Outlook must be running

*This doesn’t export the contacts picture

*PowerShell will need an Execution Policy set during running e.g Bypass (unless run in a PowerShell windows on user session)

See more about execution policies on the Microsoft technet site –> https://technet.microsoft.com/en-us/library/ee176961.aspx

 

A bit of background: I had a rare instance where the data held in a user mailbox who was moving to a new company within the umbrella of a corporation was sensitive, so a mailbox migration couldn’t be completed and they wanted to take across their contacts to their new mailbox, which spurred the creation of this script and in turn this post.

In this instance for ease of use I will be running the script initiated from a batch script with a bypass execution policy.

powershell.exe -executionpolicy bypass -File "\\SERVER\SHARE\ContactsExport.ps1"

Copy the line of code above into notepad and save as ContactExport.bat, you will be running this batch script through whatever means you choose e.g GPO, management agent, SCCM etc.

I have broken the script down into sections to explain each part:

The $Outlook variable holds the New-Object command which is allowing control of the current session of Outlook, you need to have Outlook already running else PowerShell will attempt to create a new session and error.

$Outlook= NEW-OBJECT –comobject Outlook.Application

We can then drill down to individual folders to extract information, in this case (10) is contacts.

$Contacts = $Outlook.session.GetDefaultFolder(10).items

*** Additional script below to include folders within contacts (pointed out by Mike in comments section)

 

————————————————————————————————————————————————————————————————————————————

$ContactFolders = $Outlook.session.GetDefaultFolder(10).Folders

Exempt additional folders as by default there are Recipient Cache folder, Global address lists and any other type of created address lists. (the one variable exempted all folders other than user created ones, which I found strange, but it works so hey!)

$folderexempt1 = "*Recipient*"

Declare the array so that objects gathered within the For loop can be used outside of itself

$ContactsNested = @()

For loop to loop through each folder and pull contact items, exempting additional folders. (the Folders.items array only accepted integers, which may be a restriction of using Outlook this way )

***Note you need the exemption as if your users have GAL’s this is going to pull all the contacts in there! So be warned

For ($i = 1;$i -le $ContactFolders.count;$i++){

$ContactsFoldersItems = $ContactFolders.Item($i) | Where-Object {($_.Name -notlike "$folderexempt1")}
$ContactsNested += $ContactsFoldersItems.Items 

}

Finally add the contacts within the contact folders to the original $Contacts variable.

$contacts += $ContactsNested

————————————————————————————————————————————————————————————————————————————

 

I have listed all of the different folder numbers and what they relate to below:

GetDefaultFolder(3) - Deleted Items
GetDefaultFolder(4) - Outbox
GetDefaultFolder(5) - Sent Items
GetDefaultFolder(6) - Inbox
GetDefaultFolder(9) - Calendar
GetDefaultFolder(10) - Contacts
GetDefaultFolder(11) - Journal
GetDefaultFolder(12) - Notes
GetDefaultFolder(13) - Tasks
GetDefaultFolder(16) - Drafts
GetDefaultFolder(18) - All Public Folders
GetDefaultFolder(19) - Conflicts
GetDefaultFolder(20) - Sync Issues
GetDefaultFolder(21) - Local Failures
GetDefaultFolder(22) - Server Failures
GetDefaultFolder(23) - Junk Email
GetDefaultFolder(25) - RSS Feeds
GetDefaultFolder(28) - To-Do List
GetDefaultFolder(30) - Suggested Contacts

Next we get the OS’s environmental variable UserName (currently logged in user) ready for naming the exported .csv file.

$user = [Environment]::UserName

We then need to select all of the attributes and details for each contact from the $Contacts variable, here I have selected everything but have listed it all to pick and choose.

$Info = $Contacts | Select FirstName,MiddleName,LastName,CompanyName,Department,JobTitle,BusinessAddressStreet,BusinessAddressCity,BusinessAddressState,BusinessAddressPostalCode,BusinessAddressCountry,HomeAddressStreet,HomeAddressCity,HomeAddressState,HomeAddressPostalCode,HomeAddressCountry,OtherAddressStreet,OtherAddressCity,OtherAddressState,OtherAddressPostalCode,OtherAddressCountry,AssistantTelephoneNumber,BusinessFaxNumber,BusinessTelephoneNumber,Business2TelephoneNumber,CallbackTelephoneNumber,CarTelephoneNumber,CompanyMainTelephoneNumber,HomeFaxNumber,HomeTelephoneNumber,Home2TelephoneNumber,ISDNNumber,MobileTelephoneNumber,OtherFaxNumber,OtherTelephone,PagerNumber,PrimaryTelephoneNumber,RadioTelephoneNumber,TTYTDDTelephoneNumber,TelexNumber,Anniversary,Birthday,Email1Address,Email2Address,Email3Address,Initials,OfficeLocation,ManagerName,Body,Profession,Spouse,WebPage

This is then exported to a .csv file named as the logged in user with the $User variable. The Encoding is set to ensure any contacts which contain funky characters are not made worse.

$Info | Export-Csv -Encoding Unicode -NoTypeInformation "c:\SERVER\SHARE\$user.csv"

That’s it, this should export all contacts to a .csv file ready for importing elsewhere. I will be writing an article on importing this into users mailboxes through Exchange using PowerShell in the coming weeks.

Full Script with comments below, hope it helps.(Updated to include Contact Folders)

#Create Outlook session
$Outlook=NEW-OBJECT –comobject Outlook.Application
#Store the Contacts objects
$Contacts=$Outlook.session.GetDefaultFolder(10).items
#Store the folder objects
$Contactsfolders = $Outlook.session.GetDefaultFolder(10).Folders
#Get the logged in User
$user = [Environment]::UserName
#Contacts folder exemption **Required to remove GAL entries and Recipient Cache**
$folderexempt1 = "*Recipient*"
#Create array for nested contacts (within folders)
$contactsnested = @()
#For Loop takes the total folders starting at folder 1, while less than the total count, will loop with an addition of 1 each time
#The script block cycles through each Object in the Item array where the Object name is not like the exemption and we add this to the variable $conectsnested
For ($i = 1;$i -le $contactfolders.count;$i++){

$ContactsFoldersItems = $contactfolders.Item($i) | Where-Object {($_.Name -notlike "$folderexempt1")}
$contactsnested += $ContactsFoldersItems.Items 

}

$contacts += $Contactsnested
#Select attributes from Contacts
$Info = $Contacts | Select FirstName,MiddleName,LastName,CompanyName,Department,JobTitle,BusinessAddressStreet,BusinessAddressCity,BusinessAddressState,BusinessAddressPostalCode,BusinessAddressCountry,HomeAddressStreet,HomeAddressCity,HomeAddressState,HomeAddressPostalCode,HomeAddressCountry,OtherAddressStreet,OtherAddressCity,OtherAddressState,OtherAddressPostalCode,OtherAddressCountry,AssistantTelephoneNumber,BusinessFaxNumber,BusinessTelephoneNumber,Business2TelephoneNumber,CallbackTelephoneNumber,CarTelephoneNumber,CompanyMainTelephoneNumber,HomeFaxNumber,HomeTelephoneNumber,Home2TelephoneNumber,ISDNNumber,MobileTelephoneNumber,OtherFaxNumber,OtherTelephone,PagerNumber,PrimaryTelephoneNumber,RadioTelephoneNumber,TTYTDDTelephoneNumber,TelexNumber,Anniversary,Birthday,Email1Address,Email2Address,Email3Address,Initials,OfficeLocation,ManagerName,Body,Profession,Spouse,WebPage
#Export .CSV of contacts named with username
$Info | Export-Csv -Encoding Unicode -NoTypeInformation "c:\SERVER\SHARE\$user.csv" 

5 thoughts on “Exporting Outlook contacts with PowerShell

  1. Hi There,

    Thank you very much for this script, my company is in a similar situation and this script is going to help us a ton! Just had a quick question and comment. The script runs great however it doesn’t seem to backup any sub folders you create within your contacts. Is there anyway to backup the contacts folder along with the sub folders?

    Second just wanted to mention that the email field you listed (E-mail1Address,E-mail2Address,E-mail3Address) only works for me when the dashes are removed. So it should be Email1Address,Email2Address,Email3Address.

    Thanks again
    Mike

    1. Hi Mike

      I’ll have a look at nested contacts tonight and get back to you, I’m glad this has helped and thanks for the corrections!

      You might be interested in the next post relating to this for importing the same contacts directly into users mailboxes through EWS, I’ll get the article up over the weekend.

      Cheers

      Chris

  2. FYI –
    #load outlook
    $Outlook= New-Object–comobject Outlook.Application
    # assembly is now available
    #all folder enums
    [Microsoft.Office.Interop.Outlook.OlDefaultFolders]::olFolderCalendar

    Just type:
    [Microsoft.Office.Interop.Outlook.OlDefaultFolders]::
    and hit tab to cycle through folder enums

    No need to remember or save list of folder IDs.

Leave a Reply

Your email address will not be published. Required fields are marked *