CRM Online では、 今のところ、北米かヨーロッパ、アジア太平洋のサーバーでホストされます。自分の使用している CRM サーバーがどの場所で動作しているかは、サーバー名のアドレスを見ればわかりますが、せっかくなので IDiscoveryService Web Service を使用して 自分のCRM Online がどこでホストされているかを調べるサンプルを掲載します。CRM Onlineのサーバー名と実際に動作しているロケーションについては以下のURLを参照してください。

Discover the URL for Your Organization with IDiscoveryService Web Service
http://technet.microsoft.com/en-us/library/gg328127.aspx

IDiscoveryService を使用してみたかったので、プログラムでDiscoveryService 経由で取得した組織情報を列挙するサンプルを掲載します。サンプルを実行するとわかるのですが、特定の組織情報を取得する場合に指定する組織のユニーク名は CRM Online と OnPremise の場合でネーミングが異なります。 

1. IDiscoveryServiceを使用するサンプルプログラム

コンソールアプリケーションを作成します。[Dynamics CRM 2011]遅延バインディング(Late Binding) でCRM Webサービス に接続する で記載したように、参照の追加により、sdkのbinフォルダに格納されている、microsoft.crm.sdk.proxy.dll と microsoft.xrm.sdk.dll を追加します。同様に、System.ServiceModel.dll と System.Runtime.Serialization.dll を追加します。

プロジェクトのプロパティを開いて、ターゲットフレームワークを .NET Framework 4.0 にします。ここまでで準備は完了です。

CRM Online の IDiscoveryService に接続して、組織情報を列挙するサンプルソースを記載します。サンプルでは、CRM Online 用の3箇所のIDiscoveryService 用のアドレスすべてに対して、RetrieveOrganizationsRequest  を使用して、組織情報を取得しています。

サンプルでは、単独の組織を取得するサンプルとして、内部でRetrieveOrganizationRequest を使用するDisplayOrganizationInfo メソッドも実装しています。注意点として、CRM Online の場合、RetrieveOrganizationRequest で使用する 組織のユニーク名は 組織IDのGUIDからハイフンを除いた文字列になっています。CRM Onlineのホスト名の先頭の組織名らしき文字列(UrlName)ではないので注意してください。OnPremiseの場合は、組織名と同じになります。

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Microsoft.Xrm.Sdk.Client;
using System.ServiceModel.Description;
using Microsoft.Xrm.Sdk.Discovery;
using System.ServiceModel.Security;

namespace LateBindingSample03
{
    class Program
    {
        static string[] discoveryServiceUrls = new string[]{
                "https://dev.crm.dynamics.com/XRMServices/2011/Discovery.svc"
                ,"https://dev.crm4.dynamics.com/XRMServices/2011/Discovery.svc"
                ,"https://dev.crm5.dynamics.com/XRMServices/2011/Discovery.svc"};

