Rick Tatem Messaging and Directory Resources Group

Дата канвертавання25.04.2016
Памер67.15 Kb.

Pushing The Envelope With Perl: Using Perl With Microsoft Exchange

Rick Tatem

Messaging and Directory Resources Group


Cary, NC



This paper describes the use of Perl for managing and extending the Microsoft Exchange messaging system. Perl’s versatility has made several critical (and expensive!) tasks possible. From synchronizing the Exchange Directory Service with our employee directory to reporting on the volume of mail traffic between servers and sites, Perl has proven itself up to the task. Perl is used in several incarnations: plain scripts, PerlScript in ASP pages, “executable” (IndigoSTAR’s perl2exe), and Win32 COM objects (ActiveState’s PerlCtrl). In an environment where solutions are usually needed yesterday, Perl has always delivered.

Brute Force

Most of the Perl solutions I have implemented over the years have been of a nocturnal nature. They run very late at night and try to attract as little attention as possible. Most of them began their existence as quick, nimble, and focused on immediate needs. Over time, due to never-ending requests for feature enhancements and handling of exceptional input, they have become more like lumbering beasts of burden. While certainly not pretty, they do their nightly tasks without a whimper. Interaction is not necessary (or even wanted).
As is the case in most technology companies, it is a constant struggle to keep pace with all of the advances being made on both the software and hardware fronts. Time to soak in knowledge is a luxury. Hence, most of the innards often come from code pilfered from any book, web site, Q article, or colleague that has anything that even remotely resembles something useful. It is open source… right?

Humble Beginnings

SAS Institute decided in 1996 that the standard corporate desktop would be the “Wintel” platform (low cost Intel processor PCs running Microsoft Windows NT). The back-end would continue to be the usual mix of UNIX (HP and Sun, mostly) and NT. As part of that decision, Microsoft Exchange was also deemed the new corporate messaging platform. At the time, the support staff for the PC platform was not capable of immediately handling the additional workload. Because the UNIX support group had been handling the email system (sendmail on HPUX) it was thought that perhaps they would be interested in getting involved. I was approached since I had been stuck in the world of backups and restores for 2 years. ANYTHING else was an improvement. So I transitioned from the UNIX world to NT… and I brought Perl along with me.
Because of my inexperience with Exchange and Windows in general, most of the early solutions were merely text-based processing. These “quickie” solutions resulted in .bat files for executing manually. Because of Exchange’s close ties with the underlying operating system, often the problems to be solved were closely related to the NT accounts. Perl is adept at supplying arguments for common NT administrative commands, such as “net user” for creating accounts. Although primitive, (in my own opinion) these “quickie” tools provided a wonderful opportunity to evangelize Perl to the main NT/PC support staff. Without exaggeration, there were several instances of outright astonishment as to the ease with which Perl could provide these ad hoc tools. (Using ‘vi’ instead of ‘notepad’ also added to the fun.)
The first purely Exchange-related process to be automated was transferring employee data (office, phone, title, etc.) from our corporate Employee Directory (a SAS Dataset, naturally) to the Microsoft Exchange Directory Service. I admit, I’m not really a SAS programmer, so the bulk of the process is taking the output of few simple SAS Data Steps (text files) and “massaging” them enough to match the fields necessary for importing into the directory.
Growing Up Quickly

