This is the third and final version of my script to compare Item and Byte counts for Public Folders that are replicated between Exchange 2000 and Exchange 2007 servers. Since we will be taking our Exchange 2000 server offline soon, my ability to develop / test / support this script has ended.
Enhancements:
- Require declaration of Powershell variables (kind of like Option Explicit for VBS)
- Fixed some inconsistencies in logging
- Updated output XML file name to include a timestamp
- Added additional documentation within the code
If you've used this code in your environment to monitor Public Folder replication or even dissected the code to learn how to do something new, please post a comment below. I feel really good when I know that someone has benefitted from my work.
#--------------------==--------------------#
set-psdebug –strict # Require declaration of powershell variables
# Set-PSDebug -Off # Do not require declaration of variables
#------------ Exchange Servers ------------#
#
# Populate $NewServer and $OldServer with your
# Exchange 2007 and Exchange 2000 server names.
# Don't use <server name>.<domain>.com notation.
$NewServer = "<Exchange 2007 server name>";
$OldServer = "<Exchange 2000 server name>";
#---------- Public Folder Access ----------#
#
# Please use a fresh account for this script. It does not need
# any administrative rights but I did make it a member of the new
# Exchange Public Folder Administrators security group. I
# suggest a fresh account because access permissions to Public
# Folders will be added AND removed for this account. You don't
# want to screw up a legitimate production account, do you? This
# account will also need a mailbox.
$ConnectAs = "<domain>\<userID>";
$Password = "<password>";
#-------- Security Permission Mode --------#
#
# This section needs a little explanation before you're ready to use it. It it very likely that $ConnectAs will be unable
# to view every Public Folder hosted on $OldServer. At first this script would check permissions, add 'FolderVisible' if
# necessary, wait for the permissions to replicate to $OldServer, then compare Public Folder size and item count between
# $OldServer and $NewServer. This was it was taking upwards of 20 minutes for the security permission update to replicate
# to $OldServer each and every time an Access Denied error was encountered. This is why I broke out the functionality into
# four modes. Each mode has a description after it. I recommend that you run this script under $Security_Permission_Mode_Add
# by setting $Current_SPM = $Security_Permission_Mode_Add; wait a couple hours or a day for Public Folder Replication to
# work its magic; re-run this script using $Security_Permission_Mode_Add_Only_As_Necessary; then when you have all your results,
# run it once more using $Security_Permission_Mode_Remove to clean up the security changes.
$Security_Permission_Mode_Add = 1; # Don't perform any mailbox compares. Just add 'FolderVisible' permissions for $ConnectAs where necessary.
$Security_Permission_Mode_Remove = 2; # Don't perform any mailbox compares. Just remove any 'FolderVisible' permissions for $ConnectAs.
$Security_Permission_Mode_No_Changes = 3; # Compare Public Folders using the security permissions available at the time of the run.
$Security_Permission_Mode_Add_Only_As_Necessary = 4; # Add 'FolderVisible' permissions for $ConnectAs where necessary,
# wait for Public Folder Replication, then compare folders.
$Security_Permission_Mode_Add_Remove_As_Necessary = 5; # Add 'FolderVisible' permissions for $ConnectAs where necessary,
# wait for Public Folder Replication, compare folders, then remove added permissions.
$Current_SPM = $Security_Permission_Mode_Add_Only_As_Necessary;
$TimeConstant = [int32]1800; # How many seconds to wait for security permissions to replicate from $OldServer to $NewServer per folder.
# This value is neede only during $Security_Permission_Mode_Add_Only_As_Necessary
#-------------- Quit On Error -------------#
#
# If an error is encountered while attempting to
# access the Public Folders via the web site hosted by
# $OldServer, the script will halt or not based on the config below.
# This flag is active during modes $Security_Permission_Mode_No_Changes,
# $Security_Permission_Mode_Add_Only_As_Necessary, and
# $Security_Permission_Mode_Add_Remove_As_Necessary.
$Quit_On_Error = $True;
function Check_Security([string]$PublicFolderHTTPFormat, [string]$UserID, [string]$Pass)
{
$strRequest = "<?xml version=""1.0"" ?><D:propfind xmlns:D=""DAV:"" xmlns:E=""http://schemas.microsoft.com/mapi/proptag/""><D:prop><E:x0e080014 /><E:x36020003 /></D:prop></D:propfind>";
$xmlHTTP = new-object -com msxml2.xmlhttp;
#Write-Host `t Accessing: $PublicFolderHTTPFormat;
#Write-Host `t UserID: $UserID;
#Write-Host `t Password: $Pass;
if ($PublicFolderHTTPFormat.EndsWith(".")) {
$tempString = $PublicFolderHTTPFormat + "%20";
}
else {
$tempString = $PublicFolderHTTPFormat
}
$xmlHTTP.Open("PROPFIND", $tempString, $False, $UserID, $Pass);
$xmlHTTP.setRequestHeader("Content-type:", "text/xml");
$xmlHTTP.setRequestHeader("Depth","0");
$xmlHTTP.send($strRequest);
#Write-Host `t xmlHTTP.Status: $xmlHTTP.Status;
return $xmlHTTP.Status;
}
[xml] $xmlLog = '<?xml version="1.0" encoding="ISO-8859-1"?> <Public_Folders><x /></Public_Folders>';
# Generate Run Details
$xmlRunDetails = $xmlLog.CreateElement("Run_Details");
$xmlStart = $xmlLog.createelement("Start");
$xmlFinish = $xmlLog.createelement("Finish");
$xmlTimeStamp = $xmlLog.CreateElement("TimeStamp");
($xmlTimeStamp.AppendChild(($($xmlLog.CreateElement("Year"))))).psBase.InnerText = Get-Date -UFormat %Y;
($xmlTimeStamp.AppendChild(($($xmlLog.CreateElement("Month"))))).psBase.InnerText = Get-Date -Format %M;
($xmlTimeStamp.AppendChild(($($xmlLog.CreateElement("Day"))))).psBase.InnerText = Get-Date -Format %d;
($xmlTimeStamp.AppendChild(($($xmlLog.CreateElement("Time"))))).psBase.InnerText = Get-Date -UFormat %T;
$xmlParameters = $xmlLog.CreateElement("Parameters");
($xmlParameters.AppendChild(($($xmlLog.CreateElement("Connect_As_Identiy"))))).psBase.InnerText = $ConnectAs;
($xmlParameters.AppendChild(($($xmlLog.CreateElement("New_Server"))))).psBase.InnerText = $NewServer;
($xmlParameters.AppendChild(($($xmlLog.CreateElement("Old_Server"))))).psBase.InnerText = $OldServer;
switch ($Current_SPM)
{
$Security_Permission_Mode_Add {($xmlParameters.AppendChild(($($xmlLog.CreateElement("Security_Permission_Mode"))))).psBase.InnerText = "Add";}
$Security_Permission_Mode_Remove {($xmlParameters.AppendChild(($($xmlLog.CreateElement("Security_Permission_Mode"))))).psBase.InnerText = "Remove";}
$Security_Permission_Mode_No_Changes {($xmlParameters.AppendChild(($($xmlLog.CreateElement("Security_Permission_Mode"))))).psBase.InnerText = "No Changes";}
$Security_Permission_Mode_Add_Only_As_Necessary {($xmlParameters.AppendChild(($($xmlLog.CreateElement("Security_Permission_Mode"))))).psBase.InnerText = "Add Only As Necessary";}
$Security_Permission_Mode_Add_Remove_As_Necessary {($xmlParameters.AppendChild(($($xmlLog.CreateElement("Security_Permission_Mode"))))).psBase.InnerText = "Add Remove As Necessary";}
}
$Catch_Output = $xmlStart.AppendChild($xmlTimeStamp);
$Catch_Output = $xmlRunDetails.AppendChild($xmlStart);
$Catch_Output = $xmlRunDetails.AppendChild($xmlFinish);
$Catch_Output = $xmlRunDetails.AppendChild($xmlParameters);
$Catch_Output = $xmlLog.Public_Folders.AppendChild($xmlRunDetails);
$intCounter = 0;
Get-PublicFolder -recurse |
foreach {
if ($_.ParentPath -ne $null)
{
if ([int]$($_.ParentPath.get_length()) -gt 1)
{
$PublicFolderPath = $_.ParentPath + "\" + $_.name
}
else
{
$PublicFolderPath = "\" + $_.name
}
}
else
{
$PublicFolderPath = "\" + $_.name
}
# NOTE: Microsoft allows the character "/" to be used in Public Folder Names.
# Try to reference a Public Folder named "Pizza/Toppings" via HTTP. You can't. The web server
# will come back with a HTTP 409 error. So we have to do a replace with "_xF8FF_".
$PublicFolderWebPath = "HTTP://" + $OldServer + "/public" + $PublicFolderPath.replace("/","_xF8FF_").replace("\","/");
$PublicFolderWebPathProper = $PublicFolderWebPath.replace(" ","%20");
$ReplicaSet = $_.Replicas;
$intCounter += 1;
$xmlFolder = $xmlLog.CreateElement("Public_Folder");
$xmlFolder.SetAttribute("ID",[string]$intCounter);
($xmlFolder.AppendChild(($($xmlLog.CreateElement("Name"))))).psBase.InnerText = $_.name;
($xmlFolder.AppendChild(($($xmlLog.CreateElement("Path"))))).psBase.InnerText = $PublicFolderPath;
($xmlFolder.AppendChild(($($xmlLog.CreateElement("Friendly_Web_Address"))))).psBase.InnerText = $PublicFolderWebPath;
($xmlFolder.AppendChild(($($xmlLog.CreateElement("Proper_Web_Address"))))).psBase.InnerText = $PublicFolderWebPathProper;
Write-Host $_.name;
$Error_Flag = $False;
forEach ( $Replica in $ReplicaSet ) {
if ( ($([string]$Replica).ToLower().Contains($OldServer.ToLower()) -eq $true))
{
# The code that deals with XML came from this location:
# [link=http://www.infinitec.de/post/2004/12/Retrieve-the-size-of-a-Microsoft-Exchange-20002003-public-folder.aspx]http://www.infinitec.de/post/2004/12/Retrieve-the-size-of-a-Microsoft-Exchange-20002003-public-folder.aspx[/link]
# It was written by Henning Krause. Many thanks for the excelent code.
# Visit Henning's Blog at [link=http://www.infinitec.de/author/hkrause.aspx]http://www.infinitec.de/author/hkrause.aspx[/link]
# I translated it into PowerShell
# A list of additional (and sometimes available) MAPI properties are available at:
# [link=http://svn.opengroupware.org/OGoProjects/evolution-groupdav/trunk/utils/mapi-properties]http://svn.opengroupware.org/OGoProjects/evolution-groupdav/trunk/utils/mapi-properties[/link]
$strRequest = "<?xml version=""1.0"" ?><D:propfind xmlns:D=""DAV:"" xmlns:E=""http://schemas.microsoft.com/mapi/proptag/""><D:prop><E:x0e080014 /><E:x36020003 /></D:prop></D:propfind>";
$xmlHTTP = new-object -com msxml2.xmlhttp;
$xmlDOC = new-object -com msxml2.DOMDocument;
$return = $xmlDOC.loadXML($strRequest);
Write-Host Inspecting: $PublicFolderWebPath;
$xmlReplica = $xmlLog.CreateElement("Replica");
($xmlReplica.AppendChild(($($xmlLog.CreateElement("Server_Name"))))).psBase.InnerText = $OldServer;
($xmlReplica.AppendChild(($($xmlLog.CreateElement("Web_Address_Header"))))).psBase.InnerText = 'http://' + $OldServer;
# I was getting a lot of HTTP 401 Access Denied errors while attempting to access
# some public folders. In the end, I discovered that this is because the account
# I'm using to troll through the Public Folders does not have 'FolderVisible'
# rights for that particular Public Folder after ALL the folder permissions have
# been compiled and compared against the user $ConnectAs.
# So I got the bright idea to check for a denied condition ("401" error) and
# grant 'FolderVisible' access rights using the "Add-PublicFolderClientPermission"
# cmdlet that you'll see a couple lines below. Initially I didn't use the "-Server"
# parameter. This caused some heartache. The security changes were being made on
# $NewServer and would eventually take effect on $OldServer through the Public
# Folder replication. This was not fast enough. I tried to grant rights on
# $OldServer manually using the Exchange System Manager (remember: $OldServer is
# running Exchange 2000) and after a few seconds, I got this email in my inbox:
# 'A folder design conflict has occurred in "Public Folder Store (<$OldServer>)".
# The design of this folder has been simultaneously modified on two or more
# folder replicas. Only the set of changes made last have been saved.'
# Having read this, I decided to attempt to use the "-Server $OldServer" parameter
# of the cmdlet "Add-PublicFolderClientPermission".
# This failed miserably since $OldServer is running Exchange 2000. My only option
# left was to grant permissions on $NewServer then wait for the predefined replication
# period before continuing. Through repeated testing, I found that I had to keep
# keep extending the wait time stored in $Time for the security replication to take place.
# Test to see if $ConnectAs can access $PublicFolderPath.
# If not, add an Access Control Entry (ACE) into the Access Control Llist (ACL)
# for $PublicFolderPath.
$Time = $TimeConstant;
$TimeCounter = $Time;
If (( $(Check_Security $PublicFolderWebPathProper $ConnectAs $Password) -eq 401 ) -and `
(($Current_SPM -eq $Security_Permission_Mode_Add) -or `
($Current_SPM -eq $Security_Permission_Mode_Add_Only_As_Necessary) -or `
($Current_SPM -eq $Security_Permission_Mode_Add_Remove_As_Necessary)) ) {
Write-Host `t Adding FolderVisible Access Permissions to $NewServer;
($xmlFolder.AppendChild(($($xmlLog.CreateElement("Security_Action"))))).psBase.InnerText = `
"Adding FolderVisible Access Permissions to " + $NewServer + " for " + $ConnectAs;
$return = Add-PublicFolderClientPermission -Identity $PublicFolderPath -User $ConnectAs -AccessRights "FolderVisible" -Confirm:$False;
If (($Current_SPM -eq $Security_Permission_Mode_Add) -or `
($Current_SPM -eq $Security_Permission_Mode_Add_Only_As_Necessary)) {
$strActivity = 'Waiting up to ' + $Time.tostring() + ' Seconds for Public Folder replication to push permissions to ' + $OldServer;
$Show = $True;
While (($Time -gt 0) -and ($(Check_Security $PublicFolderWebPathProper $ConnectAs $Password) -eq 401)){
Write-Progress -Activity $strActivity -Status "Polling in 10 Second Intervals" -SecondsRemaining $TimeCounter -Completed $Show;
Start-Sleep -Seconds 10;
$TimeCounter = $TimeCounter - 10;
if ($Show -eq $True) {$Show = $False} else {$Show = $True}
}
Write-Progress -Activity $strActivity -Status "Polling in 10 Second Intervals" -SecondsRemaining $Time; #-PercentComplete (0) -Completed:$True;
Write-Progress -Activity $strActivity -Status "Polling in 10 Second Intervals" -Completed:$True;
}
}
# We've passed through the section of code that makes security changes on the fly (if necessary).
# Hopefully by this point everything is in order to allow a successful read attempt when we access
# the HTTP directory that represents the Public Folder located on $OldServer.
if ( ($Current_SPM -eq $Security_Permission_Mode_Add_Remove_As_Necessary) -or `
($Current_SPM -eq $Security_Permission_Mode_Add_Only_As_Necessary) -or `
($Current_SPM -eq $Security_Permission_Mode_No_Changes) ) {
# Some of the folders in my organization ended with a period (".") and a space.
# I tried removing just the space but that frequently didn't work; the space would come back.
# If I removed both the space and the period, the change stuck. So when I encounter
# a public folder that ends with a period, I append a space to the end of the URL.
# Then IIS can access the URL. This is explained again in greater detail several
# lines below. Search for "404_Error" and look for the big blob of text above it.
if ($PublicFolderWebPathProper.EndsWith(".")) {
$tempString = $PublicFolderWebPathProper + "%20";
}
else {
$tempString = $PublicFolderWebPathProper
}
$xmlHTTP.Open("PROPFIND", $tempString, $False, $ConnectAs, $Password);
$xmlHTTP.setRequestHeader("Content-type:", "text/xml");
$xmlHTTP.setRequestHeader("Depth","0");
$xmlHTTP.send($strRequest);
$xmlDOC = $xmlHTTP.ResponseXML;
if ( $xmlHTTP.Status -eq 207 ) {
$xmlDOC.SetProperty("SelectionNamespaces", "xmlns:ex='http://schemas.microsoft.com/mapi/proptag/'");
# To see the properties & methods for a single XML Node (Msxml2.DOMDocument), uncomment this next line
# forEach ( $property in $($xmlDOC.selectSingleNode("//ex:x36020003") | get-member)) { Write-Host $property }
Write-Host `t Items: $xmlDOC.selectSingleNode("//ex:x36020003").text vs `
$(Get-PublicFolderStatistics -identity $PublicFolderPath).ItemCount.ToString();
Write-Host `t Bytes: $xmlDOC.selectSingleNode("//ex:x0e080014").text vs `
$(Get-PublicFolderStatistics -identity $PublicFolderPath).TotalItemSize.ToString().Replace("B","");
($xmlReplica.AppendChild(($($xmlLog.CreateElement("Item_Count"))))).psBase.InnerText = $xmlDOC.selectSingleNode("//ex:x36020003").text;
($xmlReplica.AppendChild(($($xmlLog.CreateElement("Byte_Count"))))).psBase.InnerText = $xmlDOC.selectSingleNode("//ex:x0e080014").text;
}
else {
Write-Host `t Failed: $xmlHTTP.Status `n`t Actual HTTP path attempted: $PublicFolderWebPathProper
if ($TimeCounter -eq 0) {
Write-Host '`tTime expired while waiting for security permissions to replicate to $oldServer';
($xmlReplica.AppendChild(($($xmlLog.CreateElement("Time_Error"))))).psBase.InnerText = `
'Time expired while waiting for security permissions to replicate to $oldServer';
}
if ($xmlHTTP.Status.ToString() -eq "404") {
$string = "`t A 'Not Found' error was encountered. Please check the public folder `
`n`t " + $PublicFolderPath + "`n and make sure there are no trailing spaces. `
`n`t The easiest way to do this is to open Exchange System Manager `
`n`t on the Exchange 2000 server an navigate to 'Administrative `
`n`t Groups' -> 'First Administrative Group' -> 'Folders' -> `
`n`t 'Public Folders' -> " + $PublicFolderPath + `
"`n`n`t Before you continue running this script, I recommend that `
`n`t you visit [link=http://visualbasicscript.com/m_61934/tm.htm]http://visualbasicscript.com/m_61934/tm.htm[/link] and run `
`n`t this script to discover which Public Folders have trailing spaces. `
`n`n`t If the above does not work, try this method:`
`n`t Using PFDavAdmin.exe, grant yourself 'Owner' Rights to the Public Folder `
`n`t then go to that folder within Outlook. Change the Name of the troublesome `
`n`t folder. Verify the name change in both Exchange 2000's Exchange System `
`n`t Manager and Exchange 2007 SP1's Public Folder Management Console. When `
`n`t both GUI's show the new name, then rerun this script. `
`n`t NOTE: I encountered one particular folder that had a period and a space `
`n`t at the end of its name ('. '). Outlook displayed the period but not the `
`n`t trailing space. Removing the period also removed the space in Exchange `
`n`t 2000's Exchange System Manager. Using Outlook to add the period back `
`n`t to the end of the Public Folder name also added the trailing space `
`n`t automatically. In the end, I decided to remove the trailing space `
`n`t and period to make sure it worked.";
Write-Host $string;
($xmlReplica.AppendChild(($($xmlLog.CreateElement("404_Error"))))).psBase.InnerText = $string;
}
$Error_Flag = $True;
}
$Catch_Output = $xmlFolder.AppendChild($xmlReplica);
}
# Look for the Access Control Entry for the user $ConnectAs and remove it.
if ( ($Current_SPM -eq $Security_Permission_Mode_Add_Remove_As_Necessary) -or `
($Current_SPM -eq $Security_Permission_Mode_Remove) ) {
foreach ($ACE in $(get-publicfolderclientpermission -Identity $PublicFolderPath)) {
#Write-Host `t ACE:. $([string]$ACE.User)
#Write-Host `t User: $([string]$(get-user $ConnectAs).Identity)
#Write-Host `t $([string]$ACE.User).CompareTo( $([string]$(get-user $ConnectAs).Identity) )
if ($([string]$ACE.User).CompareTo( $([string]$(get-user $ConnectAs).Identity) ) -eq 0) {
($xmlFolder.AppendChild(($($xmlLog.CreateElement("Security_Action"))))).psBase.InnerText = `
"Removing all Access Permissions to " + $NewServer + " for " + $ConnectAs;
Remove-PublicFolderClientPermission -Identity $PublicFolderPath -User $ACE.User -AccessRights $ACE.AccessRights -Confirm:$False;
Write-Host `t Removing ACE for $ConnectAs;
}
}
}
Write-host -------------------------------
Write-host -------------------------------
$Catch_Output = $xmlFolder.AppendChild($xmlReplica);
}
# This code only centers upon $NewServer and $OldServer; which must be explicitly
# defined at the beginning of the script. A good project for someone else would
# be to modify this script to handle 3+ Exchange servers and NOT require $OldServer
# be explicitly defined.
if ( ($([string]$Replica).ToLower().Contains($NewServer.ToLower()) -eq $true))
{
$xmlReplica = $xmlLog.CreateElement("Replica");
($xmlReplica.AppendChild(($($xmlLog.CreateElement("Server_Name"))))).psBase.InnerText = $NewServer;
($xmlReplica.AppendChild(($($xmlLog.CreateElement("Web_Address_Header"))))).psBase.InnerText = 'https://' + $NewServer;
($xmlReplica.AppendChild(($($xmlLog.CreateElement("Item_Count"))))).psBase.InnerText = `
$(Get-PublicFolderStatistics -identity $PublicFolderPath).ItemCount.ToString();
($xmlReplica.AppendChild(($($xmlLog.CreateElement("Byte_Count"))))).psBase.InnerText = `
$(Get-PublicFolderStatistics -identity $PublicFolderPath).TotalItemSize.ToString().Replace("B","");
$Catch_Output = $xmlFolder.AppendChild($xmlReplica);
}
$Catch_Output = $xmlLog.Public_Folders.AppendChild($xmlFolder);
if (($Quit_On_Error -eq $True) -and ($Error_Flag -eq $True)) {exit;}
}
}
Write-Host "Done Processing Folders.`nWriting Log to file.";
$xmlTimeStamp = $xmlLog.CreateElement("TimeStamp");
($xmlTimeStamp.AppendChild(($($xmlLog.CreateElement("Year"))))).psBase.InnerText = Get-Date -UFormat %Y;
($xmlTimeStamp.AppendChild(($($xmlLog.CreateElement("Month"))))).psBase.InnerText = Get-Date -Format %M;
($xmlTimeStamp.AppendChild(($($xmlLog.CreateElement("Day"))))).psBase.InnerText = Get-Date -Format %d;
($xmlTimeStamp.AppendChild(($($xmlLog.CreateElement("Time"))))).psBase.InnerText = Get-Date -UFormat %T;
$Catch_Output = $xmlFinish.AppendChild($xmlTimeStamp);
$xmlLog.Save($(join-path -path $(get-location).tostring() ((get-date -UFormat `
"%Y %m %d %A %r Ex2000 vs Ex2007 Public Folders.xml").replace(" ","_").replace(",","").replace(":","_"))));
This code generates an XML log file as its output. Take a look here:
http://www.visualbasicscript.com/m_62487/tm.htm for the Powershell script that will parse the log file and tell you which folders are out of sync.
An example of what the XML log looks like:
<?xml version="1.0" encoding="ISO-8859-1"?>
<Public_Folders>
<x />
<Run_Details>
<Start>
<TimeStamp>
<Year>2008</Year>
<Month>7</Month>
<Day>14</Day>
<Time>15:03:08</Time>
</TimeStamp>
</Start>
<Finish>
<TimeStamp>
<Year>2008</Year>
<Month>7</Month>
<Day>14</Day>
<Time>20:35:07</Time>
</TimeStamp>
</Finish>
<Parameters>
<Connect_As_Identity>UserID</Connect_As_Identity>
<New_Server>Exchange2007</New_Server>
<Old_Server>Exchange2000</Old_Server>
<Security_Permission_Mode>No Changes</Security_Permission_Mode>
</Parameters>
</Run_Details>
<Public_Folder ID="2">
<Name>Access</Name>
<Path>\Access</Path>
<Friendly_Web_Address>HTTP://OldServer/public/Access</Friendly_Web_Address>
<Proper_Web_Address>HTTP://OldServer/public/Access</Proper_Web_Address>
<Replica>
<Server_Name>NewServer</Server_Name>
<Web_Address_Header>https://NewServer</Web_Address_Header>
<Item_Count>0</Item_Count>
<Byte_Count>0</Byte_Count>
</Replica>
</Public_Folder>
<Public_Folder ID="3">
<Name>Access Issues</Name>
<Path>\Access\Access Issues</Path>
<Friendly_Web_Address>HTTP://OldServer/public/Access/Access Issues</Friendly_Web_Address>
<Proper_Web_Address>HTTP://OldServer/public/Access/Access%20Issues</Proper_Web_Address>
<Replica>
<Server_Name>OldServer</Server_Name>
<Web_Address_Header>http://OldServer</Web_Address_Header>
<Item_Count>26</Item_Count>
<Byte_Count>529033</Byte_Count>
</Replica>
<Replica>
<Server_Name>NewServer</Server_Name>
<Web_Address_Header>https://NewServer</Web_Address_Header>
<Item_Count>26</Item_Count>
<Byte_Count>540999</Byte_Count>
</Replica>
</Public_Folder>
...
<message edited by turranx on Wednesday, July 23, 2008 12:27 AM>