コンソール アプリケーションのプロビジョニング サンプル

新しいアドイン モデルをサポートするために Office 365 Developer Patterns and Practices プログラム (PnP) で導入されたプロビジョニング フレームワークを使用すると、ユーザーは、

  • サイト モデルを指すだけでカスタム サイト テンプレートを作成でき、
  • そのモデルをプロビジョニング テンプレートとして永続化し、
  • そのカスタム テンプレートを必要に応じて既存のサイト コレクションに適用することができます。

注:

PnP プロビジョニング フレームワーク & PnP プロビジョニング エンジンは、アクティブなコミュニティがサポートを提供するオープン ソース ソリューションです。 Microsoft からのオープン ソース ツールのサポート SLA はありません。

このサンプルでは、PnP のコア プロビジョニング ライブラリのクラスを実装する基本的なコンソール アプリケーションを作成します。これらのクラスの実装により、PnP プロビジョニング エンジンが以下の必要なプロビジョニング タスクを実行することが可能になります。

  • サイトのカスタマイズを設計してモデル化します。 新しいサイト デザインにすることも、既存のサイトをポイントして、それをプロビジョニング テンプレートとして保存することもできます。
  • サイト モデルをプロビジョニング テンプレートとして保存して永続化し、再利用できるようにします。
  • プロビジョニング テンプレートを新規または既存のサイト コレクションに適用します。

注:

このサンプル チュートリアルは、現在 GitHub の「PnP プロビジョニング エンジンの入門」で入手できるサンプルと対になるものです。 このサンプルのコード (Program.cs) とソリューション ファイルは、ダウンロードできます。 Microsoft Channel 9 のサイトの「PnP プロビジョニング エンジンの入門」にはこのプロセス (コードは若干異なります) について説明する 20 分間のビデオもあります。

Visual Studio プロジェクトの作成と準備

