How to Check Replicas?
Public Folder replicas are almost a thing of the past. Once support for Exchange 2010 is gone and companies finally move off, we never have to worry about Public Folder Replication again. This is because Exchange 2013 introduced Modern Public Folders where HA or ‘replica’ copying was provided by Database Availability Groups. Thus a Pubic Folder, stored in a mailbox, which was store in a mailbox database that had multiple copies was now protected by the DAG replication. For this exercise, we don’t have that to look to and must examine what replicas were configured manually for each Public Folder in the environment. Here are some quick one-liners to see these replicas:
The wrong way:
get-publicfolder | ft name,parentpath,replicas
The right way:
get-publicfolder '\' -Recurse | ft name,parentpath,replicas
Once we have a list of replicas, we should be able to tell if all servers have a copy of all of the folders. Now, it is possible that not all copies have replicas and that may be by design, however. Yet, it may reveal copies that are missing, that were not be design and now can be fixed. This is also useful for revealing replicas for when they are synced to the cloud, that we have a good source to sync from and are not missing any folders.
Disk Space Analysis
Now, the real trick is checking the size of each folder and some of the way the script was written draws out the flaws of Public Folders, replicas and Exchange 2010’s aging architecture. We focus on the cmdlet ‘Get-PublicFolderStatistics’. With a bit of testing and lab time, I’ve come up with code that looks like this for getting the size of an individual folder:
Get-PublicFolderStatistics $PublicFolder -Server $PFServer | Select Name,ItemCount,TotalItemSize,FolderPath | % {$size = [string]$_.TotalItemSize;$StepOne = $Size.Split('(');$StepTwo = $StepOne[1].Split(')');$Bytes = $StepTwo[0].Split(' ') -replace ‘[,]’,'';$Bytes2 = [int64]$Bytes[0];$MegaBytes = $Bytes2/1024/1024;$MbxSize = [Math]::Round($MegaBytes,2);$_.TotalItemSize = $MbxSize;return $_}
Now, admittedly, this is a bit of a mess, however, there is a purpose to this mess. The ‘TotalItemSize’ value is converted from the standard output to a value that is purely in Mb. Doing so eliminates any words in the value like these examples:
Now, we can also use this method to get the same values:
Get-PublicFolderStatistics $PublicFolder -Server $PFServer | select-object Name,ItemCount,@{expression={$_.TotalItemSize.Value.ToMB()};label="PublicFolder Size(MB)"},FolderPath | ft -auto
However, this has produced mixed results in some environments, so I went with a calculated value, versus this method above. Also, using the above ToMB call does not work on objects in Exchange Online which is something to keep in mind.
Now, the other issue that can occur, is that when a Public Folder does not have a copy on the same server where the PowerShell we receive an error like so:
This can occur when there are just one or multiple replicas, but the commonality is that there is no copy on the server where the query is made. We need to add the ‘-Server $PFServer’ parameter for PowerShell to query the Exchange 2010 with a copy of the Public Folder.
Script
The code to get all Public Folder statistics, on all servers and exported to a file, could look something like this:
#Variables $Path = (Get-Item -Path ".\" -Verbose).FullName $PublicFolderStatFile = "PublicFolder-Statistics.csv" $PublicFolderStatDestination = $Path+"\"+$PublicFolderStatFile $PublicFolderOutputStat = @() # Counter for Public Folder Progress Bar: $Counter = 1 $TotalCount = $PublicFolders.Count # Header for Public Folder File: $Line = 'Name|ItemCount|TotalItemSize|ParentPath' | Out-File $PublicFolderStatDestination # Public Folder Query: $PublicFolders = Get-PublicFolder "\" -Recurse -ResultSize Unlimited Foreach ($PublicFolderFull in $PublicFolders){ # Progress Bar $Percent = ($Counter/$TotalCount)*100 $PercentComplete = [math]::Round($Percent,3) Write-Progress -Activity "Public Folder Statistics" -Status "Public Folder - $Counter of $TotalCount - Percent Complete $PercentComplete %" # Pull Public Folder Identity $PublicFolder = $PublicFolderFull.identity # Get Public Folder Server to prevent errors: $PFDatabase = ((Get-Publicfolder $PublicFolder).Replicas[0]).name $PFServer = ((Get-PublicFolderDatabase $PFDatabase).Server).Name # Get Public Folder Stats $Line = Get-PublicFolderStatistics $PublicFolder -Server $PFServer | Select Name,ItemCount,TotalItemSize,FolderPath | % {$size = [string]$_.TotalItemSize;$StepOne = $Size.Split('(');$StepTwo = $StepOne[1].Split(')');$Bytes = $StepTwo[0].Split(' ') -replace ‘[,]’,'';$Bytes2 = [int64]$Bytes[0];$MegaBytes = $Bytes2/1024/1024;$MbxSize = [Math]::Round($MegaBytes,2);$_.TotalItemSize = $MbxSize;return $_} # Output variables: $Name = $Line.Name $ItemCount = $Line.ItemCount $TotalItemSize = $Line.TotalItemSize $FolderPath = $Line.FolderPath # Output to file, with '|' for a delimiter: $Line = "$Name|$ItemCount|$TotalItemSize|$FolderPath" | Out-File $PublicFolderStatDestination -Append $Counter++ }
Sample Output File
Notice the ‘| delimiter in the file below, this makes it easier to ensure that the delimiter is a unique character which ensures our column integrity when opened with Excel:
Summary
In the end, this is just another final exercise when it comes to Exchange 2010 Public Folders. With support dropping off in late 2020, let’s hope that this will be one last send off for this version of Public Folders….