by

EWS Fundamentals : Create a Folder in a Mailbox or Public Folder

EWS Fundamentals : Create a Folder in a Mailbox or Public Folder One of many extra frequent questions on EWS I get is round how one can create a folder so this submit will cowl the fundamentals you want to know round creating folders utilizing EWS in Mailboxes or Public Folders.

What you want to create a Folder

To create a folder you first want a novel title for the brand new folder eg in case you going to create a folder known as “SubFolder1” beneath the Inbox one other folder with the title Subfolder1 cannot already exists as a SubFolder of the Inbox (anyplace else within the Mailbox is okay) if it does you’re going to get an error.  So when writing a script to create a folder its first good to features a search to see if the folder already exists. eg

  #Outline Folder Veiw Actually solely need to return one object  
$fvFolderView = new-object Microsoft.Change.WebServices.Knowledge.FolderView(1)
#Outline a Search folder that's going to do a search primarily based on the DisplayName of the folder
$SfSearchFilter = new-object Microsoft.Change.WebServices.Knowledge.SearchFilter+IsEqualTo([Microsoft.Exchange.WebServices.Data.FolderSchema]::DisplayName,$NewFolderName)
#Do the Search
$findFolderResults = $service.FindFolders($EWSParentFolder.Id,$SfSearchFilter,$fvFolderView)
if ($findFolderResults.TotalCount -eq 0){
Write-host ("Folder Doesn't Exist")
$NewFolder.Save($EWSParentFolder.Id)
Write-host ("Folder Created")
}
else{
Write-error ("Folder already Exist with that Name")
}

The second piece of knowledge you want is what sort of folder your going to create, in Change  folders have a default ItemType property (in EWS this the FolderClass in Mapi its PR_CONTAINER_CLASS) . Eg while you create a folder is you specify the Folder Class of this Folder is for Appointment the Shopper will deal with that folder as a Calender Folder. In EWS as soon as this FolderClass is ready the service will return a unique FolderType for the next Folder

  • Mail Folders – IPF.Observe – EWS Managed API Sort Folder
  • Calendar Folders – IPF.Appointment – EWS Managed API Sort CalendarFolder
  • Contact Folders – IPF.Contact – EWS Managed API Sort ContactFolder
  • Activity Folders – IPF.Activity – EWS Managed API Sort TaskFolder

In Change and Outlook there are different FolderType eg Notes, Journal and many others however these will simply be returned as Folder in EWS. Usually aside from CalendarFolder which has totally different Permissions varieties the Folders could be handled the identical aside from the FolderClass property.

The final piece of knowledge you want when making a folder is you want know the ewsId of the Father or mother folder. In case your making a folder inside a WellKnown Folder just like the Inbox,Calendar,MailboxRoot and many others then you possibly can simply use the FolderId overload eg for the Inbox

$folderid= new-object Microsoft.Change.WebServices.Knowledge.FolderId([Microsoft.Change.WebServices.Knowledge.WellKnownFolderName]::Inbox,$MailboxName)   
$NewFolder.Save($folderid)

If this isn’t a WellKnownFolder or a PublicFolder then you want to first discover the EWSFolderId, for this I usually advocate you nice a path for the mum or dad folder like InboxParentFolder after which use a Operate like this to search out the FolderId eg

operate FolderIdFromPath{
param (
$FolderPath = "$( throw 'Folder Path is a compulsory Parameter' )",
$SmtpAddress = "$( throw 'Folder Path is a compulsory Parameter' )"
)
course of{
## Discover and Bind to Folder primarily based on Path
#Outline the trail to look needs to be seperated with
#Bind to the MSGFolder Root
$folderid = new-object Microsoft.Change.WebServices.Knowledge.FolderId([Microsoft.Exchange.WebServices.Data.WellKnownFolderName]::MsgFolderRoot,$SmtpAddress)
$tfTargetFolder = [Microsoft.Exchange.WebServices.Data.Folder]::Bind($service,$folderid)
#Break up the Search path into an array
$fldArray = $FolderPath.Break up("")
#Loop via the Break up Array and do a Seek for every degree of folder
for ($lint = 1; $lint -lt $fldArray.Size; $lint++) {
#Carry out search primarily based on the displayname of every folder degree
$fvFolderView = new-object Microsoft.Change.WebServices.Knowledge.FolderView(1)
$SfSearchFilter = new-object Microsoft.Change.WebServices.Knowledge.SearchFilter+IsEqualTo([Microsoft.Exchange.WebServices.Data.FolderSchema]::DisplayName,$fldArray[$lint])
$findFolderResults = $service.FindFolders($tfTargetFolder.Id,$SfSearchFilter,$fvFolderView)
if ($findFolderResults.TotalCount -gt 0){
foreach($folder in $findFolderResults.Folders){
$tfTargetFolder = $folder
}
}
else{
"Error Folder Not Found"
$tfTargetFolder = $null
break
}
}
if($tfTargetFolder -ne $null){
return $tfTargetFolder.Id.UniqueId.ToString()
}
else{
throw "Folder not found"
}
}
}