As the demands and expectations of administering our Microsoft Exchange site grew, I searched (mostly in vain) for examples using Perl for solutions to the tasks before me. There were some very useful sources (Dave Roth’s site, http://www.roth.net/perl/, in particular) but they mainly dealt with the OS and general account maintenance. There wasn’t a lot of Exchange-specific code in Perl. But there is a wealth of samples using Visual Basic.

Visual Basic (and more often VBScript), while easy to learn and rife with sample code, couldn’t sway me completely. There are still plenty of routines that are more comfortable to do in Perl. Arrays and hashes, in particular, are much simpler to manipulate in Perl. As it turns out, “translating” from most VB/VBScript samples to Perl is actually achievable without too much effort.
Listing 1 shows a VBScript that asks for an email address in SMTP format and returns the corresponding Display Name and Distinguished Name of the Directory Object. Listing 2 shows the same thing, with the exception that the email address is a command-line argument.

Listing 1

Listing 2

Set conn = CreateObject("ADODB.Connection")

conn.Provider = "ADSDSOObject"

conn.Open "ADsProvider;CN=uid,DC=DOMAIN;passwd"

myEmail = inputbox("Enter First.Last@sas.com address:")
Set rs = conn.Execute(";(mail=" & myEmail & _ ");adspath,cn;subtree")
While Not rs.EOF

msgbox rs.Fields(0) & vbcrlf & _






use strict; # Always!

use Win32::OLE;

my $conn = Win32::OLE->new("ADODB.Connection");

$conn->{'Provider'} = "ADsDSOObject";

$conn->Open("ADs Provider;CN=uid,DC=DOMAIN;passwd");
my $Email = $ARGV[0]; # lazy

my $rs = $conn->Execute(";(mail=$Email);adspath,cn;subtree");

while ( !$rs->EOF ) {

print $rs->Fields('adspath')->value . "\n" .

$rs->Fields('cn')->value . "\n";





The object/property/method approach of VB fits neatly into Perl. While VB uses the “dot” notation (object.method or object.property), most examples I’ve seen in Perl distinguish between properties and methods (object->Method() vs. object->{‘Property’}). As is the Perl way, there’s more than one way to do it. This is the way I’ve chosen, as I consider it easier to follow with “method as function”. The Win32::OLE modules do the lion’s share of the work.

Delivering the Goods

A handful of projects have really showcased the power and adaptability of Perl in working with a complex application such as Microsoft Exchange. Exchange is more than simply email. Exchange encompasses many facets of a Windows computing environment: networking, databases, directory services (LDAP), account maintenance, collaboration, etc. Perl has been used, in one form or another, with all of these. A few projects in particular demonstrate Perl’s ability to quickly and effectively deliver a solution when and where it’s needed. Table 1 contains some Exchange-specific terms and a brief description of each. The solutions presented will include these terms often.

Table 1

Exchange-related Term


Information Store

The underlying database containing all mail messages, attachments, and other various items. There are two types of Information Store: Public and Private. The Public Store is the content of the Public Folders “homed” on the server holding the Store. The Private Store is the content of all user mailboxes “homed” on the server holding the Store.


An administrative grouping of one or more Exchange Servers connected to the same local area network.


The root of the directory. All Exchange sites belong to the Organization.

Public Folder

A specialized mailbox for sharing among many users. Can receive e-mail. Contents kept separate from user mailboxes.


Messaging Application Programming Interface. An API providing access to Messaging systems such as Exchange. Difficult to work with, at best.


Global Address List. All mail recipients in an Exchange Organization.


Active Directory Services Interface. An API for accessing Windows 2000 Active Directory. Also provides access to Exchange 5.5 directory and Windows NT 4 accounts. Easily accessible via the Win32::OLE modules.


Lightweight Directory Access Protocol. Internet standard for directory services. Exchange 5.5 and Windows 2000 Active Directory are LDAP v.3 compliant. Great way to get the UNIX folks to access the Exchange directory.

Directory Name

The unique identifier in the Exchange Directory of an object. Appears in the same context as the Relative Distinguished Name in an LDAP directory. However, the Exchange Directory forces uniqueness throughout the entire Organization, not just within the same directory node. Like having unique filenames for all files on a disk.

Distinguished Name/AdsPath

The fully qualified name of an object, from the root of the directory. Like a fully qualified pathname for a file. If you know (or can construct) this, you can access the object directly, instead of having to perform a search for it.

Message Tracking

I was pleasantly surprised to find Perl mentioned prominently in the July 2000 issue of Exchange Administratori. The article discusses using Perl to parse the message tracking logs generated by Microsoft Exchange. The logs are plain text containing tab-separated fields. Exchange provides the ability to track messages within the Exchange Administrator GUI, so there had not been much push for anything more. The Perl code contained in the article was, to put it bluntly, quite simple. It merely split() each line into an array then, based on the value of one field (specifically the ‘Event’ field), incremented two counters. This simple parsing yielded (according to the article) the number of messages delivered locally, the number sent to another server, and their ratio.
These numbers are can be quite useful to an Exchange administrator. Exchange utilizes “single instance storage”, meaning that regardless of how many recipients on an Exchange server a message is to be delivered, only one instance of the message (body and all attachments) exists in the Information Store (database). By being selective when putting mailboxes on servers, the Exchange Administrator can minimize both the traffic of messages between servers and sites, and the cumulative size of the mail databases.
It became apparent after trying out the code that it needed some improvement. There were two main points where the example provided did not succeed. First, the ‘Local Delivery’ event (Event ID 1000) indicates both the submission and delivery in a single instance. In the case of this particular event, a ‘Message Submission’ event (Event ID 4) is not always noted. If a message is addressed only to local recipients, no ‘Message Submission’ event is triggered. So subtracting the number of ‘Local Delivery’ events from the number of ‘Message Submission’ events is incorrect. Secondly, a submitted message may still end up delivered locally, though not in the context of the ‘Local Delivery’ event. By noting the message-id of submitted messages (Event ID 4) and delivered messages (Event ID 9), a more accurate assessment of message delivery can be made. Listing 3 shows the improved (though still not perfect) report.

Automated Rules-based Distribution Lists

As the number of employees using Exchange grew, there were several processes that begged for updates. Most of SAS’ official corporate mailing lists were hosted by the ListServ system running on VM. All mailing lists based upon employee data (departments, divisions, buildings, etc.) were maintained automatically. Because of the visual nature of the Global Address List, employees began requesting that these lists be made available in the GAL.
Because many of these lists were quite large it was not practical to continue using simple directory import/export files. Also, because we were trying to mimic the behavior of the ListServ lists, we needed to have archives available. Exchange Public Folders were the obvious choice, but manipulating them automatically can be tricky.
Microsoft’s example code for creating Distribution Lists based on search criteria were found to be lacking. While useful for initially creating the list, they provided no logic for updating existing lists. Also, some of our existing lists used data not yet available in the Exchange directory. A query-based solution was not appropriate at the time.
I came up with a process to provide exactly the same functionality as was currently on the VM ListServ system, including archives. Lists and archives are designated by an entry in a text file called DLRULES.TXT”. This file contains three comma-separated fields: list alias, list rule, and list display name. The list rule is written in Perl syntax. For example:
MNR,(($unit eq 'MNR') && ($location eq 'Cary')),*Dept: MNR Multivariate & Numerical R&D)

Listing 3

#Message Tracking Log parser


use strict;


my ($eventid,$submitted,$locally,$remotely,$count,$repdate);

my ($messageid,%sent,$returns);

@servers = qw(SERVER01 SERVER02); #replace with your own server names

foreach $server (@servers) {

unless (opendir(DIR,"//$server/tracking.log")) { # the tracking.log directory is shared by default

print "Cannot open directory on $server: $!\n";



@tfiles = grep { /\.log$/ } readdir(DIR);


foreach $count (0 .. 6) {

open(TLOG, "

die "Cannot open tracking log @tfiles[$count] on $server: $!\n";

# Reset counters… bound to be a more clever way...

$submitted = 0;

$locally = 0;

$remotely = 0;

$returns = 0;


while() {


($messageid,$eventid) = (split(/\t/))[0,1];

# Event ID 4 - Message Submitted by client

if ($eventid == 4) {


$sent{$messageid} = 0; # will remain 0 if no local delivery

# Event ID 1000 - Local Delivery (no transfer)

} elsif ($eventid == 1000) { # send/recieve at same time


# Event ID 9 - Message Delivery

} elsif ($eventid == 9) {

if (defined($sent{$messageid})) { # sent from this server



} }

close (TLOG);

foreach (keys(%sent)) {

if ($sent{$_} == 0) {


} else {



substr(@tfiles[$count],6,0) = "/";

$repdate = substr(@tfiles[$count],4,5);

print "\nDelivery Numbers for $server ($repdate)\n";

print "-------------------------------------------\n\n";

print " $submitted messages submitted by users\n\n";

print " $remotely sent off server\n\n";

print " $returns messages delivered to server\n\n";

print " $locally delivered locally (no transfer)\n\n";


Allowances are made to include exceptions to the membership rules in the “DLEXCEPT.TXT” file. Of the seven steps listed below, five of them are purely for dealing with the public folder archives. A single Perl program (autodl.exe) handles the actual creation and update of the distribution lists.

Here are the steps involved:

  1. Export recipient information from the Global Address List and our corporate employee data in order to map between the Exchange Directory Name (the unique identifier for an object) and an Employee Number (the unique identifier in our Corporate data). These files will be used to determine membership.

  2. Create an archive public folder, if necessary.

  3. Export information for public folders. (directory name in particular)

  4. Create two files for importing temporary changes to the archive folders (show/hide from address book).

  5. Change the “hide from address book” property of the archive folders temporarily to “False”.

  6. Update/create the distribution lists. (autodl.exe)

  7. Change the “hide from address book” property of the archive folders back to “True”.

The autodl.exe executable is the heart of the automated distribution list create/update process. Because of the nature of the server running the updates (it is used for all scheduled administrative jobs), there was concern about changing the configuration in any way… including the installation of Perl. To avoid that issue, we have a licensed copy of perl2exe from IndigoSTAR software (http://www.indigostar.com/perl2exe.htm). This allows the creation of completely stand-alone executable, which is much easier to convince the other NT administrators to approve.

The logic is straightforward:

  1. Employee data is read into a hash

  2. Each rule (from the DLRULES.TXT file) is eval’ed for each employee.

  3. If the eval is TRUE, then the employee number is pushed into an array of employees who should be members of that distribution list.

  4. If the corresponding Distribution List exists, then the current membership (read directly from the list properties and pushed into an array) and the eval’ed membership array are compared to determine who needs to be added or deleted.

  5. Otherwise the list is created and populated.

Listing 4 shows example code. It shows the create_DL and dl_enum subroutines. The dl_enum subroutine accesses an existing distribution list and enumerates the membership. It then returns a reference to an array of the current members.
Having Public Folders available for archiving messages to the list is tricky to implement. By default, Public Folders are not visible in the Address Book. This also means they aren’t visible by normally used ADSI routines. In order to get things working quickly, I decided to forego much of the programmatic access to Public Folders. Instead, I utilize a special import/export routine to expose the Public Folders to the Address Book just while the list updates are occurring. I use the dsimport.exe and dsexport.exe programs from Microsoft’s Platform SDK. By utilizing specific syntax in naming the folders, it’s easy to create the necessary syntax for including them in the lists.
As hinted to earlier, this process is one of the lumbering beasts toiling away in the wee hours of the morning. It’s not the most efficient Perl in the world, although I have made some attempts at keeping things in check. Currently there are more than 350 lists being updated nightly, some with up to four thousand members.


The next step is to get rid of our dependency on the ListServ system entirely (as we have it implemented). Exchange and the Outlook client provide the basic “owner-controlled” list functionality. A list is owned

Listing 4

sub create_DL {

my $dldn = shift(@_);

my $DL = "cn=" . $dldn;

my $DisplayName = $DISPLAY{$dldn};


## Edit strings below to match requirements

my $SMTP = $dldn . "\@corp.com";

my $DLDN = $DL . ",cn=Recipients,ou=Site,o=Organization";

my $DLX400 = "c=US;a= ;p=Organization;o=Site;s=" . $dldn . ";";

my $CPath = "LDAP://$EXSERVER/cn=Container,ou=Site,o=Organization";

my $myIADS = Win32::OLE->GetObject("LDAP:");


# ***IMPORTANT*** Put a valid userid/password combo in the line below!!!

my $Recipients = $myIADS->OpenDSObject($CPath,"dc=Domain,cn=userid",'password',0);

my $newDL = $Recipients->Create("groupOfNames",$DL);


$newDL->Put("uid",$dldn); # Alias

$newDL->Put("name",$dldn); # Simple Display Name




$newDL->Put("info","This list is created automatically from information in the ALLEMPS dataset.");

$newDL->SetInfo; # Commit changes


return "LDAP://$EXSERVER/$DLDN";


sub dl_enum


my $adspath = shift;

# Having the AdsPath makes access so easy…

my $DL = Win32::OLE->GetObject($adspath);

my $mems = $DL->Members;

my $Enum = Win32::OLE::Enum->new($mems);

my @MEMS = $Enum->All;

my (@members,$member,$dname);

foreach $member (@MEMS) {



return \@members;


and maintained by one or more persons. The automated distribution list job takes care of the lists that have fixed membership (in the sense the no one decides who is/isn’t a member). What was missing was the concept of the “open” list: distribution lists that anyone could join/leave as they wished.

At first we looked at most of the options already available, mostly from third parties. The one overwhelmingly lacking feature of all products we examined was their lack of integration with the Exchange Directory Service. The product from Reddfish (http://www.reddfish.co.nz/reddfish/listserver/) requires a separate recipients container and new directory objects for ALL list members… even those already in the directory. We felt this was unacceptable. Managing the primary recipients container was enough work, we didn’t want to duplicate our efforts. The product from NTP Software (http://www.ntpsoftware.com/products/lm/) doesn’t even use the directory. It stores all subscribers in a Personal Address Book. (There’s an Exchange Administrators’ mantra. Say it with me: “PAB=BAD”) Even an example solution from Microsoft was weak. Well, that wasn’t good enough, so I did it myself.
The solution I came up with is NOT a complete solution (although I’m working on it ). However, it does solve the immediate need: provide a mechanism for SAS employees to join/leave mailing lists hosted on SAS’ Exchange servers. The major missing piece is the ability to allow external recipients as members (without compromising the directory). The surprising thing is that this solution accomplished with four pieces: an Exchange mailbox, a Public Folder, an Exchange Server Event Script (written in VBScript), and a COM Object/ActiveX Control written in Perl (and compiled into DLL form by PerlCtrl, part of the Perl Development Kit from ActiveState Tool Corporation). No new service needs to be installed. No overtly suspicious permissions are required.
DLManager consists of a mailbox, a public folder with an event script, and the ActiveX control. The Exchange 5.5 Event Service provides asynchronous events. This means that by the time the event actually registers, the underlying message may not be in the same state. For example, the ONDELETE event can only be used as an indicator, since by the time you see the event, the message has, in fact, been deleted. While not appropriate for all possible scenarios, the requirements for DLMANAGER are not time critical.

The Event Script actually does very little. When a message arrives, it extracts the sender and the subject and just hands them over to the DLL. The sender is resolved against the Global Address List if possible, and the subject is parsed to determine if a valid command has been sent. Based on the resulting command and the sender, the Event Script either sends an error message, or continues by calling the appropriate methods of the control (subscribe/unsubscribe/etc.), then sending the results back to the sender. All access is based on the directory and its security. If the sender isn’t in the directory, they don’t count!

There was one particularly troublesome problem to overcome: not all employees are Exchange (or more specifically, Outlook) users. Many of these employees have Custom Recipients (i.e. aliases) instead of mailboxes. This presented a challenge since the ‘sender’ of the message (as viewed by the Event Script) wouldn’t already be resolved against the directory. To further complicate matters, some of these folks had been set up with a Mailbox (so they could use the calendaring functions) and a Custom Recipient (Exchange’s way of providing forwarding). Depending on where such a person originated the message determined whether they could be verified against the directory. We were able to make the stipulation that such persons should send mail from their “primary mail account”. In a development environment, it’s not unusual to have mailboxes spread over a wide variety of hosts: UNIX/Windows/mainframe/etc. I devised a three-step query to determine whether the sender resolves to a GAL entry.
Listing 5 is the Event Script. Most of the code is of the housekeeping variety. NOTE: I have edited out some of the debugging/logging to save space. Listing 6 is the Subscribe method (the Unsubscribe is quite similar). Note that this method demonstrates the special sender query as described above.
Our Sales & Marketing division has used DLManager heavily. One of the first lists offered by DLManager was a list to subscribe to our monthly corporate “webzine”… currently more than 1100 subscribers.
There are several benefits to DLManager:

  1. Relies on the Directory (secure)

  2. A DLManager list is a normal list (owner can still modify as usual)

  3. By using the subject line for commands, it is easily incorporated into web pages (mailto:dlmanager@corp.com?subject=subscribe%20listname)

Other Perl goodies

I’ve used Perl in several other capacities, as well. I’ve used PerlScript in web page for creating general distribution lists (including a checkbox for making it a ‘DLManager’ list!). Tools have been provided to our Help Desk support staff for tasks such as “cleaning up” the directory: removing objects, including ‘hidden’ ones, from distribution lists and removing Access Control List entries from Public Folder Permissions. So far, there hasn’t been anything that couldn’t be done using Perl.

Listing 5 – DLManager Event Script

Option Explicit

Dim gc_ReplySubject

gc_ReplySubject = "Your DLManager request..."

' Event Handler Description: This event is fired when a new message is added to the folder

Public Sub Folder_OnMessageCreated

Dim oSession

Dim oCurrentMsg

Dim oReplyMsg

Dim oFolderOutbox

Dim oRecipient

Dim str_Log

Dim oSender

On Error Resume Next


Set oSession = EventDetails.Session

Set oCurrentMsg = oSession.GetMessage(EventDetails.MessageID,NULL)

oCurrentMsg.Unread = False

str_Log = "Message received, Subject=" & oCurrentMsg.Subject & ";Sender=" & oCurrentMsg.Sender.Name

Set oFolderOutbox = oSession.Outbox

Set oReplyMsg = oCurrentMsg.Reply

Set oSender = oCurrentMsg.Sender

oReplyMsg.Subject = gc_ReplySubject

Dim str_return

Dim ctrlDLManager

Set ctrlDLManager = CreateObject("PRK.DLManager")

ctrlDLManager.Subject = oCurrentMsg.Subject

ctrlDLManager.UserID = oSender.Address

str_return = ctrlDLManager.ParseSubject

Select Case str_return

Case "HELP"

str_return = ctrlDLManager.Help

Case "INFO"

str_return = ctrlDLManager.Info


str_return = ctrlDLManager.Review(ctrlDLManager.DList)


str_return = ctrlDLManager.Subscribe(ctrlDLManager.UserID,ctrlDLManager.DList)


str_return = ctrlDLManager.Unsubscribe(ctrlDLManager.UserID,ctrlDLManager.DList)

End Select

oReplyMsg.Text = str_return



str_Log = str_Log & ", Reply sent!"


Set oRecipient = Nothing

Set oReplyMsg = Nothing

Set oFolderOutbox = Nothing

Set ctrlDLManager = Nothing

Set oCurrentMsg = Nothing

Set oSession = Nothing

Script.Response = str_Log

End Sub

Listing 6 – DLManager Subscribe subroutine

my $person = shift;

my $list = shift;

my $dlpath = "LDAP://server/cn=" . $list . ",cn=Container,ou=Site,o=Organization";

my $confirmation;

# lookup the dl...

my $DL = Win32::OLE->GetObject($dlpath);

return(&main::Error('REVIEW',$list)) if (! $DL);


# Used this because it exists, isn’t readily exposed, and is already indexed for easy queries!

my $status = $DL->Get('physicalDeliveryOfficeName');

if ($status ne 'Open') {

my $owner = $DL->Get('owner');

my $Owner = Win32::OLE->GetObject("LDAP://MERC51/$owner");

$DLManager::DListOwner = $Owner->Get('cn');



# lookup the person...

my ($upath,$uname) = &main::ADO($person,"OPEN");

if ($upath =~ m/NULL/) {

($upath,$uname) = &main::ADO($person,"HIDDEN");

if ($upath =~ m/NULL/) {

($upath,$uname) = &main::ADO($person,"TARGET");

if ($upath =~ m/NULL/) {

$confirmation = &main::Error($upath,$person);





if (! &main::Is_Member($upath,$DL)) {


$confirmation = &main::Confirm('SUBSCRIBE',$uname,$list);

} else {

$confirmation = &main::Error('SUBSCRIBE',$uname,$list);




Looking Ahead: Windows 2000/Active Directory/Exchange 2000

At the time of this writing, many exciting advancements are occurring in conjunction with SAS’ adoption and deployment of Windows 2000 and Exchange 2000. The first challenge is Active Directory. As an Exchange Administrator, I describe Active Directory as the Exchange 5.5 directory “taking over” and moving into the OS. There are (in my opinion) more similarities between Active Directory and Exchange 5.5 directory than Active Directory and the NT4 SAM database. Whereas, in Exchange 5.5 the NT Account was a property of the mailbox, now in AD the mailbox is a property of the NT Account. The consolidation of NT security groups and Exchange Distribution Lists provides tremendous opportunity. The exact same logic used for distribution lists can now be applied to security groups, freeing up administrator resources.
There are significant changes on the Information Store, as well. Most significant is the conversion of the database to what Microsoft calls the WebStore. Before, MAPI was the only way to access data in the store. Now the WebStore exposes the data in a much more accessible manner. The IFS (Installable File System) allows you to access your mailbox as if it were a file system (you can ‘cd’ into your mailbox!). From a programmers perspective, even more exciting is the fact that the Information Store is accessible via the WebDAV protocol. Every item in Exchange is URL addressable!
These changes are exciting, and the challenges will be many. Admittedly, many of the processes and programs mentioned here are currently in a state of flux. All of the code I’ve present is being updated to work directly with Active Directory. In addition, there will be new problems to solve. From my perspective, the question isn’t whether it can be done with Perl… it’s a question of what you want to do first! If you’d like to obtain the Perl code presented (and alluded to) here, send an e-mail to me (Rick.Tatem@sas.com) and I’ll be happy to provide it to you.


I’d like to express my gratitude for the hard work of Perl porters. I’ve used Perl on a wide variety of platforms (including a much-tinkered Atari 1040ST a few years back) and have always been amazed at the consistency of the ports. I’d also like to thank the folks at ActiveState. The Windows NT world generally has a different mindset than the UNIX world. The products and services provided by ActiveState are helping to broaden the impact of Perl where it’s needed most. Specifically, I’d like to thank:

Jan Dubois and Gurusamy Sarathy for their work on the Win32::OLE modules

Dave Roth for his work on the Win32:: AdminMisc (and many other useful) modules

Graham Barr and Mark Wilcox for their work on the Net::LDAP module

i Exchange Administrator, Vol. 3, No. 4, Duke Communications International, Inc.

База данных защищена авторским правом ©shkola.of.by 2016
звярнуцца да адміністрацыі

    Галоўная старонка