I'm trying to move items between non-wellknown folders to consolidate two hierarchy branches in an Exchange Online Archive mailbox. I've gotten the mailboxFolderStatistics, converted the FolderID (OWAid) to EWSid, and I'm trying to compare it to the list of EWSids retrieved when binding to the ArchiveMsgFolderRoot, and getting a list of all the folders. I'm finding that the converted FolderIDs are not the same as what's retrieved by the bind. I was trying to get the folder stats, convert the FolderID, and bind to the folders using those converted FolderIDs, but can't find the folders. I'm going to try to do this a different way at this point (Glen's FolderIdFromPath function), but I don't understand why the converted and retrieved EWSids are different.
This is how I'm converting the FolderIDs, and how I'm retrieving the folders. The same folder in the $FolderStats and $MailboxFolderList do not have the same ID.
# Function to convert the OWAid to EWSid
function ConvertId{
param (
$OwaId = "$( throw 'OWAId is a mandatory Parameter' )"
)
process{
$aiItem = New-Object Microsoft.Exchange.WebServices.Data.AlternateId
$aiItem.Mailbox = $Mailbox
$aiItem.UniqueId = $OwaId
$aiItem.Format = [Microsoft.Exchange.WebServices.Data.IdFormat]::OwaId
$convertedId = $service.ConvertId($aiItem, [Microsoft.Exchange.WebServices.Data.IdFormat]::EwsId)
return $convertedId.UniqueId
}
} # function ConvertId END
# Mailbox to act against
$Mailbox = "UserA@domain.com"
# Import Web Services Module
Import-Module -Name "C:\Program Files\Microsoft\Exchange\Web Services\2.2\Microsoft.Exchange.WebServices.dll"
# Load the System.Web assembly
Add-Type -AssemblyName System.Web
# EWS service setup: Create the service object to access the Archive mailbox
$service = New-Object Microsoft.Exchange.WebServices.Data.ExchangeService -ArgumentList Exchange2013_SP1
$service.Credentials = new-object Microsoft.Exchange.WebServices.Data.WebCredentials -ArgumentList $Credential.UserName, $Credential.GetNetworkCredential().Password
$service.Url= new-object Uri("https://outlook.office365.com/EWS/Exchange.asmx")
$service.TraceEnabled = $True
$service.ImpersonatedUserId = new-object Microsoft.Exchange.WebServices.Data.ImpersonatedUserId([Microsoft.Exchange.WebServices.Data.ConnectingIdType]::SmtpAddress,$Mailbox)
# Import the latest Archive mailbox folderstats
$FolderStats = Import-Csv "C:\MBstats_4-1-2019.csv" | select *, EWSid
# Convert the OWAid(mailboxFolderStatistics) to EWSid
foreach($FolderStat in $FolderStats)
{
$UrlEncodedId = [System.Web.HttpUtility]::UrlEncode($FolderStat.FolderId.ToString())
$FolderStat.EWSid = new-object Microsoft.Exchange.WebServices.Data.FolderId((Convertid $UrlEncodedId))
}
# Bind to the Archive mailbox root
$ArchiveMailboxRoot = New-Object Microsoft.Exchange.WebServices.Data.FolderId([Microsoft.Exchange.Webservices.Data.WellKnownFolderName]::ArchiveMsgFolderRoot,$Mailbox)
$BindArchiveMailboxRoot = [Microsoft.Exchange.WebServices.Data.Folder]::Bind($service,$ArchiveMailboxRoot)
# Create search criteria
$FolderView = New-Object Microsoft.Exchange.WebServices.Data.FolderView(10000)
$FolderView.Traversal = [Microsoft.Exchange.WebServices.Data.FolderTraversal]::Deep
# Get all Archive mailbox folders
$MailboxFolderList = $BindArchiveMailboxRoot.FindFolders($FolderView)
When you converting an Id from an Archive folder you need to set the IsArchive property to True on the AlternateId Object eg maybe do
# Function to convert the OWAid to EWSid
function ConvertArchiveId{
param (
$OwaId = "$( throw 'OWAId is a mandatory Parameter' )"
)
process{
$aiItem = New-Object Microsoft.Exchange.WebServices.Data.AlternateId
$aiItem.Mailbox = $Mailbox
$aiItem.UniqueId = $OwaId
$aiItem.Format = [Microsoft.Exchange.WebServices.Data.IdFormat]::OwaId
$aiItem.isArchive = $true
$convertedId = $service.ConvertId($aiItem, [Microsoft.Exchange.WebServices.Data.IdFormat]::EwsId)
return $convertedId.UniqueId
}
} # function ConvertId END