Exchange 2010 Auto-mapping mailboxes feature doesn't work when groups grant permissions

Solution 1:

I created this script when we ran into the same issue. Maybe it's not the prettiest thing in the world, but it gets the job done. I have a separate OU for the access groups and then another for the resources mailboxes. The groups and resource mailboxes use the same name except for an A- in front for the group.

e.g. A-RESMBX1 for the group name and REXMBX1 for the resource mailbox.

The script enumerates the groups in the groups OU and then the resource mailboxes in that OU. It then cycles through each group and finds the matching resource mailbox. When a match is found it enumerates the groups' users and then adds them to the msExchDelegateListLink attribute of the Resource Mailbox.

It will also remove users from the msExchDelegateListLink attribute that are no longer members of the associated access group. I have this running in a Scheduled Task on a DC.

Our need was due to high turnover of interns that needed to have access to a large number of resource mailboxes.

You'd need to update the LDAP paths to the OUs for $Groups & $ResMBXs as well as your DC name for $DomainController

Import-Module ActiveDirectory
$DomainController = "MYDOMAINCONTROLLER"
$Groups = Get-ADGroup -Filter * -SearchBase 'OU=Groups,OU=Resource Mailboxes,DC=mydomain,DC=com' -Server $DomainController | Sort-Object Name
$ResMBXs = Get-ADUser -Filter * -SearchBase 'OU=Resource Mailboxes,DC=mydomain,DC=com' -Server $DomainController -properties msExchDelegateListLink  | Sort-Object Name

Write-Host "Enumerating Groups and Resource Mailboxes..."
Write-Host ""

# IsMember function is borrowed from : http://gallery.technet.microsoft.com/scriptcenter/5adf9ad0-1abf-4557-85cd-657da1cc7df4
# Hash table of security principals and their security group memberships. 
$GroupList = @{}    

Function IsMember ($ADObject, $GroupName) 
{ 
    # Function to check if $ADObject is a member of security group $GroupName. 

    # Check if security group memberships for this principal have been determined. 
    If ($GroupList.ContainsKey($ADObject.sAMAccountName.ToString() + "\") -eq $False) 
    { 
        # Memberships need to be determined for this principal. Add "pre-Windows 2000" 
        # name to the hash table. 
        $GroupList.Add($ADObject.sAMAccountName.ToString() + "\", $True) 
        # Retrieve tokenGroups attribute of principal, which is operational. 
        $ADObject.psbase.RefreshCache("tokenGroups") 
        $SIDs = $ADObject.psbase.Properties.Item("tokenGroups") 
        # Populate hash table with security group memberships. 
        ForEach ($Value In $SIDs) 
        { 
            $SID = New-Object System.Security.Principal.SecurityIdentifier $Value, 0 
            # Translate into "pre-Windows 2000" name. 
            $Group = $SID.Translate([System.Security.Principal.NTAccount]) 
            $GroupList.Add($ADObject.sAMAccountName.ToString() + "\" + $Group.Value.Split("\")[1], $True) 
        } 
    } 
    # Check if $ADObject is a member of $GroupName. 
    If ($GroupList.ContainsKey($ADObject.sAMAccountName.ToString() + "\" + $GroupName)) 
    { 
        Return $True 
    } 
    Else 
    { 
        Return $False 
    } 
} 

Foreach ($gr in $Groups) {

         Foreach ($mbx in $ResMBXs) {
             $MBXName = "A-" + $mbx.Name
             $LDAPUser=[ADSI]"LDAP://$($DomainController)/$($mbx.distinguishedName)"

             if ($gr.Name -eq $MBXName) 
             {
              #Build an Array of DNs from each Group
              $Members = Get-ADGroupMember $gr -Server $DomainController
              if ($Members -ne $Null)
              {
                  Foreach ($mbr in $Members){


                     if($mbr.distinguishedName -ne $Null)
                     {
                        $LDAPUser.msExchDelegateListLink.Add($mbr.distinguishedName)
                        $LDAPUser.SetInfo()
                     }
                    $AddedUsers += $mbr.Name
                  }
              }
              Else {Write-Host -foregroundcolor darkyellow "Group contains no members..."; Write-Host ""}

              if($mbx.msExchDelegateListLink -ne $Null) {
                  $ACLUsers = $mbx.msExchDelegateListLink
                  Foreach ($ACLUser in $ACLUsers)
                  {
                    #Check if user is a member of the current group
                    #If not, remove from attribute
                    $user = [ADSI]"LDAP://$($DomainController)/$($ACLUser)"
                    $userDN = Get-ADUser $ACLUser -Server $DomainController
                    $mem = IsMember $user $gr.Name
                    If ($mem -eq $False)
                        {
                            $LDAPUser.msExchDelegateListLink.Remove($userDN.distinguishedName)
                            $LDAPUser.SetInfo()
                            Write-Host "The Following User was removed from: " -nonewline; Write-Host -foregroundcolor yellow $mbx.Name
                            Write-Host -nonewline -foregroundcolor darkyellow " " $UserDN.Name
                            Write-Host ""
                        }
                  }
                 }
              $Members = ""
              Write-Host "The Following Users were added to: " -nonewline; Write-Host -foregroundcolor yellow $mbx.Name
              Write-Host ""
              Write-Host -foregroundcolor darkyellow $AddedUsers
              Write-Host ""
              $AddedUsers = ""
             }
         }

      }