Are you a world traveler? ZoneTick is a cool utility that'll help you stay in touch over multiple time zones!
 
Using BatchExport Function  
Nik Okuntseff  MS Exchange Server Programming 

Using BatchExport Function

One of very interesting functions in DAPI is the BatchExport function. With it you can export properties of multiple directory objects into a file. It has a counterpart - BatchImport, to do the same operation in reverse. When I was just starting investigating MS Exchange directory - I thought about a way to export the whole directory into a file for examination. In fact, it is very useful to dump the contents of the whole tree (or a sub-tree) for closer look.
 

Batch Export of All Addr-Type Objects in Organization

The following sample (which you may find in the Dir/BatchExport subdirectory in my set of samples) demonstrates how to dump 4 specific attributes for all Addr-Type objects in organization.

#include <afxwin.h>
#include <dapi.h>

int main( void )
{
    BEXPORT_PARMS bep;
    ZeroMemory( &bep, sizeof( BEXPORT_PARMS ) );

    // Initialize BEXPORT_PARMS struct
    bep.dwDAPISignature = DAPI_SIGNATURE;
    bep.dwFlags = DAPI_EXPORT_ALL_CLASSES |
        DAPI_EXPORT_HIDDEN |
        DAPI_EXPORT_SUBTREE |
        DAPI_RAW_MODE;
 
    bep.pszExportFile = "D:\\temp\\Dump.txt";
    bep.pszBasePoint = ""; // Base point is current organization object

    // Specify which objects to export. This overrides DAPI_EXPORT_ALL_CLASSES
    // in dwFlags.
    LPTSTR classes[2];
    classes[0] = "Addr-Type";
    classes[1] = NULL; // This terminator is needed.
    bep.rgpszClasses = classes;
 

    // Specify attributes to export
    ATT_VALUE avAttrName[5];

    avAttrName[0].DapiType = DAPI_STRING8;
    avAttrName[0].Value.pszA = "Obj-Class";
    avAttrName[0].size = 9;
    avAttrName[0].pNextValue = NULL;
 
    avAttrName[1].DapiType = DAPI_STRING8;
    avAttrName[1].Value.pszA = "Directory Name";
    avAttrName[1].size = 14;
    avAttrName[1].pNextValue = NULL;

    avAttrName[2].DapiType = DAPI_STRING8;
    avAttrName[2].Value.pszA = "Proxy-Generator-DLL";
    avAttrName[2].size = 19;
    avAttrName[2].pNextValue = NULL;

    avAttrName[3].DapiType = DAPI_STRING8;
    avAttrName[3].Value.pszA = "File-Version";
    avAttrName[3].size = 12;
    avAttrName[3].pNextValue = NULL;

    // This terminates our attribute name array
    ZeroMemory( &avAttrName[4], sizeof(ATT_VALUE) );

    DAPI_ENTRY deAttributes;

    deAttributes.unAttributes = 4;
    deAttributes.ulEvalTag = TEXT_VALUE_ARRAY;
    deAttributes.rgEntryValues = &avAttrName[0];
 
    bep.pAttributes = &deAttributes;

    // Do batch export operation
    DWORD dwResult = BatchExport( &bep );
    return ( dwResult );
}

The file named "Dump.txt" may be found in Dir/BatchExport subdirectory with the result of this export operation on my Exchange server. In my particular case it contains 11 exported objects - 10 that came with default MS Exchange installation, and one custom one - EDK:i386, which appeared after installation of Microsoft's sample gateway.
 

Batch Export of the Whole Directory Tree in an Organization

If you'd like to export the contents of the whole tree, you may do it by using the following fragment (corresponding sample is called Dir/BatchExportAll):

#include <afxwin.h>
#include <dapi.h>

int main( void )
{
    BEXPORT_PARMS bep;
    ZeroMemory( &bep, sizeof( BEXPORT_PARMS ) );

    // Initialize BEXPORT_PARMS struct
    bep.dwDAPISignature = DAPI_SIGNATURE;
    bep.dwFlags = DAPI_EXPORT_ALL_CLASSES |
        DAPI_EXPORT_HIDDEN |
        DAPI_EXPORT_SUBTREE |
        DAPI_RAW_MODE;
 
    bep.pszExportFile = "D:\\temp\\Dump.txt";
    bep.pszBasePoint = ""; // Base point is current organization object

    // Specify attributes to export
    ATT_VALUE avAttrName[3];

    avAttrName[0].DapiType = DAPI_STRING8;
    avAttrName[0].Value.pszA = "Obj-Class";
    avAttrName[0].size = 9;
    avAttrName[0].pNextValue = NULL;
 
    avAttrName[1].DapiType = DAPI_STRING8;
    avAttrName[1].Value.pszA = "Obj-Dist-Name";
    avAttrName[1].size = 13;
    avAttrName[1].pNextValue = NULL;

    // This terminates our attribute name array
    ZeroMemory( &avAttrName[2], sizeof(ATT_VALUE) );

    DAPI_ENTRY deAttributes;

    deAttributes.unAttributes = 2;
    deAttributes.ulEvalTag = TEXT_VALUE_ARRAY;
    deAttributes.rgEntryValues = &avAttrName[0];
 
    bep.pAttributes = &deAttributes;

    // Do batch export operation
    DWORD dwResult = BatchExport( &bep );
    return ( dwResult );
}

This code exports only class names and distinguished names for all objects in the organization. Again, the result of the dump may be found together with source files. If you look into Dump.txt file in Dir/BatchExportAll sub-directory, you'll notice that most of its contents is occupied by Class-Schema and Attribute-Schema objects, and only a small fraction in the end - by real physical "instances" of them. This is because my test installation of MS Exchange is very small - it contains only a few mailboxes.

The fragment above is different from the first one because I don't specify class names here. In the first sample I have initialized rgpszClasses member of BEXPORT_PARMS, thus telling that I specifically request Addr-Type objects only. Also, the number of exported attributes is different - I have decided for the sake of simplicity only export distinguished names (and class names). If you want to export other attributes - you need to do extra work initializing its pAttributes member.
 

[ Contents | Home ]

Send comments and suggestions to niko@wrconsulting.com
Copyright © 1997-1998 by Nik Okuntseff