[Editor's note: The From the Field column is brought to you by Lotus Support, and features technical articles based on our experiences with helping customers to find solutions in the field. This month's article focuses on a customer solution for moving from cc:Mail to Notes Mail by writing agents to ease the transition.]
This solution works with the Lotus tools available now for upgrading cc:Mail users to Notes 4.x. However, Domino 5.0 will include an integrated method for upgrading cc:Mail users to Notes 5.0.
Are you thinking about migrating from cc:Mail to Notes? If so, you've probably already taken a look at Lotus' cc:Mail-to-Notes migration tool (downloadable free of charge from the Lotus Web site). This tool helps administrators move individual cc:Mail users, or an entire post office, over to Notes. While this tool makes migration easy for the administrator, it works at the bits-and-bytes level, and individual users often have to perform additional tasks to complete the migration satisfactorily. Moreover, the migration tool does little to help acquaint former cc:Mail users with the new messaging world of Notes. Typically, that job is left to formal user training, or in some cases, helpful agents or SmartIcons.
Although a migration tool isn't expected to teach users a new e-mail package, the tool is expected to handle every aspect of migration. In some cases, however, the migration tool just can't do everything. Two such examples with the cc:Mail-to-Notes migration tool are as follows:
-
When the Notes administrator performs the migration, the system adds private mailing lists to a Notes database that attaches to a new e-mail message and appears in the user's InBox. Then, to gain access to the migrated mailing lists, users must open this message, detach the attachment, and add this database to their Notes workspace. Not a difficult task for most users; however, the burden of
completing the migration of private mailing lists is on the user.
Note: The issues of private mailing lists and Internet e-mail address conversion do not exist if the users run the migration (Release 4.11 or greater) from their workstation; however, if the Notes administrator controls every aspect of the migration from the Notes server, these issues remain.
- The migration tool saves individual Internet e-mail addresses in cc:Mail (Release 6 and earlier) in a file called PRIVDIR.INI. When the Notes administrator executes the migration, the addresses in this file do not migrate. The workaround for this issue, once again, places the burden on the users, who must create Person documents in their Personal Address Book for each Internet e-mail address previously in their PRIVDIR.INI. And by the way, unless users know that the PRIVDIR.INI exists, they must create Person documents from memory.
Neither of these tasks is insurmountable for most users; however, in a perfect migration, users shouldn't have to worry about such issues.
One customer, in the quest for the perfect migration, dealt with these two issues during a recent cc:Mail-to-Notes migration project. Rather than have the users complete the migration for their private mailing lists and Internet e-mail addresses, the customer created two LotusScript agents that provided a one-button solution for both of these issues. The overall design, and actual code, of these two home-grown LotusScript agents are the focus of this report From the Field.
Note: The LotusScript Agents detailed in this report are for educational purposes and therefore not supported by Lotus Technical Support.
The customer's cc:Mail environment
The customer featured in this report migrated to Notes from a cc:Mail 2.x environment. The former cc:Mail setup had a single cc:Mail hub with four post offices, each supporting approximately 200 to 300 users. The migration project converted one post office per week and used the cc:Mail Message Transfer Agent (MTA) to temporarily support coexistence between the two messaging environments.
Prior to the actual migration project, the customer conducted a migration pilot, using a small group of 20 users. The purpose of the pilot was to test the migration plan and shake out any problems that might exist. A byproduct of this pilot was the discovery of the private mailing list and Internet e-mail address-migration shortcomings.
The manner in which the migration tool handled the conversion of private mailing lists and Internet e-mail addresses was not necessarily a problem. The customer knew, however, that these two items would cause some confusion for certain users. Rather than frustrate those people, the customer quickly went to work at finding a way to overcome these issues.
Automating steps for the user: The private mailing list agent
Overcoming the issue with private mailing list conversion was simple because the hard part of list conversion was already done by the migration tool. The only thing left to do was to create a one-button solution so users didn't have to execute the steps manually. Keep in mind that, when a Notes administrator migrates a cc:Mail user or an entire post office, private mailing lists convert into Group documents and then appear in a new database derived from the Personal Address Book template. Since each user already has a Personal Address Book, the ideal one-button solution (or agent) should execute the following steps:
- Locate the message created by the migration tool that contained the database attachment of private mailing lists.
- Open the message.
- Detach the database attachment.
- Copy each Group document from the database and paste it into the pre-existing Personal Address Book.
- Delete the detached database.
- Delete the message.
It is one thing to create a list of steps to be automated; it is yet another to create the agent that actually executes these steps. The agent is supposed to act on a specific message and attachment. Therefore, the agent needs a way to distinguish this message and attachment from all others in the mail database. Fortunately, when the migration tool converts private mailing lists, it creates two useful pieces of information that are always the same:
- The subject line for the message containing the attachment: "cc:Mail Migrated Private Mailing List is attached"
- The file name of the attachment: CCPMLIST.NSF
Knowing the subject line of the message that contains the attachment and knowing the file name of that attachment provides the agent with nearly everything it needs to successfully find the message and work with the attachment. The agent also needs to know that the Personal Address Book for every user in the customer's environment has the file name NAMES.NSF. With these three pieces of information, the customer designed an agent to:
- Search through the InBox for a message with the subject line "cc:Mail Migrated Private Mailing List is attached." If the agent finds such a message, it removes the attachment (CCPMLIST.NSF) and saves it on the user's local disk drive. Otherwise, the agent informs the user that there are no private mailing lists.
- Open the detached database and copy each Group document to the user's pre-existing Personal Address Book.
- Delete the message and the detached database.
The following illustration shows a flowchart of the process the agent follows:
Figure 1. A flow chart of the private mailing list agent
Transforming a process flow diagram into a useful agent resulted in the following LotusScript code:
Sub Initialize
Dim db1 As NotesDatabase
Dim collection As NotesDocumentCollection
Dim doc As NotesDocument
Dim object As NotesEmbeddedObject
Dim session As New NotesSession
Dim j As Integer
Dim Subject As Variant
Dim FoundIt As Integer
Dim Pab As String
Dim Comma As String
Dim Position As Integer
Comma = ","
FoundIt = False
Pab = session.GetEnvironmentString("NAMES", True)
Position = Instr(1,Pab,Comma,1)
If Position >0 Then
Pab = Left$(Pab,Position -1)
End If
Dim db2 As New NotesDatabase("",Pab)
Set db1 = session.CurrentDatabase
Set collection = db1.AllDocuments
Set doc = collection.GetLastDocument()
Do While Not (doc Is Nothing)
If doc.HasItem("Subject") Then
Subject = doc.Subject
If Subject(0) = ("cc:Mail Migrated Private Mailing
List is attached") Then
FoundIt = True
Set object = doc.GetAttachment( "ccpmlist.nsf" )
Call object.ExtractFile( "c:\ccpmlist.nsf" )
Call doc.Remove(True)
Exit Do
End If
Set doc = collection.GetPrevDocument(doc)
End If
Loop
If FoundIt = True Then
Dim db3 As New NotesDatabase("","c:\ccpmlist.nsf")
Set collection = db3.AllDocuments
Set doc = collection.GetFirstDocument()
While Not (doc Is Nothing)
Call doc.CopyToDatabase(db2)
Set doc = collection.GetNextDocument(doc)
Wend
Call db3.Remove
Else
Messagebox "You do not have any private mailing lists to extract."
End If
End Sub |
The LotusScript code starts with several variable
declarations and value assignments. These variables make it
possible to work with the current mail database, Personal
Address Book, and file attachment. After these variables
are declared, a
For
loop begins in which the agent tests the subject of each document in the mail database. The agent compares the value of the subject line to the string "cc:Mail Migrated Private Mailing List is attached." If it finds a match, it assigns the variable
FoundIt
the value "True." The agent detaches the attachment, saves it to the local drive (C:\), and deletes the message. If none of the documents passes the subject-line test, the value of
FoundIt
remains "False."
Note: This script is specifically designed for a PC with a local "C:\" drive, and therefore won't work with Macintosh clients or other clients without a "C:\" drive.
After the
For
loop ends, the agent tests the value of
FoundIt.
If
FoundIt
equals "True," the agent copies each document from the detached database (CCPMLIST.NSF) to the user's Personal Address Book, and deletes the detached database. If, however,
FoundIt
does not equal "True," a message appears that informs the user that there are no private mailing lists to extract.
The customer used the private mailing list agent successfully throughout the migration project. However, in situations where the private mailing lists contained characters not supported by the migration tool, the agent failed. This failure was not the fault of the agent because attempts to extract the attached database manually also failed. The issue of unsupported characters is clearly documented in the migration tool's "User's Guide." Therefore, the customer was well aware of the character limitation and considered the agent extremely successful despite its occasional breakdown.
The extra mile: The Internet e-mail address agent
Next the customer wanted to extract Internet e-mail addresses contained in each user's personal PRIVDIR.INI file and place them in a Person document in the Personal Address Book.
The PRIVDIR.INI file is what cc:Mail (Release 6 and earlier) uses to store personal Internet e-mail addresses. Any user who has ever sent a message to an Internet e-mail address has one of these simple text files stored on the local hard drive. Since the file is stored locally, the migration tool can't access it when it runs from a Notes server. The workaround for this situation is to have each user manually perform the following steps:
- Find and open the PRIVDIR.INI file.
- Copy the Internet e-mail address in the file.
- Create a new Person document in the Personal Address Book.
- Paste the Internet e-mail address into the e-mail address field.
- Optionally fill in the first name, last name, and full name fields.
- Save the new Person document.
- Repeat steps 2 through 6 until no more Internet e-mail addresses remain in the PRIVDIR.INI file.
The customer felt that this manual user intervention was unnecessary and created a LotusScript agent to:
- Search the default directory location for the PRIVDIR.INI file (C:\WINDOWS\CCMAIL\CC1DIR).
- If the file is not found, increment the number in the CC1DIR directory name and search that directory (C:\WINDOWS\CCMAIL\CC2DIR). Continue directory-name number incrementing until finding the PRIVDIR.INI file or until reaching CC9DIR.
- If the file is not found, inform the user and stop running.
- If the file is found, open the file for reading.
- Ask the users if they want to enter a first and last name for each address as it's extracted.
- If the answer is No, extract each address, create a new Person document in the Personal Address Book, and stop running.
- If the answer is Yes, extract each address and allow the user to add a first and last name for each address.
- Take the additional information and create a new Person document in the Personal Address Book. The additional information helps fill in the following fields: First name, last name, full name, and e-mail address.
- Repeat steps 7 and 8 until no addresses remain.
The following illustration shows a flowchart of the process the agent follows:
Figure 2. A flow chart of the internet e-mail address agent
The steps came together in the following LotusScript code:
Option Public
%INCLUDE "LSCONST.LSS"
Sub Initialize
Dim session As New NotesSession
Dim doc As NotesDocument
Dim iEndOfFile As Integer
Dim iFileNum As Integer
Dim iReadLn As Integer
Dim iCharPos As Integer
Dim iRightNum As Integer
Dim iAnswer As Integer
Dim iCount As Integer
Dim iFileCount As Integer
Dim i As Integer
Dim tAtSign As String
Dim tFlatFileRecord As String
Dim tCharComp As String
Dim tInternetName As String
Dim tFormType As String
Dim tFirstName As String
Dim tLastName As String
Dim tPath As String
Dim tSubPath As String
Dim tFullPath As String
Dim tFileName As String
Dim tName As String
Dim tPab As String
Dim tComma As String
Dim iPosition As Integer
tComma = ","
tPab = session.GetEnvironmentString("NAMES", True)
iPosition = Instr(1,tPab,tComma,1)
If iPosition >0 Then
tPab = Left$(tPab,iPosition -1)
End If
Dim db As New NotesDatabase("",tPab)
iFileNum = Freefile
tCompChar = "="
tAtSign = "@"
tFormType = "Person"
iCount = 0
iFileCount = 0
tPath = "U:\WINDOWS\CCMAIL\"
tSubPath = ""
On Error Goto EndOfFile
For i = 1 To 10
tFullPath = tPath + tSubPath + "*.*"
tFileName = Dir$(tFullPath, 0)
Do While tFileName <> ""
If Instr(1, tFileName, "privdir.ini", 1) > 0 Then
tName = tPath + tSubPath + tFileName
iFileCount = 1
Exit For
End If
tFileName = Dir$()
Loop
tSubPath = "cc" + Cstr(i) + "dir\"
Next
Open tName For Input As iFileNum
iAnswer = Messagebox("Do you want to extract
and add old cc:Mail Internet addresses interactively?
Yes allows you to add a first and last name for
each address extracted. No simply extracts the
Internet addresses and adds them to your Personal Address Book",
MB_YESNO + MB_ICONQUESTION, "Interactive Mode?")
If iAnswer = IDYES Then
While Not Eof(iFileNum)
Line Input #iFileNum, tFlatFileRecord
If Instr(1, tFlatFileRecord, tCompChar, 0) > 0 Then
iRightNum = Len(tFlatFileRecord)
- Instr(1, tFlatFileRecord, tCompChar, 0)
tInternetName = Right(tFlatFileRecord, iRightNum)
If Instr(1, tInternetName, tAtSign, 0) Then
tFirstName = Inputbox$
("What is the FIRST NAME for "
+ tInternetName + "?")
tLastName = Inputbox$
("What is the LAST NAME for "
+ tInternetname + "?")
Set doc = db.CreateDocument
doc.FirstName = tFirstName
If tLastName = "" Then
doc.LastName = iInternetName
Else
doc.LastName = tLastName
doc.FullName = tFirstName
+ " " + tLastName
End If
doc.MailAddress = tInternetName
doc.Type = tFormType
Call doc.Save( True, True )
iCount = iCount + 1
End If
End If
Wend
Else
While Not Eof(iFileNum)
Line Input #iFileNum, tFlatFileRecord
If Instr(1, tFlatFileRecord, tCompChar, 0) < 0 Then
iRightNum = Len(tFlatFileRecord)
- Instr(1, tFlatFileRecord, tCompChar, 0)
tInternetName = Right(tFlatFileRecord, iRightNum)
If Instr(1, tInternetName, tAtSign, 0) Then
Set doc = db.CreateDocument
doc.LastName = tInternetName
doc.MailAddress = tInternetName
doc.Type = tFormType
Call doc.Save( True, True )
iCount = iCount + 1
End If
End If
Wend
End If
Messagebox ( "Process complete. " + Cstr(iCount)
+ " Internet addresses added to your Personal Address Book.")
EndOfFile:
If iFileCount = 0 Then
Messagebox "No Internet addresses were defined
in your cc:Mail account."
Close #FileNum
Exit Sub
End If
Close #iFileNum
End Sub |
The LotusScript code starts with several variable
declarations and value assignments. After the agent
declares these variables, it begins a
For
loop. This loop repeats a maximum of ten times and searches several directories for the PRIVDIR.INI file. The first pass through the loop starts with U:\WINDOWS\CCMAIL. If a search of that directory is unsuccessful, the agent adds CC1DIR to the path, creating U:\WINDOWS\CCMAIL\CC1DIR. The agent then checks this directory. If this search is also unsuccessful, the agent increments the number found in the complete path name, and checks that directory (for example, U:\WINDOWS\CCMAIL\CC2DIR, U:\WINDOWS\CC:MAIL\CC3DIR, and so on). This process of incrementing and searching continues until the agent reaches U:\WINDOWS\CCMAIL\CC9DIR, at which point it searches this directory and the loop ends. If at any time the search is successful, the loop immediately ends.
Note: The U:\ drive is specific to the customer's environment. Other environments might use different drive and directory names.
After the loop ends, either by successfully finding the
PRIVDIR.INI or repeating the maximum of ten times, the
agent attempts to open the PRIVDIR.INI file. If the file is
found, this attempt is successful and the script continues;
however, if the file isn't found, this attempt causes an
error that sends the script down to the section labeled
EndofFile. This section displays a message for the user stating that there are no Internet e-mail addresses to extract. Then the script ends.
Successfully opening the PRIVDIR.INI file produces a
message that asks the users whether they want to extract
addresses interactively. Answering
No
causes the script to move quickly through the PRIVDIR.INI file, extracting each address and creating a new Person document in the Personal Address Book. In contrast, answering
Yes
causes the script to extract an address and then prompts the user for the first and last name associated with this address. The user-supplied values appear in the appropriate fields in the new Person document, which the agent then saves in the Personal Address Book. This process continues until the PRIVDIR.INI contains no addresses. When complete, a message appears indicating how many addresses were extracted.
The customer ran this agent flawlessly throughout the migration project, with users having no idea how much time was saved with this agent. Isn't that always the case?
These two
home-grown
LotusScript agents were designed to make the transition to Notes a little easier for recently migrated cc:Mail users. These agents were the result of
one
customer's migration experience, and similar to the official cc:Mail-to-Notes migration tool, these additional agents can't be all things to all people. Therefore, the agents described in this article may not prove useful for everyone.
How will you know whether these agents will help your migration project? The only way to answer this question is to follow the lead of this article's featured customer: conduct a migration pilot. Look for ways to improve the migration process and ease the transition for your user community. If you keep these goals in mind, your project is bound for success.
Bret Swedeen joined Lotus in the summer of 1997 as a Principal Knowledge Architect. Bret has worked in the computer industry for nearly 8 years doing everything from Notes phone support at Corporate Software to Notes consulting at Coopers & Lybrand. A Certified Netware Engineer (CNE) and Certified Lotus Professional (CLP) System Administrator and Application Developer, Bret has also written articles for the Lotus Notes Advisor, Database Advisor, LAN Times, and LAN Magazine. Most recently Bret authored the Lotus Notes 4.5 Administrator's Guide from Sybex publishing.
Comments (Undergoing maintenance)





