HOW TO:Set folder level permissions using CDO 1.21 and ACL.dll

This is not something everyone would want to do, but just in case below is the sample code that uses ACL.dll (found in the Platform SDK) to set "Reviewer" permissions on all the folders for a specific user.

The following sample is a simple VBScript code sample that iterates through all folders in multiple mailboxes and sets the "Reviewer" permissions. To use this sample, paste the following code in a new text file, and then name the file SetFolderPermissions.vbs:

 'This script logs on to a server that is running Exchange Server and iterates through all the mailboxes
'recursively setting the "Reviewer" permission on each folder for a specific user.

' USAGE: cscript SetFolderPermissions.vbs SERVERNAME DATAFILE FullUserName
' This requires that CDO 1.21 and the Acl.dll is installed on the computer.

Dim obArgs
Dim cArgs
Dim objSession
Dim objInfoStores
Dim FullUserName

Set obArgs = WScript.Arguments
cArgs = obArgs.Count

Const CdoMsg = 3,ForReading = 1, ForWriting = 2, ForAppending = 8, TristateFalse = 0


Sub Main()
Dim FileSysObj
Dim DataFileName
Dim DataFile
Dim alias

    If cArgs <> 3 Then
        WScript.Echo "Usage: cscript SetFolderPermissions.vbs SERVERNAME DATAFILE(Name and Path) FullUserName"
        Exit Sub
    End If

    Set FileSysObj = CreateObject("Scripting.FileSystemObject")

    DataFileName = obArgs.Item(1)
    FullUserName = obArgs.Item(2)

    Set DataFile = FileSysObj.OpenTextFile(DataFileName, ForReading, False,0)
    'Read line by line
    Do While Not DataFile.AtEndOfStream
         alias = DataFile.ReadLine
    'Loop through the mailboxes
        Call IterateInfoStores(obArgs.Item(0), alias)

    'Clean Up    
    Set DataFile = Nothing
    Set FileSysObj = Nothing

End Sub

Sub IterateInfoStores(ServerName,UserName)

Dim objFolder
Dim intCounter
Dim objInfoStore
Dim sMsg

    On Error Resume Next
    'Create the new Session Object
    Set objSession = CreateObject("MAPI.Session")

    If Err.Number <> 0 Then
      sMsg = "Error creating MAPI.Session."
      sMsg = sMsg & "Make sure CDO 1.21 is installed. "
      sMsg = sMsg & Err.Number & " " & Err.Description
      WScript.Echo sMsg
      Exit Sub
    End If

    'Logon to the Mailbox
    objSession.Logon "", "", False, True, 0, False, ServerName & vbLf & UserName
    If Err.Number <> 0 Then
      sMsg = "Error logging on: "
      sMsg = sMsg & Err.Number & " " & Err.Description
      WScript.Echo sMsg
      WScript.Echo "Server: " & ServerName
      WScript.Echo "Mailbox: " & UserName
      Set objSession = Nothing
      Exit Sub
    End If

    WScript.Echo "Logged On to:" & objSession.CurrentUser

    'Loop through the Infostores
    For intCounter = 1 To objSession.InfoStores.Count
        Set objInfoStore = objSession.InfoStores(intCounter)

    If Err.Number <> 0 Then
          sMsg = "Error retrieving InfoStore Object: "
          sMsg = sMsg & Err.Number & " " & Err.Description
          WScript.Echo sMsg
          WScript.Echo "Server: " & ServerName
          WScript.Echo "Mailbox: " & UserName
          Set objInfoStore = Nothing
          Set objSession = Nothing
          Exit Sub
    End If
        If objInfoStore.Name = "Mailbox - " & objSession.CurrentUser Then
            Exit For
        End If
    Set objFolder = objInfoStore.RootFolder
    If Err.Number <> 0 Then
    sMsg = "Error retrieving RootFolder Object: "
    sMsg = sMsg & Err.Number & " " & Err.Description
    WScript.Echo sMsg
    WScript.Echo "Server: " & ServerName
    WScript.Echo "Mailbox: " & UserName
    Set objInfoStore = Nothing
    Set objFolder = Nothing
    Set objSession = Nothing
    Exit Sub
    End If

    'Recurse through the sub-folders
    NavigateFolders objFolder

    If Err.Number <> 0 Then
    sMsg = "Error: "
    sMsg = sMsg & Err.Number & " " & Err.Description
    WScript.Echo sMsg
    WScript.Echo "Server: " & ServerName
    WScript.Echo "Mailbox: " & UserName
    End If
    'Logoff from the session

    'Clean Up
    Set objFolder = Nothing
    Set objInfoStore = Nothing
    Set objSession = Nothing
