Sunday, April 15, 2007

Script: Importing Address Books into Outlook

Last year the University decided to use Exchange as the campus calendaring solution. As you well know, Exchange is a collaboration suite and it is difficult to separate email and calendaring functionality. Thus we also had a large mail migration on our hands.

Migrating mail was simple enough using a combination of drag-and-drop methods of IMAP folders and the Aid4Mail application to migrate local folders to PST files. Migrating address books proved to be a little more difficult. All the documentation on the internet detailed a process of importing a LDIF file into Outlook Express; then converting the Outlook Express address book into Outlook contacts. We found this solution rather cumbersome and it didn’t always import contacts in the desired format.

To solve this problem I wrote a VBScript that would parse a LDIF file and create the associated Outlook contacts.

How it works


First, export your address book as an LDIF file from your old IMAP client. If you have multiple address books you will need to export each into its own LDIF file.

Second, run the ImportLDIF.vbs script from a command prompt using CScript.exe. The script will parse the specified LDIF file and import any contacts/distribution lists included. The script will actually parse the LDIF file twice. The first time it will import any user contacts and the second run will import distribution lists. The LDIF file is parsed twice to ensure that all the contact objects have been created before creating the distribution lists and adding the members.

The script accepts 2 parameters: 1) the LDIF file name and 2) an optional category for all the users/groups in the specified LDIF file. The category option was added for those instances where users previously had multiple address books.

cscript.exe ‹path›\ImportLdif.vbs ‹path›\‹exported file name›.ldif /Category:"Category Name"


When the script enters the distribution list import phase you may be prompted in Outlook to allow the script to access your e-mail address stored in Outlook. Grant the script access for 1 minute to complete the import process.



The Script


'# Author: Nick Smith 
'# http://knicksmith.blogspot.com
'# Script Name: ImportLDIF.vbs
'# Purpose: This script will parse a LDIF file and import user
'# objects as contacts and groups as distribution lists.


'Create a shell object
Dim oShell
Set oShell = CreateObject("Wscript.Shell")

'Ensure the script is run with CScript
CheckForCScript

'Check arguments
If Wscript.Arguments.UnNamed.Count <> 1 then
Wscript.Echo "Usage: cscript ImportLdif.vbs LdifFileName [/Category:""My Category Name""] "
Wscript.Echo vbtab & "/Category" & vbtab & "Optional - Creates a category for the imported address book"
Wscript.Quit
End If

Dim olApp
Dim olNS
Dim contact
Dim contactFolder
Dim contactCategory
Dim bMoveToFolder

Dim mainFSO
Dim objFile
Dim strLine

Const olContactItem = 2
Const olDistributionListItem = 7
Const olFolderContacts = 10

'Create Outlook object
Set olApp = CreateObject ("Outlook.Application")
Set olNS = olApp.GetNamespace("MAPI")

on error resume next

'Open LDIF file
Set mainfso = CreateObject("Scripting.FileSystemObject")
Set objFile = mainFSO.OpenTextFile(Wscript.Arguments.Item(0), 1)
If Err.number <> 0 Then
'Error Opening File. Display Error info.
wscript.echo "Unable to open file: " & Wscript.Arguments.Item(0)
wscript.echo "Error Number: " & Err.number
wscript.echo "Error Description: " & Err.Description
Err.clear

'No reason to continue script so quit
Wscript.quit
End if

'Save the contacts in the default folder
Set contactFolder = olNS.GetDefaultFolder(olFolderContacts)

'Create category if needed
If (Wscript.Arguments.Named.Item("Category") <> "") Then
contactCategory = Wscript.Arguments.Named.Item("Category")
Else
contactCategory = ""
End if
on error goto 0
'*****************************************************************
' Add Contacts First
'*****************************************************************

Dim strSplit
Dim bContact
Dim bFullName

'Start parsing file
Do Until objFile.AtEndOfStream
strLine=objFile.ReadLine