        static void Main(string[] args)
        {
            // 北米、ヨーロッパ、アジア太平洋のDiscoveryService を検索して、
            // 組織情報を検索する
            string uniquename = DisplayOrganizationsInfo();
            // 組織のユニーク名を指定して組織情報を検索する
            DisplayOrganizationInfo(uniquename);
            //DisplayOrganizationsInfoForOnPremise();
            Console.ReadLine();
        }
        #region Online版のサンプル
        /// <summary>
        /// 組織のユニーク名(CrmOnlineのURLで先頭に付与される組織名らしきものではないので注意)
        /// CrmOnlineの場合、組織のGUIDにハイフンを除いた文字列
        /// </summary>
        /// <param name="uniqueName"></param>
        public static void DisplayOrganizationInfo(string uniqueName)
        {
            if (string.IsNullOrEmpty(uniqueName)) return;
            foreach (var discoveryServiceUrl in discoveryServiceUrls)
            {
                try
                {
                    using (DiscoveryServiceProxy service = GetDiscoveryService(discoveryServiceUrl))
                    {
                        RetrieveOrganizationRequest request = new RetrieveOrganizationRequest()
                        {
                            UniqueName = uniqueName,
                            Release = OrganizationRelease.Current,
                            AccessType = EndpointAccessType.Default
                        };
                        RetrieveOrganizationResponse response = service.Execute(request) as RetrieveOrganizationResponse;

                        Console.WriteLine("取得できたDiscoveryServiceのURL:{0}", discoveryServiceUrl);
                        OrganizationDetail detail = response.Detail;
                        Console.WriteLine("組織GUID:{0}", detail.OrganizationId);
                        Console.WriteLine("組織UniqueName:{0}", detail.UniqueName);
                        Console.WriteLine("組織フレンドリ名:{0}", detail.FriendlyName);
                        Console.WriteLine("組織名(UrlName):{0}", detail.UrlName);
                        Console.WriteLine("バージョン:{0}", detail.OrganizationVersion);

                        Console.WriteLine("エンドポイント一覧");
                        Console.WriteLine("WebApp:{0}", detail.Endpoints[EndpointType.WebApplication]);
                        Console.WriteLine("組織サービス:{0}", detail.Endpoints[EndpointType.OrganizationService]);
                        Console.WriteLine("組織データサービス:{0}", detail.Endpoints[EndpointType.OrganizationDataService]);
                    }
                }
                catch (SecurityAccessDeniedException)
                {
                    // 該当のエリアには指定した組織が存在しない
                }
            }

        }
        public static string DisplayOrganizationsInfo()
        {
            string uniquename = string.Empty;
            foreach (var discoveryServiceUrl in discoveryServiceUrls)
            {
                try
                {
                    using (DiscoveryServiceProxy service = GetDiscoveryService(discoveryServiceUrl))
                    {
                        RetrieveOrganizationsRequest request = new RetrieveOrganizationsRequest()
                        {
                            AccessType = EndpointAccessType.Default,
                            Release = OrganizationRelease.Current
                        };
                        RetrieveOrganizationsResponse response = service.Execute(request) as RetrieveOrganizationsResponse;

                        foreach (OrganizationDetail detail in response.Details)
                        {
                            Console.WriteLine("組織GUID:{0}", detail.OrganizationId);
                            Console.WriteLine("組織UniqueName:{0}", detail.UniqueName);
                            Console.WriteLine("組織フレンドリ名:{0}", detail.FriendlyName);
                            Console.WriteLine("組織名(UrlName):{0}", detail.UrlName);
                            Console.WriteLine("バージョン:{0}", detail.OrganizationVersion);

                            Console.WriteLine("エンドポイント一覧");
                            Console.WriteLine("WebApp:{0}", detail.Endpoints[EndpointType.WebApplication]);
                            Console.WriteLine("組織サービス:{0}", detail.Endpoints[EndpointType.OrganizationService]);
                            Console.WriteLine("組織データサービス:{0}", detail.Endpoints[EndpointType.OrganizationDataService]);

                            uniquename = detail.UniqueName;
                        }
                    }
                }
                catch (SecurityAccessDeniedException)
                {
                    // 該当のエリアには指定した組織が存在しない
                }
            }
            return uniquename;
        }
        private static DiscoveryServiceProxy GetDiscoveryService(string discoverServiceAddress)
        {
            // Windows Live のユーザ名とパスワード
            ClientCredentials liveCredential = new ClientCredentials();
            liveCredential.UserName.UserName = "testxxx@xxxx.jp";
            liveCredential.UserName.Password = "xxxaaaxxx";

            // DeviceID
            ClientCredentials deviceCredential = new ClientCredentials();
            deviceCredential.UserName.UserName = "xxxxxxddddddd";
            deviceCredential.UserName.Password = "xsadfasfawsfas";


            DiscoveryServiceProxy proxy = new DiscoveryServiceProxy(new Uri(discoverServiceAddress), null, liveCredential, deviceCredential);
            return proxy;
        }
        #endregion

        #region OnPremiseの場合のサンプル
        /// <summary>
        /// 参考としてOnPremise版の処理。Online 版と異なり、UniqueName と組織名は同じになります。
        /// </summary>
        private static void DisplayOrganizationsInfoForOnPremise()
        {
            using (DiscoveryServiceProxy service = GetDiscoveryServiceForOnPremise())
            {
                RetrieveOrganizationsRequest request = new RetrieveOrganizationsRequest()
                {
                    AccessType = EndpointAccessType.Default,
                    Release = OrganizationRelease.Current
                };
                RetrieveOrganizationsResponse response = service.Execute(request) as RetrieveOrganizationsResponse;

                foreach (OrganizationDetail detail in response.Details)
                {
                    Console.WriteLine("組織GUID:{0}", detail.OrganizationId);
                    Console.WriteLine("組織UniqueName:{0}", detail.UniqueName);
                    Console.WriteLine("組織フレンドリ名:{0}", detail.FriendlyName);
                    Console.WriteLine("組織名(UrlName):{0}", detail.UrlName);
                    Console.WriteLine("バージョン:{0}", detail.OrganizationVersion);

                    Console.WriteLine("エンドポイント一覧");
                    Console.WriteLine("WebApp:{0}", detail.Endpoints[EndpointType.WebApplication]);
                    Console.WriteLine("組織サービス:{0}", detail.Endpoints[EndpointType.OrganizationService]);
                    Console.WriteLine("組織データサービス:{0}", detail.Endpoints[EndpointType.OrganizationDataService]);

                }
            }

        }
        /// <summary>
        /// 参考:OnPremiseの場合
        /// </summary>
        /// <returns></returns>
        private static DiscoveryServiceProxy GetDiscoveryServiceForOnPremise()
        {
            string url = "http://crmsvr01/XRMServices/2011/Discovery.svc";

            // 実行ユーザの資格情報を使用
            ClientCredentials credential = new ClientCredentials();

            DiscoveryServiceProxy proxy = new DiscoveryServiceProxy(new Uri(url), null, credential, null);
            return proxy;
        }
        #endregion
    }
}

上記サンプルプログラムで使用している、DeviceIDとパスワードは、SDKにソースコードで付属している deviceregistration ツール を使用して調べることができます。

2.まとめ

説明は以上です。間違い、指摘点などあればご連絡ください。

組織のユニーク名は Online と OnPremise では異なるネーミングルールとなっているようです。