需要一种使用 EWS Web 服务 (SOAP) 查找 Exchange 产品版本的方法

Posted

技术标签:

【中文标题】需要一种使用 EWS Web 服务 (SOAP) 查找 Exchange 产品版本的方法【英文标题】:Need a way to find Exchange product version by using EWS web service (SOAP) 【发布时间】:2016-03-27 01:27:20 【问题描述】:

我正在尝试获取不同服务器的 Exchange 产品版本。服务器由 Microsoft、客户或第三方服务提供商托管。 我需要一种查找版本的方法 - 这样我就可以使用正确的架构和版本指定操作(例如 Exchange2010_SP2 中引入的“获取密码过期”)。支持的最低产品版本是“Exchange2007”。 我发送到服务器以检索版本的soap请求如下。

<?xml version="1.0" encoding="utf-8" ?>
<soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/" xmlns:t="http://schemas.microsoft.com/exchange/services/2006/types">
  <soap:Header>
    <t:RequestServerVersion Version="Exchange2007_SP1" />
  </soap:Header>
  <soap:Body>
    <GetFolder xmlns="http://schemas.microsoft.com/exchange/services/2006/messages" xmlns:t="http://schemas.microsoft.com/exchange/services/2006/types">
      <FolderShape>
        <t:BaseShape>Default</t:BaseShape>
      </FolderShape>
      <FolderIds>
        <t:DistinguishedFolderId Id="sentitems" />
      </FolderIds>
    </GetFolder>
  </soap:Body>
</soap:Envelope>

此请求的问题是返回的服务器版本不同,并且没有清楚地显示 Exchange 产品版本。我得到的版本值类似于“V2_68”、“V2015_10_05”。由于这些值不稳定,我无法将这些值与 Exchange 产品版本匹配。

我曾尝试使用 AutoDiscover GetUserSettingsResponseMessage 操作。对于某些服务器,此操作可以返回标记 EwsSupportSchemas 中的模式。但并非所有服务器都支持自动发现。

<?xml version="1.0" encoding="utf-8"?>
<soap:Envelope xmlns:a="http://schemas.microsoft.com/exchange/2010/Autodiscover"      
               xmlns:wsa="http://www.w3.org/2005/08/addressing" 
               xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"      
               xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/">
  <soap:Header>
    <a:RequestedServerVersion>Exchange2010</a:RequestedServerVersion>
    <wsa:Action>http://schemas.microsoft.com/exchange/2010/Autodiscover/Autodiscover/GetUserSettings</wsa:Action>
    <wsa:To>https://myserver.contoso.com/autodiscover/autodiscover.svc</wsa:To>
  </soap:Header>
  <soap:Body>
    <a:GetUserSettingsRequestMessage xmlns:a="http://schemas.microsoft.com/exchange/2010/Autodiscover">
      <a:Request>
        <a:Users>
          <a:User>
            <a:Mailbox>UserName@domain.contoso.com</a:Mailbox>
          </a:User>
        </a:Users>
        <a:RequestedSettings>
          <a:Setting>UserDisplayName</a:Setting>
          <a:Setting>UserDN</a:Setting>
          <a:Setting>UserDeploymentId</a:Setting>
          <a:Setting>InternalMailboxServer</a:Setting>
          <a:Setting>MailboxDN</a:Setting>
          <a:Setting>ActiveDirectoryServer</a:Setting>
          <a:Setting>CasVersion</a:Setting>
          <a:Setting>EwsSupportedSchemas</a:Setting>
        </a:RequestedSettings>
      </a:Request>
    </a:GetUserSettingsRequestMessage>
  </soap:Body>
</soap:Envelope>

非常感谢。

【问题讨论】:

【参考方案1】:

Exchange 在每个响应中返回服务器信息。您可以执行虚拟请求并从那里获取版本。使用此处提供的 EWS 托管 API 库:https://github.com/OfficeDev/ews-managed-api