or for Public Folders you want to use one thing like

operate PublicFolderIdFromPath{
param (
[Parameter(Place=0, Necessary=$true)] [Microsoft.Exchange.WebServices.Data.ExchangeService]$service,
[Parameter(Place=1, Necessary=$true)] [String]$FolderPath,
[Parameter(Place=2, Necessary=$true)] [String]$SmtpAddress
)
course of{
## Discover and Bind to Folder primarily based on Path
#Outline the trail to look needs to be seperated with
#Bind to the MSGFolder Root
$folderid = new-object Microsoft.Change.WebServices.Knowledge.FolderId([Microsoft.Exchange.WebServices.Data.WellKnownFolderName]::PublicFoldersRoot)
$psPropset= new-object Microsoft.Change.WebServices.Knowledge.PropertySet([Microsoft.Exchange.WebServices.Data.BasePropertySet]::FirstClassProperties)
$PR_REPLICA_LIST = New-Object Microsoft.Change.WebServices.Knowledge.ExtendedPropertyDefinition(0x6698,[Microsoft.Exchange.WebServices.Data.MapiPropertyType]::Binary);
$psPropset.Add($PR_REPLICA_LIST)
$tfTargetFolder = [Microsoft.Exchange.WebServices.Data.Folder]::Bind($service,$folderid,$psPropset)
$PR_REPLICA_LIST_Value = $null
if($tfTargetFolder.TryGetProperty($PR_REPLICA_LIST,[ref]$PR_REPLICA_LIST_Value)){
$GuidAsString = [System.Text.Encoding]::ASCII.GetString($PR_REPLICA_LIST_Value, 0, 36);
$HeaderAddress = new-object System.Internet.Mail.MailAddress($service.HttpHeaders["X-AnchorMailbox"])
$pfHeader = $GuidAsString + "@" + $HeaderAddress.Host
write-host ("Root Public Folder Routing Information Header : " + $pfHeader )
$service.HttpHeaders.Add("X-PublicFolderMailbox", $pfHeader)
}
#Break up the Search path into an array
$fldArray = $FolderPath.Break up("")
#Loop via the Break up Array and do a Seek for every degree of folder
for ($lint = 1; $lint -lt $fldArray.Size; $lint++) {
#Carry out search primarily based on the displayname of every folder degree
$fvFolderView = new-object Microsoft.Change.WebServices.Knowledge.FolderView(1)
$fvFolderView.PropertySet = $psPropset
$SfSearchFilter = new-object Microsoft.Change.WebServices.Knowledge.SearchFilter+IsEqualTo([Microsoft.Exchange.WebServices.Data.FolderSchema]::DisplayName,$fldArray[$lint])
$findFolderResults = $service.FindFolders($tfTargetFolder.Id,$SfSearchFilter,$fvFolderView)
if ($findFolderResults.TotalCount -gt 0){
foreach($folder in $findFolderResults.Folders){
$tfTargetFolder = $folder
}
}
else{
"Error Folder Not Found"
$tfTargetFolder = $null
break
}
}
if($tfTargetFolder -ne $null){
$PR_REPLICA_LIST_Value = $null
if($tfTargetFolder.TryGetProperty($PR_REPLICA_LIST,[ref]$PR_REPLICA_LIST_Value)){
$GuidAsString = [System.Text.Encoding]::ASCII.GetString($PR_REPLICA_LIST_Value, 0, 36);
$HeaderAddress = new-object System.Internet.Mail.MailAddress($service.HttpHeaders["X-AnchorMailbox"])
$pfHeader = $GuidAsString + "@" + $HeaderAddress.Host
write-host ("Target Public Folder Routing Information Header : " + $pfHeader )
Get-PublicFolderContentRoutingHeader -service $service -Credentials $Credentials -MailboxName $SmtpAddress -pfAddress $pfHeader
}
return $tfTargetFolder.Id.UniqueId.ToString()
}
else{
throw "Folder not found"
}
}
}

I’ve a module that mixes all these that I’ve blogged earlier than right here https://github.com/gscales/Powershell-Scripts/blob/grasp/CreateFolder.ps1 I’ve added a brand new cmdlet on this module to now let you create folder inside a public folder eg

Create-PublicFolder -Mailboxname mailbox@area.com -NewFolderName check -ParentPublicFolderPath ‘Folder1Folder2’