はじめに、Visual Studio プロジェクトを作成します。 このサンプルでは、簡略化するために、プロビジョニング フレームワークの PnP コア ライブラリを使用して PnP プロビジョニング エンジンを実装する基本的なコンソール アプリケーションを作成します。 ただし、このサンプル ソリューションをサポートするには、PnP コア ライブラリ用のプロビジョニング フレームワークをダウンロードしてインストールする必要があります。

  1. Visual Studio を開いてから、[ファイル]>[新規]>[プロジェクト] を選択します。

  2. 新規プロジェクト ウィザードで、[Visual C#] を選択してから、[コンソール アプリケーション] を選択します。

  3. プロジェクトに Program という名前を付けてから、[OK] を選択します (任意の名前を付けることができますが、このサンプル チュートリアルではプロジェクト名は Program とします)。

  4. PnP コア ライブラリをダウンロードしてインストールします。これは NuGet パッケージとして「SharePointPnPCore パッケージ」から入手できます。

    注:

    このライブラリには、次の 3 つのバージョンがあります。 1 つ目のバージョンは、SharePoint Online と Office 365 をターゲットにした SharePointPnPCoreOnline ライブラリです。 その他のバージョンは、SharePointPnPCore2013 および SharePointPnPCore2016 です。そして、それぞれが SharePoint オンプレミス バージョン 2013 および 2016 をターゲットにします。

  5. NuGet クライアント インストーラー」にアクセスして NuGet クライアントをインストールします。

  6. NuGet クライアントがインストールされたら、NuGet パッケージ マネージャーを実行します。 Visual Studio のソリューション エクスプローラーReferences ノードを右クリックしてから、[NuGet パッケージの管理] を選択します。

  7. パッケージ マネージャーで [参照] を選択し、検索語として「SharePoint PnP」を入力して、SharePointPnPCoreOnline ライブラリが表示されるようにします。

  8. 指示に従って SharePointPnPCoreOnline ライブラリをダウンロードしてインストールします。

    After the PnP Core library is referenced in your Visual Studio project, all library members are available to you as extension methods on existing object instances, for example, web and list instances.

  9. Program.cs ファイルに以下のすべての using ステートメントが含まれていることを確認します。

    using Microsoft.SharePoint.Client;
    using OfficeDevPnP.Core.Framework.Provisioning.Connectors;
    using OfficeDevPnP.Core.Framework.Provisioning.Model;
    using OfficeDevPnP.Core.Framework.Provisioning.ObjectHandlers;
    using OfficeDevPnP.Core.Framework.Provisioning.Providers.Xml;
    using System;
    using System.Net;
    using System.Security;
    using System.Threading;
    

プロビジョニング テンプレートの作成、抽出、および永続化

プロジェクトがセットアップされたら、サイトのカスタマイズを作成できます。 これは、手動で実行することも、デザインを流用するサイトを指すことで実行することもできます。 選択したサイト デザインをプロビジョニング テンプレートとして保存するだけです。両方のアプローチの組み合わせを使用することもできます。 このサンプルの目的では、既存のサイトを指して、作成済みの外観とサイト成果物 (ただし、コンテンツではない) をプロビジョニング テンプレートとして保存するだけです。

まず、プロビジョニング テンプレートのモデルにするサイトに接続する必要があります。 ユーザー名、パスワード、ソース URL などの接続情報を収集することから開始します。

  1. ユーザーから接続情報を収集します。 プログラムの Main ルーチンでは、次の 3 つの簡単な作業を行っています。これらは、接続情報の収集、プロビジョニング テンプレートの取得、およびプロビジョニング テンプレートの適用です。 面倒な作業は、次に定義する GetProvisioningTemplate メソッドと ApplyProvisioningTemplate メソッドによって行われます。

    static void Main(string[] args)
    {
      ConsoleColor defaultForeground = Console.ForegroundColor;
    
      // Collect information
      string templateWebUrl = GetInput("Enter the URL of the template site: ", false, defaultForeground);
      string targetWebUrl = GetInput("Enter the URL of the target site: ", false, defaultForeground);
      string userName = GetInput("Enter your user name:", false, defaultForeground);
      string pwdS = GetInput("Enter your password:", true, defaultForeground);
      SecureString pwd = new SecureString();
      foreach (char c in pwdS.ToCharArray()) pwd.AppendChar(c);
    
      // GET the template from existing site and serialize
      // Serializing the template for later reuse is optional
      ProvisioningTemplate template = GetProvisioningTemplate(defaultForeground, templateWebUrl, userName, pwd);
    
      // APPLY the template to new site from
      ApplyProvisioningTemplate(targetWebUrl, userName, pwd, template);
    
      // Pause and modify the UI to indicate that the operation is complete
      Console.ForegroundColor = ConsoleColor.White;
      Console.WriteLine("We're done. Press Enter to continue.");
      Console.ReadLine();
    }
    
  2. プライベート GetInput メソッドを作成し、これを使用して必要なユーザー資格情報を取得します。

    private static string GetInput(string label, bool isPassword, ConsoleColor defaultForeground)
    {
      Console.ForegroundColor = ConsoleColor.Green;
      Console.WriteLine("{0} : ", label);
      Console.ForegroundColor = defaultForeground;
    
      string value = "";
    
      for (ConsoleKeyInfo keyInfo = Console.ReadKey(true); keyInfo.Key != ConsoleKey.Enter; keyInfo = Console.ReadKey(true))
      {
        if (keyInfo.Key == ConsoleKey.Backspace)
        {
          if (value.Length > 0)
          {
            value = value.Remove(value.Length - 1);
            Console.SetCursorPosition(Console.CursorLeft - 1, Console.CursorTop);
            Console.Write(" ");
            Console.SetCursorPosition(Console.CursorLeft - 1, Console.CursorTop);
          }
        }
        else if (keyInfo.Key != ConsoleKey.Enter)
        {
          if (isPassword)
          {
            Console.Write("*");
          }
          else
          {
            Console.Write(keyInfo.KeyChar);
          }
          value += keyInfo.KeyChar;
        }
      }
      Console.WriteLine("");
    
      return value;
    }
    
  3. プロビジョニング テンプレートのモデルとなるサイトを指します。 1 行のコードを使用してソース サイトで GET を実行しながら、定義した GET メソッドである GetProvisioningTemplate() を確認します。

    private static ProvisioningTemplate GetProvisioningTemplate(ConsoleColor defaultForeground, string webUrl, string userName, SecureString pwd)
    {
      using (var ctx = new ClientContext(webUrl))
      {
        // ctx.Credentials = new NetworkCredentials(userName, pwd);
        ctx.Credentials = new SharePointOnlineCredentials(userName, pwd);
        ctx.RequestTimeout = Timeout.Infinite;
    
        // Just to output the site details
        Web web = ctx.Web;
        ctx.Load(web, w => w.Title);
        ctx.ExecuteQueryRetry();
    
        Console.ForegroundColor = ConsoleColor.White;
        Console.WriteLine("Your site title is:" + ctx.Web.Title);
        Console.ForegroundColor = defaultForeground;
    
        ProvisioningTemplateCreationInformation ptci
                = new ProvisioningTemplateCreationInformation(ctx.Web);
    
        // Create FileSystemConnector to store a temporary copy of the template
        ptci.FileConnector = new FileSystemConnector(@"c:\temp\pnpprovisioningdemo", "");
        ptci.PersistComposedLookFiles = true;
        ptci.ProgressDelegate = delegate(String message, Int32 progress, Int32 total)
        {
            // Only to output progress for console UI
            Console.WriteLine("{0:00}/{1:00} - {2}", progress, total, message);
        };
    
        // Execute actual extraction of the template
        ProvisioningTemplate template = ctx.Web.GetProvisioningTemplate(ptci);
    
        // We can serialize this template to save and reuse it
        // Optional step
        XMLTemplateProvider provider =
                new XMLFileSystemTemplateProvider(@"c:\temp\pnpprovisioningdemo", "");
        provider.SaveAs(template, "PnPProvisioningDemo.xml");
    
        return template;
      }
    }
    

    以前のコード スニペットでは、ProvisioningTemplateCreationInformation 変数 (pcti) も定義しました。 この変数により、テンプレートと共に保存できる成果物に関する情報を格納できます。

  4. ファイル システム コネクター オブジェクトを作成し、別のサイトに適用するプロビジョニング テンプレートの一時的なコピーを格納できるようにします。

    注:

    この手順は省略できます。 XML にプロビジョニング テンプレートをシリアル化する必要はありません。 この段階で、テンプレートは単なる C# コードです。 シリアル化が省略可能であるだけでなく、必要なシリアル化形式を何でも使用できます。

  5. 次の 1 行のコードだけを使用して、プロビジョニング テンプレートの抽出を実行します。

    ProvisioningTemplate template = ctx.Web.GetProvisioningTemplate(ptci);
    
  6. (オプション) プロビジョニング テンプレートのシリアル化されたバージョンを保存して再利用できるようにします。 プロビジョニング テンプレートは任意の形式でシリアル化することができます。 このサンプルでは、PnPProvisioningDemo.xml という名前の XML ファイルにシリアル化しました。 ファイル自体は、ファイル システムの場所に配置された XMLFileSystemTemplateProvider オブジェクトです。

新規または既存のサイトへのプロビジョニング テンプレートの適用

プロビジョニング テンプレートを抽出、保存、永続化したら、次の最後の手順は、そのプロビジョニング テンプレートを新しい SharePoint サイト コレクションに適用することです。これを行うには、ApplyProvisioningTemplate メソッドを使用します。

  1. 対象サイトの資格情報を取得します。

    // ctx.Credentials = new NetworkCredentials(userName, pwd);
    ctx.Credentials = new SharePointOnlineCredentials(userName, pwd);
    ctx.RequestTimeout = Timeout.Infinite;
    
  2. コンパニオン メソッド ProvisioningTemplateApplyingInformation を使用して、ProvisioningTemplateCreationInformation メソッドによって格納されたサイト成果物をキャプチャします。

    ProvisioningTemplateApplyingInformation ptai = new ProvisioningTemplateApplyingInformation();
    ptai.ProgressDelegate = delegate(String message, Int32 progress, Int32 total)
    {
      Console.WriteLine("{0:00}/{1:00} - {2}", progress, total, message);
    };
    
  3. アセットのファイル コネクタへの関連付けを取得します。

    // Associate file connector for assets
    FileSystemConnector connector = new FileSystemConnector(@"c:\temp\pnpprovisioningdemo", "");
    template.Connector = connector;
    
  4. (省略可能) プロビジョニング テンプレートはオブジェクト インスタンスであるため、実行時にサイト アーティファクトをカスタマイズするコードを作成できます。 このインスタンスでは、新しい「contact」リストを追加します。

    // Because the template is actual object, we can modify this using code as needed
    template.Lists.Add(new ListInstance()
    {
      Title = "PnP Sample Contacts",
      Url = "lists/PnPContacts",
      TemplateType = (Int32)ListTemplateType.Contacts,
      EnableAttachments = true
    });
    
  5. 1 行のコードを再び使用して、新しいサイトにプロビジョニング テンプレートを適用します。

    web.ApplyProvisioningTemplate(template, ptai);
    
  6. ApplyProvisioningTemplate() メソッドの実装全体は以下のとおりです。

    private static void ApplyProvisioningTemplate(string targetWebUrl, string userName, SecureString pwd, ProvisioningTemplate template)
    {
      using (var ctx = new ClientContext(targetWebUrl))
      {
        // ctx.Credentials = new NetworkCredentials(userName, pwd);
        ctx.Credentials = new SharePointOnlineCredentials(userName, pwd);
        ctx.RequestTimeout = Timeout.Infinite;
    
        Web web = ctx.Web;
    
        ProvisioningTemplateApplyingInformation ptai = new ProvisioningTemplateApplyingInformation();
        ptai.ProgressDelegate = delegate (String message, Int32 progress, Int32 total)
        {
          Console.WriteLine("{0:00}/{1:00} - {2}", progress, total, message);
        };
    
        // Associate file connector for assets
        FileSystemConnector connector = new FileSystemConnector(@"c:\temp\pnpprovisioningdemo", "");
        template.Connector = connector;
    
        // Because the template is actual object, we can modify this using code as needed
        template.Lists.Add(new ListInstance()
        {
          Title = "PnP Sample Contacts",
          Url = "lists/PnPContacts",
          TemplateType = (Int32)ListTemplateType.Contacts,
          EnableAttachments = true
        });
    
        web.ApplyProvisioningTemplate(template, ptai);
      }
    }
    

関連項目