Fixing Public Folder Directory Objects That Aren’t Linked To The Hierarchy

In my recent post on the Exchange Team Blog, I briefly mentioned the dangers of forcibly removing an administrative group from ADSI Edit. The most common unintended consequence of this is a deletion of the directory object that represents the Public Folder Hierarchy.

Deleting this object creates quite a mess, because all of your mail-enabled public folders and all of your public folder stores point to it. Even if you create a new hierarchy object and manually link the stores to it by setting the msExchOwningPFTree value, you still have a ton of public folder directory objects in Microsoft Exchange System Objects with no homeMDB.

I had a customer today in this situation, and I wrote a quick Powershell script to fix all the directory objects for the mail-enabled public folders. Here it is.

If you find yourself in this situation, you’ll still need to create a new hierarchy object and link your public folder stores to it. This script does not fix that part of the problem, although it wouldn’t be hard to adapt it to link the stores as well.

To keep things simple, this only runs against one domain at a time. You’ll need to change the container to point to the Microsoft Exchange System Objects container in each different domain.

# Link-PFProxies.ps1
#
# Change these two values to match your environment.
# $container should point to the MESO container you want to run against.
# $pfTreeDN should contain the distinguishedName of the public folder hierarchy object.

$container = [ADSI]("LDAP://CN=Microsoft Exchange System Objects,DC=contoso,DC=com")
$pfTreeDN = "CN=Public Folders,CN=Folder Hierarchies,CN=Exchange Administrative Group (FYDIBOHF23SPDLT),CN=Administrative Groups,CN=First Organization,CN=Microsoft Exchange,CN=Services,CN=Configuration,DC=contoso,DC=com"

#################################################

$filter = "(!(homemdB=*))"
$propertyList = @("distinguishedName")
$scope = [System.DirectoryServices.SearchScope]::OneLevel

$finder = new-object System.DirectoryServices.DirectorySearcher($container, $filter, $propertyList, $scope)
$finder.PageSize = 100
$results = $finder.FindAll()

("Found " + $results.Count + " folder proxies with no homeMDB...")
foreach ($result in $results)
{
("Fixing object: " + $result.Path)
$entry = $result.GetDirectoryEntry()
$entry.Put("homeMDB", $pfTreeDN)
$entry.SetInfo()
}