End Sub

Sub NavigateFolders(MAPIFolder)
Dim intCounter
Dim oDelegate
Dim oAddrBook
Dim oNewAce
Dim ACLObj
Dim FolderACEs
Dim objAce

Const ROLE_OWNER = &H5E3 
Const ROLE_EDITOR = &H463 
Const ROLE_AUTHOR = &H41B 
Const ROLE_NONE = &H400 

    WScript.Echo "Folder Name:" & MAPIFolder.Name

    'Create the ACL object
    Set ACLObj = CreateObject("MSExchange.aclobject")
    ' Associate the ACLObject to the CDO Folder
    ACLObj.CDOItem = MAPIFolder
    Set FolderACEs = ACLObj.ACEs

    ' Create a MAPI object for UserA
    Set oAddrBook = objSession.AddressLists("Global Address List")

    Set oDelegate = oAddrBook.AddressEntries.Item(FullUserName)

    Set oNewAce = CreateObject("MSExchange.ACE")

    oNewAce.ID = oDelegate.ID
    oNewAce.Rights = ROLE_REVIEWER
    FolderACEs.Add oNewAce

    ' Loop through all of the ACEs for the folder and display them
    For each objAce in  FolderACEs
    WScript.Echo GetACLEntryName(objAce.ID) & " - " & DispACERules(objAce)
    WScript.Echo ""

    ' Clean up objects
    Set objAce = Nothing
    Set oNewAce = Nothing
    Set FolderACEs = Nothing
    Set ACLObj = Nothing

    If MAPIFolder.Folders.Count > 0 Then
        For intCounter = 1 To MAPIFolder.Folders.Count
            NavigateFolders MAPIFolder.Folders(intCounter)
    End If

End Sub

Function GetACLEntryName(ACLEntryID)
On Error resume Next
' This function finds the user that is listed as an ACE on the folder.
' It takes the ID that it is passed and uses the Session.GetAddressEntry method
' to find the name.
    Dim tmpEntry
    Dim tmpName

    Select Case ACLEntryID
            GetACLEntryName = "Default"
            GetACLEntryName = "Anonymous"
    Case else
       ' Get the name of the ACE
        Set tmpEntry = objSession.GetAddressEntry(ACLEntryID)
            tmpName = tmpEntry.Name
            GetACLEntryName = tmpName
    End Select
End Function

Function DispACERules(DisptmpACE)
' This function checks the roles of the ACE that is passed to it and    returns
' the Role back.
Const ROLE_NONE = 1024
Const ROLE_AUTHOR = 1051
Const ROLE_REVIEWER = 1025
Const ROLE_EDITOR = 1147
Const ROLE_OWNER = 2043

    ' Check the roles on the folder
    Select Case DisptmpACE.Rights
        Case ROLE_NONE, 0  ' Checking in case the role has not been set on that entry.
                DispACERules = "None"
        Case ROLE_AUTHOR
                DispACERules = "Author"
                DispACERules = "Contributor"
        Case ROLE_EDITOR
                DispACERules = "Editor"
                DispACERules = "Nonediting Author"
        Case ROLE_OWNER
                DispACERules = "Owner"
                DispACERules = "Publishing Author"
                DispACERules = "Publishing Editor"
        Case ROLE_REVIEWER
                DispACERules = "Reviewer"
        Case Else
        ' This will grab all other custom permissions on the folder
                DispACERules = "Custom"
    End Select

End Function

The list of mailboxes can be provided via a text file(Datafile). The Datafile contains the aliases of the users(one on each line). So assuming your Datafile is called "Aliases.txt" and is on the C:\, you would run the script as follows:

C:\>Cscript SetFolderPermissions.vbs Exchange2003 C:\Aliases.txt "Akash Bhargava"

The script currently sets and also dumps out the permissions on each folder in the mailbox.

The account that you are logged on the computer with must have permissions on the mailboxes that you are trying to iterate through. You can give the permissions by following the steps in the article below:

How to assign service account access to all mailboxes in Exchange Server 2003