'Create contact object
Set contact = olApp.CreateItem(olContactItem)
bContact = false
bFullName = false
Do Until ((Trim(strLine) = "") or (objFile.AtEndOfStream))
strSplit = Split(Trim(strLine),":")
select case Trim(Lcase(strSplit(0)))
case "objectclass"
if Trim(strSplit(1)) = "person" then
bContact = true
end if
case "givenname"
contact.FirstName = Trim(strSplit(1))
bFullName = true
case "sn"
contact.LastName = Trim(strSplit(1))
case "cn"
contact.FullName = Trim(strSplit(1))
case "mail"
contact.Email1Address = Trim(strSplit(1))
contact.Email1DisplayName = Trim(strSplit(1))
'Save contact as email address if no name
If bFullName <> True Then
contact.FullName = Trim(strSplit(1))
contact.FileAs = Trim (strSplit(1))
End If
case "telephonenumber"
contact.BusinessTelephoneNumber = Trim(strSplit(1))
case "homephone"
contact.HomeTelephoneNumber = Trim(strSplit(1))
case "facsimiletelephonenumber"
contact.BusinessFaxNumber = Trim(strSplit(1))
case "homepostaladdress"
contact.HomeAddressStreet = Trim(strSplit(1))
case "mozillahomelocalityname"
contact.HomeAddressCity = Trim(strSplit(1))
case "mozillahomestate"
contact.HomeAddressState = Trim(strSplit(1))
case "mozillahomepostalcode"
contact.HomeAddressPostalCode = Trim(strSplit(1))
case "mozillahomecountryname"
contact.HomeAddressCountry = Trim(strSplit(1))
case "postalAddress"
contact.BusinessAddressStreet = Trim(strSplit(1))
case "l"
contact.BusinessAddressCity = Trim(strSplit(1))
case "st"
contact.BusinessAddressState = Trim(strSplit(1))
case "postalcode"
contact.BusinessAddressPostalCode = Trim(strSplit(1))
case "c"
contact.BusinessAddressCountry = Trim(strSplit(1))
case "title"
contact.JobTitle = Trim(strSplit(1))
case "ou"
contact.Department = Trim(strSplit(1))
case "o"
contact.CompanyName = Trim(strSplit(1))
case "workurl"
contact.BusinessHomePage = Replace(Trim(strSplit(2)),"//","")
case "homeurl"
contact.PersonalHomePage = Replace(Trim(strSplit(2)),"//","")
case "description"
contact.Body = Trim(strSplit(1))
case "xmozillanickname"
contact.NickName = Trim(strSplit(1))
'Template fo addistional attributes
'case ""
' contact. = Trim(strSplit(1))
end select
strLine=objFile.ReadLine
Loop

'If this is a contact, save it
If bContact Then
contact.Categories = contactCategory
contact.Save
wscript.echo "Contact Created:" & contact.FullName
End If
Loop

objFile.Close


'*****************************************************************
' Now Add Distribution Lists
'*****************************************************************

'Reopen file
Set objFile = mainFSO.OpenTextFile(Wscript.Arguments.Item(0), 1)

Dim subSplit
Dim bList
Dim list
Dim objRcpnt

'Start parsing file
Do Until objFile.AtEndOfStream
strLine=objFile.ReadLine

'Create a distributil list
Set list = olApp.CreateItem(olDistributionListItem)
bList = false
bFullName = false
Do Until ((Trim(strLine) = "") or (objFile.AtEndOfStream))
strSplit = Split(Trim(strLine),":")
select case Trim(Lcase(strSplit(0)))
case "objectclass"
if Trim(strSplit(1)) = "groupOfNames" then
bList = true
end if
case "cn"
list.DLName = Trim(strSplit(1))
case "description"
'list.Description = Trim(strSplit(1))
case "member"
if (Ubound(strSplit) = 1 ) then
subSplit = Split(strSplit(1),"mail=")
if (Ubound(subSplit) = 1) then
'Create recipient with email address
set objRcpnt = olApp.Session.CreateRecipient(subSplit(1))
objRcpnt.Resolve
list.AddMember objRcpnt
end if
end if
end select
strLine=objFile.ReadLine
Loop
'If distribution list, save it
If bList Then
List.Categories = contactCategory
List.Save
wscript.echo "List Created:" & list.DLName
End If
Loop

objFile.Close



Sub CheckForCScript()
If Not Lcase(WScript.FullName) = Lcase(WScript.Path & "\cscript.exe") Then

UsageString = "Please launch script using cscript.exe" & vbcrlf
UsageString = UsageString & "Usage: cscript.exe ImportLdif.vbs LdifFileName [/Category:""My Category Name""] " & vbcrlf
UsageString = UsageString & vbtab & "/Category" & vbtab & "Optional - Creates a category for the imported address book"
oShell.Popup UsageString
WScript.Quit 0
End If
End Sub

Download the script here.

--Nick

4 comments:

Alex said...

When I moved my mail from one folder to another folder,after that mail was damaged.But first of all I found in one blog-outlook express extract.And it helped me,it is free as far as I remember.Moreover program can repair mailboxes in Outlook Express format and extract emails.

Alexis said...

To my mind mail utilities are one of the important program in computer evereone users.Because on example I had a lot of problems with mails.And use-recovery dbx file,it solves issues very easy and quality.Besides that application has free status as far as I know and can reads your mailbox and analysis it for errors.

Anonymous said...

Thanks. The link to the .ZIP did not work for me but the script did. I did a cut and paste through wordpad to handle the LFCR mess.

Renee said...

Wow, Thank You Very Much!

Your script saved me from a huge headache and a great deal of pain...

Best Regards,
Renee