您可以执行以下操作:

   /// <summary>
        /// It returns the Exchange server version. It works for any Exchange version since 2007 SP1
        /// </summary>
        private ExchangeVersion GetExchangeVersion(Uri EWS_Url, ExchangeCredentials exchange_credentials=null)
        

            // We pick the oldest version supported by the EWS library which is 2007 SP1
            // Newer exchange versions are backwards compatible
            ExchangeService exchange_service = new ExchangeService(ExchangeVersion.Exchange2007_SP1);
            exchange_service.Url = EWS_Url;

            if (exchange_credentials==null)
                exchange_service.UseDefaultCredentials = true;
            else
                exchange_service.Credentials = exchange_credentials;


            // We do a dummy call
            Folder exchange_folder;
            exchange_folder = Folder.Bind(exchange_service, WellKnownFolderName.Inbox);
            exchange_folder.Load();

            // Retrieve the server info returned in the last call
            ExchangeServerInfo server_info = exchange_service.ServerInfo;


            // This is based on the list from:
            // https://technet.microsoft.com/en-us/library/hh135098(v=exchg.150).aspx
            //
            if (server_info.MajorVersion == 8 && server_info.MinorVersion >= 1)
                return (ExchangeVersion.Exchange2007_SP1);
            else if (server_info.MajorVersion == 14 && server_info.MinorVersion == 0)
                return (ExchangeVersion.Exchange2010);
            else if (server_info.MajorVersion == 14 && server_info.MinorVersion == 1)
                return (ExchangeVersion.Exchange2010_SP1);
            else if (server_info.MajorVersion == 14 && server_info.MinorVersion >= 2)
                return (ExchangeVersion.Exchange2010_SP2);
            else if (server_info.MajorVersion == 15 && server_info.MinorVersion == 0)
                return (ExchangeVersion.Exchange2013);
            else if (server_info.MajorVersion >= 15)
                return (ExchangeVersion.Exchange2013_SP1);
            else
                throw (new Exception("Unknown Exchange version"));
        

【讨论】:

感谢您发布此信息。伟大的代码和 MS 应该最终添加一个选项来使用自动发现检索它,因此我们不需要执行两个请求。如果没有提供,甚至更好地自动执行此操作。【参考方案2】:

您需要区分 OnPrem,您尝试的请求在哪里可以正常工作(例如,您将看到 Exchange 架构版本)和 Office365,这是您唯一会获得架构版本,如“V2_68”、“V2015_10_05”(这是因为云和 OnPrem 版本已经不同),您应该期望随着云中更新节奏的变化,这种情况会发生变化。有很多方法可以确定您是否访问云邮箱,从自动发现到仅查看您的请求将要到达的端点(例如,在 Office365 上,所有内容都将转到负载平衡端点)。

干杯 格伦

【讨论】:

感谢您的回答。试图为 OnPrem 和基于云的服务器找到最低/最旧的版本,我现在需要支持。 Exchange 2007_SP1 应该是您会遇到的最低版本,但由于可支持性,2007 的安装数量正在快速下降。【参考方案3】:

我也有同样的问题。

您可以查看 /EWS/types.xsd 并阅读 version 属性,但即使这样也不能保证有效,因为 Exchange 管理员可能会以非常有创意的方式错误配置 Exchange 服务器。此外,Office365 似乎非常努力地只与 Microsoft 品牌产品配合使用。

在多次尝试表现得很好之后,我采取了反复试验。首先,我发送一个所有 EWS 版本都支持的虚拟请求(ResolveNames 服务和UnresolvedEntry=DUMMY)并测试服务器是否接受RequestServerVersion 值。如果没有,请冲洗并使用新的RequestServerVersion 值重复,直到请求被接受。如果服务器以正常的 ServerVersionInfo 值(形式为 ExchangeYYYY[_SPn])响应,我将在以下请求中使用它,否则我使用我发送的 RequestServerVersion 值。我被这个 hack 弄得眼花缭乱,但这是我发现与正在与之通信的各种 Exchange 服务器可靠工作的唯一方法。

FWIW,这是我在 2016 年 1 月测试的 RequestServerVersion 值:

Exchange2007 Exchange2007_SP1 Exchange2010 Exchange2010_SP1 Exchange2010_SP2 Exchange2013 Exchange2016

【讨论】:

以上是关于需要一种使用 EWS Web 服务 (SOAP) 查找 Exchange 产品版本的方法的主要内容,如果未能解决你的问题,请参考以下文章

节点 js 中的 EWS 推送通知

使用 TokenCredentials 的 Exchange Web 服务 (EWS) 单点登录?

Exchange Web 服务 (EWS) - 约会资源

在调用Web服务时,是否有一种简单的方法可以获取请求的soap消息和响应的soap消息?

使用 PHP 和 cURL 访问 Exchange Web 服务

比较和对比 REST 和 SOAP Web 服务? [复制]