0

我可以使用以下 powershell 命令检索存储在特定公用文件夹邮箱中的公用文件夹:

Get-PublicFolder –GetChildren | Where { $ _.ContentMailboxName –eq “PFMailbox1” }

(但我不想使用远程 PowerShell)

我无法使用 EWS 执行此操作。

我的第一个想法是获取所有公用文件夹,然后根据公用文件夹邮箱对其进行排序。

但可能没有包含公用文件夹邮箱名称的扩展 MAPI 属性(类似于 ContentMailboxName powershell 属性)。

所以我尝试了这个:具有委托访问权限的 EWS

var mailbox = new Mailbox("PFMailbox1@MyDomain.local"); 
// PFMailbox1 is Public Folder mailbox with Pubclic folders
FolderId folderId = new FolderId(WellKnownFolderName.MsgFolderRoot, mailbox);
Folder rootfolder = Folder.Bind(service, folderId);

(WellKnownFolderName 属性也使用 .Root 和 PublicFolderRoot 进行了测试)

但我总是得到错误:

“请求失败。远程服务器返回错误:(503)服务器不可用。” 或“Microsoft.Exchange.WebServices.dll 中发生了“Microsoft.Exchange.WebServices.Data.ServiceResponseException”类型的未处理异常”

当我尝试模仿时

service.ImpersonatedUserId = new ImpersonatedUserId(ConnectingIdType.SmtpAddress, impUser);
// impUser=PFMailbox1@MyDomain.local
Folder rootfolder = Folder.Bind(service, WellKnownFolderName.MsgFolderRoot );

我得到错误:

“该帐户无权模拟所请求的用户。”

用户 Administrator 和 PFMailbox1 的所有邮箱权限都设置为完全访问权限。我正在使用最新的 Exchange2013 dll。

编辑1:

第二个问题是如何创建根公用文件夹并将其保存到所需的公用文件夹邮箱?

EWS 方法 Folder.Save(FolderId) 只有一个参数,如果我使用 FolderId = PublicFolderRoot -> 所有文件夹都将保存到 MasterHierarchy 公共文件夹邮箱(第一次创建的邮箱)中。

我知道的唯一解决方案是使用 Remote Power Shell 为每个公用文件夹邮箱创建第一级(根)文件夹。

New-PublicFolder "Folder1" -Mailbox "PFMailbox1"
New-PublicFolder "Folder2" -Mailbox "PFMailbox2"

然后在第二个(第三个,..)文件夹级别,我可以使用 Folder.Save(FolderID)。但是如何使用 EWS 做到这一点?

4

2 回答 2

0

我找到了一个可能的解决方案。

Exchange 2013 的公用文件夹中有一个未命名的扩展 EWS 属性"0x6656"(我使用 OutlookSpy - 选择公用文件夹邮箱,单击 EMAPIFolder)。

例如,有4e1f53e4-0f2d-46eb-873f-b4857d9d395a@myDomain.local

对于一个公用文件夹邮箱中的每个文件夹,该值都相同。GUID(之前@)是ExchangeMailboxGuid- 这可以与 Active Directory 中的公用文件夹邮箱一起读取,然后将公用文件夹与邮箱配对。

问题是我无法使用托管 EWS 读取此属性(我无法读取任何未命名的扩展属性)。我使用了这个定义:

var ExchangeMailboxGuid = new ExtendedPropertyDefinition(0x6656, MapiPropertyType.String);

也许我可以尝试非托管 EWS,但它更复杂。

作为一个临时解决方案,我结合了 EWS 和远程 PowerShell。这是我的伪代码:

if (folderId == null)   // It is root public folder
{
    var mailboxGuid = GetMailboxId();
    // public folder root
    var ewsFolderId = EwsAdapter.GetPublicFolderId(folderId);
    // get all root public folders from all public folder mailboxes
    var tempFindFolderResults = FindFolders(ewsFolderId);

    var powerShellConnection = new powerShellConnection(ConnectionConfiguration);
    // get all root public folders with info which mailbox is owner
    var PublicFolderMailboxes = powerShellConnection.GetPublicFolders();

    foreach (var publicFolderMailbox in PublicFolderMailboxes)
    {
        if (publicFolderMailbox.Attributes["ExchangeMailboxGuid"].Value == mailboxGuid)
        {
            foreach (var tempFindFolderResult in tempFindFolderResults)
            {
                if (tempFindFolderResult.DisplayName == publicFolderMailbox.Attributes["Name"].Value)
                {
                    // add only folder from selected public folder mailbox
                    findFolderResults.Add(tempFindFolderResult);
                }
            }
        }
    }
}
else  // it is public subfolder - standard handling
{
    var ewsFolderId = EwsAdapterHelper.GetPublicFolderId(folderId);
    findFolderResults = FindFolders(ewsFolderId);
}

这是我在方法中使用的 PowerShell 命令GetPublicFolders

Get-PublicFolder -GetChildren

编辑:我认为 EWS 不完全支持 Exchange 2013 公用文件夹 -

  1. 如何从任何“公用文件夹邮箱”获取公用文件夹和
  2. 将根级别的公用文件夹保存到任何“公用文件夹邮箱”(不仅是主公用文件夹邮箱)。
于 2014-02-28T13:50:51.173 回答
0

我没有尝试使用委托访问或模拟,但如果我是公用文件夹的发布编辑器,我可以使用以下代码检索公用文件夹邮箱的直接子文件夹。有一个 FolderTraversal 值来指定浅搜索(仅限直接子文件夹)或深度搜索(整个层次结构),但您不能在公用文件夹上使用深度搜索。

private static void GetFolderHierarchy(int folderViewSize, ExchangeService service)
    {
        FolderView view = new FolderView(folderViewSize);
        view.PropertySet = new PropertySet(BasePropertySet.IdOnly, FolderSchema.DisplayName);     

        // Call FindFolders to retrieve the folder hierarchy, starting with the PublicFoldersRoot folder.
        FindFoldersResults findResults = service.FindFolders(WellKnownFolderName.PublicFoldersRoot, view);

        foreach (Folder folder in findResults.Folders)
        {
             Console.WriteLine("Public folder display name: {0} ", folder.DisplayName);

        }
   }
于 2014-02-22T05:31:44.677 回答