November, 2013

  • SharePoint 2013 アイテム表示テンプレートを使用して検索結果の表示をカスタマイズする

    こんにちは、SharePoint サポートの佐伯です。
    今回の投稿では、アイテム表示テンプレートを使用して検索結果の表示をカスタマイズする方法についてご紹介します。

    表示テンプレートとは、検索結果で表示する情報やデザインを定義したものです。この表示テンプレートを編集して検索結果に適用することで、検索結果の表示をカスタマイズすることができます。表示テンプレートの概要については、前回の投稿をご参照ください。

    今回は、下の画像のように検索結果のアイテムのタイトルサマリー更新者最終更新日時URL を表示するアイテム表示テンプレートを作成してみましょう。


    アイテム表示テンプレート (*.html) の作成
    それでは実際に、アイテム表示テンプレートを作成してみましょう。既存の表示テンプレートをコピーして作成すると簡単です。 SharePoint 既定のアイテム表示テンプレート “既定のアイテム” をもとに、アイテム表示テンプレートを作成しましょう。
    なお、*.html ファイルは発行インフラストラクチャをアクティブにしている場合のみ作成できます。この投稿では、発行インフラストラクチャをアクティブにしたサイトで *.html ファイルを作成する方法をご紹介します。
    1. [サイトの設定] - [Web デザイナー ギャラリー] - [マスター ページ] をクリックし、マスター ページ ギャラリーを開きます。
    2. [Display Templates]、[Search] の順にフォルダを展開し、Item_Default.html ファイルをダウンロードします。

    3. ダウンロードした Item_Default.html ファイルのファイル名を変更します。ここでは、Item_Custom.html に変更します。
    4. Item_Custom.html ファイルを開き、<body> タグの直後にある <div> の id に、この *.html ファイルのファイル名を記述します。
    <body>
        <div id="Item_Custom">

    5. <title> には表示テンプレートのタイトルを入力します。
    <title>カスタム アイテム</title>

    6. <mso:MasterPageDescription> には表示テンプレートの説明を記述します。
    <mso:MasterPageDescription msdt:dt="string">結果アイテムのタイトル、サマリー、更新者、最終更新日時、URL を表示します。</mso:MasterPageDescription>

    7. 検索結果に表示する管理プロパティのマッピング (タイトル、サマリー、更新者、最終更新日時、URL) を設定します。
    <mso:ManagedPropertyMapping msdt:dt="string">
    'Title':'Title','Path':'Path','EditorOWSUSER':'EditorOWSUSER','LastModifiedTime':'LastModifiedTime',
    'HitHighlightedSummary':'HitHighlightedSummary'
    </mso:ManagedPropertyMapping>


    (補足) 管理プロパティのマッピングを追加する際は、‘<変数名>’:’<管理プロパティ名>’ と記述します。この <変数名> と <管理プロパティ名> は可能な限り同じ名称にすることをおすすめします。
    もし、<変数名> を <管理プロパティ名> と異なるものに指定する際は、本投稿の下部に記載している 補足) アイテムの情報を取得し表示する Javascript コードの記述方法 をご確認ください。

    8. <body> 内に、アイテムのタイトル、サマリー、更新者、最終更新日時、URL を取得する Javascript コードを記述します。
    <!--#_
        //タイトルを取得します。
        var title = ctx.CurrentItem.Title;
        var titleHtml = String.format('<a href="{0}" title="{1}" >{2}</a>', $urlHtmlEncode(ctx.CurrentItem.Path), $htmlEncode(title), $htmlEncode(title));

        //URL を取得します。
        var pathHtml = ctx.CurrentItem.Path;

        //サマリーを取得します。
        var summaryHtml = Srch.U.processHHXML(ctx.CurrentItem.HitHighlightedSummary);

        //最終更新日時を取得します。
        var lastModifiedTime = ctx.CurrentItem.LastModifiedTime;
        var lastModifiedTimeHtml = "最終更新日時 " + lastModifiedTime.getFullYear() + "年" + (lastModifiedTime.getMonth() + 1) + "月" + lastModifiedTime.getDate() +"日";

        //更新者を取得します。
        var editorHtml = "";
        if (!$isEmptyString(ctx.CurrentItem.EditorOWSUSER)){
            var editorIdentifiers = ctx.CurrentItem.EditorOWSUSER.split(" | ");
                 if(!$isNull(editorIdentifiers[1]))
                 {
                     editorHtml = "更新者 " + editorIdentifiers[1];
                 }
        }
    _#-->

    9. 表示するアイテムの情報をタイトル、サマリー、更新者、最終更新日時、URL に変更するため、アイテム表示テンプレート “既定のアイテム” でアイテムの情報を表示していた以下のコードを削除します。
    _#=ctx.RenderBody(ctx)=#_

    10. 手順 8 の Javascript コードの後ろに、アイテムのタイトル、サマリー、更新者、最終更新日時、URL を表示するコードを記述します。
    <h3 class="ms-srch-ellipsis">_#=titleHtml=#_</h3><!-- タイトル -->
    <div class="ms-srch-item-path">_#=pathHtml=#_</div><!-- URL -->
    <div class="ms-srch-item-summary">_#=summaryHtml=#_</div><!-- サマリー -->
    <div>
             <span>_#=lastModifiedTimeHtml=#_</span><!-- 最終更新日時 -->
             <span>_#=editorHtml=#_</span><!-- 更新者-->
    </div>

    手順 8、10 で記載している Javascript コードについては、本投稿の下部に記載している 補足) アイテムの情報を取得し表示する Javascript コードの記述方法 をご参照ください。

    11. Item_Custom.html ファイルを保存します。これでアイテム表示テンプレートの作成は完了です。
    Item_Custom.html ファイルは下記のようになります。
    <html xmlns:mso="urn:schemas-microsoft-com:office:office" xmlns:msdt="uuid:C2F41010-65B3-11d1-A29F-00AA00C14882">
    <head>
    <title>カスタム アイテム</title>

    <!--[if gte mso 9]><xml>
    <mso:CustomDocumentProperties>
    <mso:TemplateHidden msdt:dt="string">0</mso:TemplateHidden>
    <mso:MasterPageDescription msdt:dt="string">結果アイテムのタイトル、サマリー、更新者、最終更新日時、URL を表示します。</mso:MasterPageDescription>
    <mso:ContentTypeId msdt:dt="string">0x0101002039C03B61C64EC4A04F5361F385106603</mso:ContentTypeId>
    <mso:TargetControlType msdt:dt="string">;#SearchResults;#</mso:TargetControlType>
    <mso:HtmlDesignAssociated msdt:dt="string">1</mso:HtmlDesignAssociated>
    <mso:ManagedPropertyMapping msdt:dt="string">
    'Title':'Title','Path':'Path','EditorOWSUSER':'EditorOWSUSER','LastModifiedTime':'LastModifiedTime',
    'HitHighlightedSummary':'HitHighlightedSummary'
    </mso:ManagedPropertyMapping>

    </mso:CustomDocumentProperties>
    </xml><![endif]-->
    </head>
    <body>
        <div id="Item_Custom">
    <!--#_
    if(!$isNull(ctx.CurrentItem) && !$isNull(ctx.ClientControl)){
        var id = ctx.ClientControl.get_nextUniqueId();
        var itemId = id + Srch.U.Ids.item;
             var hoverId = id + Srch.U.Ids.hover;
             var hoverUrl = "~sitecollection/_catalogs/masterpage/Display Templates/Search/Item_Default_HoverPanel.js";
        $setResultItem(itemId, ctx.CurrentItem);
             if(ctx.CurrentItem.IsContainer){
                       ctx.CurrentItem.csr_Icon = Srch.U.getFolderIconUrl();
             }
             ctx.currentItem_ShowHoverPanelCallback = Srch.U.getShowHoverPanelCallback(itemId, hoverId, hoverUrl);
        ctx.currentItem_HideHoverPanelCallback = Srch.U.getHideHoverPanelCallback();
    _#-->

    <!--#_
        //タイトルを取得します。
        var title = ctx.CurrentItem.Title;
        var titleHtml = String.format('<a href="{0}" title="{1}" >{2}</a>', $urlHtmlEncode(ctx.CurrentItem.Path), $htmlEncode(title), $htmlEncode(title));

        //URL を取得します。
        var pathHtml = ctx.CurrentItem.Path;

        //サマリーを取得します。
        var summaryHtml = Srch.U.processHHXML(ctx.CurrentItem.HitHighlightedSummary);

        //最終更新日時を取得します。
        var lastModifiedTime = ctx.CurrentItem.LastModifiedTime;
        var lastModifiedTimeHtml = "最終更新日時 " + lastModifiedTime.getFullYear() + "年" + (lastModifiedTime.getMonth() + 1) + "月" + lastModifiedTime.getDate() +"日";

        //更新者を取得します。
        var editorHtml = "";
        if (!$isEmptyString(ctx.CurrentItem.EditorOWSUSER)){
            var editorIdentifiers = ctx.CurrentItem.EditorOWSUSER.split(" | ");
                 if(!$isNull(editorIdentifiers[1]))
                 {
                     editorHtml = "更新者 " + editorIdentifiers[1];
                 }
        }
    _#-->

    <div id="_#= $htmlEncode(itemId) =#_" name="Item" data-displaytemplate="DefaultItem" class="ms-srch-item" onmouseover="_#= ctx.currentItem_ShowHoverPanelCallback =#_" onmouseout="_#= ctx.currentItem_HideHoverPanelCallback =#_">

             <h3 class="ms-srch-ellipsis">_#=titleHtml=#_</h3><!-- タイトル -->
             <div class="ms-srch-item-path">_#=pathHtml=#_</div><!-- URL -->
             <div class="ms-srch-item-summary">_#=summaryHtml=#_</div><!-- サマリー -->
             <div>
                      <span>_#=lastModifiedTimeHtml=#_</span><!-- 最終更新日時 -->
                      <span>_#=editorHtml=#_</span><!-- 更新者-->
             </div>

        <div id="_#= $htmlEncode(hoverId) =#_" class="ms-srch-hover-outerContainer"></div>
    </div>
    <!--#_
            }
    _#-->
    </div>
    </body>
    </html>

    - 表示テンプレート ファイルのアップロードと適用
    1. 作成した Item_Custom.html ファイルをマスター ページ ギャラリーにアップロードします。
    2. アップロード後のプロパティの編集画面で、アイテム表示テンプレート (*.html) の作成手順 4 ~ 7 で記述した設定が反映されていることを確認し、保存します。


    3. 検索結果 Web パーツを配置したページを開き、ページ右上の [ページの編集] をクリックします。
    4. 検索結果 Web パーツの [Web パーツの編集] をクリックします。
    5. [アイテム表示テンプレート] で、作成した表示テンプレート "カスタム アイテム" を選択します。
    (補足) 今回の投稿では、すべての検索結果の種類に対して、今回作成したアイテム表示テンプレートを適用します。

    6 ページを保存します。
     

    それでは検索ボックスに検索キーワードを入力し、検索をしてみましょう!


    検索結果にアイテム表示テンプレートで編集した内容が反映されました!!


    補足) アイテムの情報を取得し表示する Javascript コードの記述方法
    表示テンプレートでは、Javascript でアイテムの情報を取得し、表示します。まずは以下の記述方法を押さえておきましょう。

    <!--#_ Javascript コード _#--> タグ内に Javascript コードを記述
    _#= =#_ 式の結果を HTML の中に出力する

    <例 1>
    上記の 2 点の記述方法について、以下のサンプル コードを例に説明します。
    以下のコードでは、変数 text に "Sample" という文字列をセットし、変数 text の結果を HTML の中に出力します。

    <!--#_ var text = "Sample"; _#-->
    <div style="color:#4169e1">_#=text=#_</div>

    HTML での出力結果は以下となります。


    <例 2>
    実際にアイテムのプロパティを取得し、出力する方法について見ていきましょう。
    ctx.CurrentItem は検索結果のアイテムのオブジェクトです。このオブジェクトから対象のプロパティを取得します。アイテムのタイトルを取得したい場合は、ctx.CurrentItem.Title または $getItemValue(ctx, "Title") と記述します。

    <!--#_ var title = ctx.CurrentItem.Title; _#-->
    <span>_#=title=#_</span>

    または、

    <!--#_ var title = $getItemValue(ctx, "Title"); _#-->
    <span>_#=title=#_</span>

    HTML での出力結果は以下となります。


    ※なお、ここで取得するプロパティは、<mso:ManagedPropertyMapping> で管理プロパティのマッピングの設定をしておく必要があります。また、管理プロパティのマッピング ‘<変数名>’:’<管理プロパティ名>’ で、<変数名> を <管理プロパティ名> と異なる名称に設定している場合は、$getItemValue(ctx, "<変数名>") でアイテムのプロパティを取得します。
    例)
    <mso:ManagedPropertyMapping>’DisplayTitle’:’Title’</mso:ManagedPropertyMapping>

    <!--#_ var title = $getItemValue(ctx, "DisplayTitle"); _#-->
    <span>_#=title=#_</span>

    今回の投稿は以上です。
    検索結果のカスタマイズの際に、ご参考にしていただけますと幸いです。

  • 最近の SharePoint 関連ニュース (2013年11月26日)

    こんにちは。
    SharePointサポートチームの荒川です。
    今週のアップデートです。

    //先日、マイクロソフト MVP グローバルサミットでシアトルに来られていた日本の SharePoint MVP 2 名の方とお会いする機会がありました。
    お二人とは以前に大阪でコミュニティイベントで登壇させていただいた際に知り合ったのですが、まさかアメリカでお会いすることになるとは思いもしませんでした。
    人の縁って面白いですね!

    最近の SharePoint 関連ニュース (2013年11月26日)



  • SharePoint 2013 検索結果の表示を制御する表示テンプレート

    こんにちは、SharePoint サポートの佐伯です。
    今回の投稿では、検索結果の表示を制御する表示テンプレートについてご紹介します。

    SharePoint 2013 では、検索結果の種類ごとに様々な表示テンプレートを適用することで、検索結果に応じて最適な表示を行うことできます。
    検索結果の種類には、既定でサイトや Web ページ、ドキュメント ライブラリ、リスト アイテムなど各々のコンテンツを対象にしたものが用意されており、表示テンプレートには、検索結果で表示されるアイテムの情報 (タイトルや更新日時、更新者等) や UI (HTML、Javascript、CSS) が定義されています。

    検索結果の表示テンプレート
    検索結果の表示に使用する表示テンプレートには、コントロール表示テンプレート、アイテム表示テンプレート、ホバー パネル表示テンプレート の 3 種類の主要な表示テンプレートがあります。

    [
    コントロール表示テンプレート]
    コントロール表示テンプレートによって、検索結果を表示する全体的な構造が決まります。検索結果全体のレイアウトを制御し、ページング、並べ替え、リンクなど、すべての検索結果に共通の機能も含まれます。
    [アイテム表示テンプレート]
    アイテム表示テンプレートでは、検索結果のアイテムの表示方法が定義され、アイテムごとに適用されます。このテンプレートでは、管理プロパティを使用して、結果に表示させるアイテムの情報を選択することができます。また、合わせてデザインを変更することも可能です。
    [ホバー パネル表示テンプレート]
    ホバー パネル表示テンプレートでは、検索結果のアイテムにオンマウスをした際のアイテムのプレビューが定義されています。このテンプレートも検索結果のアイテムごとに適用されますが、ホバー パネル表示テンプレートはアイテム表示テンプレートに関連付けます。



    - 表示テンプレート ファイルと格納場所
    検索結果で使用する表示テンプレートはマスター ページ ギャラリーに格納されています。
    1. [サイトの設定] – [Web デザイナー ギャラリー] - [マスター ページ] にアクセスします。

    2. [Display Templates] フォルダを展開します。

    3. この [Display Templates] フォルダ内に表示テンプレートが格納されています。ここでは、検索結果 Web パーツの既定の表示テンプレートを例にあげて見ていきましょう。さらに、[Search] フォルダを展開します。
    4. [Display Templates] – [Search] フォルダ内には、検索結果 Web パーツで使用可能な既定の表示テンプレートが格納されています。検索結果は、下の画像で確認できるような *.js ファイルを使用して描画されます。


    なお、発行インフラストラクチャがアクティブの場合は、下の画像のような、*.html ファイルと *.js ファイルの一覧が確認できます。
    ※サイト コレクションの機能 “発行インフラストラクチャ” をアクティブにすると、*.html ファイルが作成されます。この *.html ファイルと *.js ファイルは関連付けられており、*.html ファイルを編集してアップロードすると、変更内容が *.js ファイルに反映されます。(“発行インフラストラクチャ” がアクティブでも非アクティブでも、検索結果に反映されるのは *.js ファイルに記述された内容です)
    表示テンプレートに加えたい変更を *.html ファイルで編集すると、通常の html ファイルと同様に HTML や Javascript、CSS を記述して編集できるので便利です。



    発行インフラストラクチャをアクティブにしている場合は、マスター ページ ギャラリーに新たに *.html ファイルをアップロードして、カスタムの表示テンプレートを追加することが可能です。*.html ファイルをアップロードした際に、*.html ファイルに関連付けられた *.js ファイルは自動で生成されます。


    発行インフラストラクチャが非アクティブの場合、*.html ファイルが存在しないため、*.js ファイルを編集してアップロードします。もしくは、発行インフラストラクチャがアクティブ化されたサイトで *.html ファイルを編集、アップロードして変更内容を反映させた *.js ファイルをコピーして、発行インフラストラクチャがアクティブ化されていないサイトに適用する方法もあります。

    [既定の表示テンプレートのファイル名]
    既定のコントロール表示テンプレートでは、"Control_" から始まります。既定のアイテム表示テンプレートとホバー パネル表示テンプレートでは "Item_"で始まり、末尾に "_HoverPanel" がついているファイルがホバー パネル表示テンプレート、ついていないファイルがアイテム表示テンプレートです。下の画像では、Control_SearchResults.html がコントロール表示テンプレート、Item_Default.html がアイテム表示テンプレート、Item_Default_HoverPanel.html がホバー パネル表示テンプレートです。


    [表示テンプレートのプロパティ]
    さらに、アイテムの [プロパティの編集] 画面より、既定のアイテム表示テンプレートの *.html ファイル (例 : 既定のアイテム) のプロパティを見てみましょう。

    アイテムのプロパティ "コンテンツ タイプ" には、コントロール表示テンプレートではコントロール表示テンプレート、アイテム表示テンプレートまたはホバー パネル表示テンプレートではアイテム表示テンプレートが設定されています。また、検索結果 Web パーツの表示テンプレートでは、”対象コントロールの種類 (検索)” には、SearchResults が設定され、"管理プロパティのマッピング" には、表示テンプレートで表示する管理プロパティのマッピングされています。表示テンプレートとして使用する際は、これらの設定が必要です。
    これらのプロパティの設定は、表示テンプレートの *.html ファイル内に記載された mso:CustomDocumentProperties 要素配下と連携しています。*.html ファイルに設定を記述してアップロードすると、プロパティの設定に反映され、反対に、プロパティの編集画面でプロパティの設定を行うと、*.html ファイルに反映されます。
    <mso:CustomDocumentProperties>
    <mso:TemplateHidden msdt:dt="string">0</mso:TemplateHidden>
    <mso:MasterPageDescription msdt:dt="string">結果アイテムの既定のテンプレートを表示します。</mso:MasterPageDescription>
    <mso:ContentTypeId msdt:dt="string">0x0101002039C03B61C64EC4A04F5361F385106603</mso:ContentTypeId>
    <mso:TargetControlType msdt:dt="string">;#SearchResults;#</mso:TargetControlType>
    <mso:HtmlDesignAssociated msdt:dt="string">1</mso:HtmlDesignAssociated>
    <mso:ManagedPropertyMapping msdt:dt="string">'Title':'Title','Path':'Path','Description':'Description','EditorOWSUSER':'EditorOWSUSER','LastModifiedTime':'LastModifiedTime','CollapsingStatus':'CollapsingStatus','DocId':'DocId','HitHighlightedSummary':'HitHighlightedSummary','HitHighlightedProperties':'HitHighlightedProperties','FileExtension':'FileExtension','ViewsLifeTime':'ViewsLifeTime','ParentLink':'ParentLink','FileType':'FileType','IsContainer':'IsContainer','SecondaryFileExtension':'SecondaryFileExtension','DisplayAuthor':'DisplayAuthor'</mso:ManagedPropertyMapping>
    </mso:CustomDocumentProperties>

    (補足) このマスター ページ ギャラリーにアップロードされた表示テンプレートは [サイトの設定] – [外観] – [デザイン マネージャー] の [5. 表示テンプレートの編集] からも参照することができます。アイテムの一覧から、表示テンプレートのタイトルとファイル名が確認できるので、表示テンプレートの対象のファイルを探したい場合はこちらのページで確認すると便利です。例えば、“おすすめコンテンツ アイテム” という表示テンプレートは Item_BestBet (*.html、*.js)であることが分かります。


    ) 検索結果 Web
    パーツで表示テンプレートを設定する
    検索結果 Web パーツを例にして、検索結果の表示に使用する表示テンプレートの設定方法をみていきましょう。表示テンプレートの設定は、[Web パーツの編集] で行います。
    <コントロール表示テンプレート>
     [結果コントロール表示テンプレート] 項目のプルダウンより、使用するコントロール表示テンプレートを選択します。

    <アイテム表示テンプレート>
    アイテム表示テンプレートでは、[検索結果の種類を使用したアイテムの表示] または [単一のテンプレートを使用してアイテムを表示する] のどちらの方法で検索結果を表示するかを設定します。
    [検索結果の種類を使用したアイテムの表示] を選択すると、検索結果の種類 (例えば、サイトやドキュメント ライブラリ、リスト アイテム等) に合わせて適用する表示テンプレートを変えることができます。

    検索結果の種類と表示テンプレートの組み合わせは、上の画像の [検索結果の種類] リンクから設定ページにアクセスすることが可能です。

    一つの表示テンプレートをすべての検索結果の種類に適用する場合は [単一のテンプレートを使用してアイテムを表示する] を設定します。以下の画像のプルダウンより、適用する表示テンプレートを選択します。なお、ホバー パネル表示テンプレートはアイテム表示テンプレートのファイルに関連付けられているため、アイテム表示テンプレートのみを設定します。



    今回の投稿では、SharePoint 2013 検索結果で使用する表示テンプレートについて概要をご紹介いたしましたが、検索結果の種類の追加や表示テンプレートのカスタマイズ、また検索結果の種類に合わせた表示テンプレートの関連付けにより、お客様のニーズに合わせて柔軟に検索結果をカスタマイズすることができます。
    表示テンプレートの詳細なカスタマイズ方法については、今後の投稿で随時ご紹介してまいります。

     

  • 最近の SharePoint 関連ニュース (2013年11月19日)

    こんにちは。
    SharePointサポートチームの荒川です。
    今週のアップデートです。

    //先日健康診断を受けたのですが、コレステロールの値がちょっと高いねということでお医者さんに呼び出しを食らってしまいました。。
    なにぶん、これ系でひかかったのが生まれて初めての経験でしたのでショックを隠し切れないのですが、思い返せばここ数か月、低糖質ダイエットと称して殆ど肉しか食べてなかったので、食生活が原因であることは間違いありません。
    やっぱり何でもバランスよく食べることが大切なんですね…。

    最近の SharePoint 関連ニュース (2013年11月19日)

    • Yammer is expanding to all Office 365 Enterprise customers
      Yammer Enterprise がすべての Office 365 Enterprise プランに含まれるようになります。
      詳細についてはこちらの記事をご参照ください。
    • SharePoint 2010 - Why lots of web applications will hurt you
      大量の Web アプリケーションを作成することによる弊害と、ホスト名付きサイトコレクションの利点について解説されています。
    • Scenarios where User Profile Synchronization Service (UPSS) is not designed to work
      SPS2010 における User Profile Synchronization Service の制限について解説されています。
      • User Profile Synchronization Service はスタンドアロンインストール環境で利用できません。
      • SQL 認証を使用して構成された環境で User Profile Synchronization Service を使用するには2012年10月CUを適用する必要があります。
      • SharePoint サーバー上に Microsoft Forefront Identity Manager クライアントの製品版が個別にインストールされている場合は User Profile Synchronization Service が正しく動作しません。



  • 最近の SharePoint 関連ニュース (2013年11月12日)

    こんにちは。
    SharePointサポートチームの荒川です。
    今週のアップデートです。

    //先日けんもりさんの Facebook をふと見ると、巨大な大根の写真がアップされていました。写真についてのコメントでは「ネタ切れなので発想の転換をする」と書かれていたのですが、いったい彼は大根で何を訴えたかったのでしょうか。。謎は深まるばかりです。

    最近の SharePoint 関連ニュース (2013年11月12日)



  • Web パーツのエラーでページが表示できない場合のトラブルシューティング 2

    対象製品:
    SharePoint Server 2010
    SharePoint Server 2013
     
    関連記事:
     
    こんにちは。SharePoint サポートチームの多田信吾です。
    前回「Web パーツのエラーでページが表示できない場合のトラブルシューティング」の記事で、Web パーツのエラーでページが表示できないパターンを 4 つ紹介しました。今回は 5 つ目のパターンを紹介します。
     
    要因 5. リストの列が 67 ~ 70 列を超えている
    ============================
    SharePoint Designer XSLT の記述形式を使用してデザインをカスタマイズしており、かつリストの列が 67 ~ 70 列を超えている場合、以下のエラーメッセージが表示されます。
     
    エラーメッセージ
    ^^^^^^^^^^^
    この Web パーツを表示できません。この問題のトラブルシューティングを行うには、Microsoft SharePoint Foundation と互換性のある Microsoft SharePoint Designer などの HTML エディターでこの Web ページを開いてください。問題が解決しない場合は、Web サーバーの管理者に問い合わせてください。
     
    リストの各列の定義はひとつの xsl:template 要素内に含まれております。アイテムの新規作成ページや変更ページを表示する際に、ひとつのスタックに xsl:template 要素内の列定義が積まれるため、列数が多すぎると StackOverflowException が発生します。診断ログには以下のメッセージが記録されます。
     
    --- 診断ログ ---
    Error while executing web part: System.StackOverflowException: この操作によってスタック オーバーフローが発生しました。    
    場所 Microsoft.Xslt.NativeMethod.CheckForSufficientStack()    
    場所 <xsl:template name="dvt_1.rowedit">(XmlQueryRuntime , XPathNavigator , Double , Double )    
    場所 <xsl:template name="dvt_1.body">(XmlQueryRuntime , XPathNavigator , Double , IList`1 )    
    場所 <xsl:template name="dvt_1">(XmlQueryRuntime , XPathNavigator , Double )    
    場所 Root(XmlQueryRuntime )    
    場所 System.Xml.Xsl.XmlILCommand.Execute(Object defaultDocument, XmlResolver dataSources, XsltArgumentList argumentList, XmlWriter writer, Boolean closeWriter)    
    場所 System.Xml.Xsl.XmlILCommand.Execute(IXPathNavigable contextDocument, XmlResolver dataSources, XsltArgumentList argumentList, XmlWriter results)    
    場所 System.Xml.Xsl.XslCompiledTransform.Transform(IXPathNavigable input, XsltArgumentList arguments, XmlWriter results)    
    場所 Microsoft.SharePoint.WebPartPages.DataFormWebPart.ExecuteTransform(XslCompiledTransform xslCompiledTransform, XsltArgumentList xmlArguments, Boolean bDeferExecuteTransform)    
    場所 Microsoft.SharePoint.WebPartPages.DataFormWebPart.PrepareAndPerformTransform(Boolean bDeferExecuteTransform)
    ----------------
     
    対処策
    ^^^^
    本来はパフォーマンスを考慮し、可能な限り 67 列を超えないリスト設計を推奨いたしますが、要件により 67 列以上を使用する場合は、以下の方法にて各列の定義を分散して xsl:template要素に配置することでエラーメッセージを防ぐことが可能です。
     
    1. SharePoint Designer にて該当のカスタムフォームを開きます。
    2. 以下の部分を探します。
     
    <xsl:call-template name="dvt_1.rowedit"/>
     
    3. 上記の記述を以下のように 3 つから 5 つぐらいコピー & ペーストし、以下のように name 属性を変更します。
     
    <xsl:call-template name="dvt_1.rowedit"/> <xsl:call-template name="dvt_1.rowedit2"/> <xsl:call-template name="dvt_1.rowedit3"/> <xsl:call-template name="dvt_1.rowedit4"/> <xsl:call-template name="dvt_1.rowedit5"/>
     
    4. 以下の部分を探します。以下の xsl:template 要素内に列の定義が記載されております。
     
    <xsl:template name="dvt_1.rowedit">
     
    5. xsl:template 要素内の列の定義を除いた外側の部分のみを 3 つから 5 つぐらいコピー & ペーストします。
     
    xsl:template要素例
    ---
    <xsl:template name="dvt_1.rowedit">
      <xsl:param name="Pos" select="position()"/>
      <tr>
       <td>
        <table border="0" cellspacing="0" width="100%">
     
        </table>
       </td>
      </tr>
    </xsl:template>
    ---
     
    6. コピー & ペーストした各 xsl:template 要素の name 属性を、手順 3 で作成した call-template 要素と整合が合うように、それぞれ以下のように変更します。
     
    ---
    <xsl:template name="dvt_1.rowedit2">
      <xsl:param name="Pos" select="position()"/>
      <tr>
       <td>
        <table border="0" cellspacing="0" width="100%">
     
        </table>
       </td>
      </tr>
    </xsl:template>
     
    <xsl:template name="dvt_1.rowedit3">
      <xsl:param name="Pos" select="position()"/>
      <tr>
       <td>
        <table border="0" cellspacing="0" width="100%">
     
        </table>
       </td>
      </tr>
    </xsl:template>
     
    ---
     
    7. もとの xsl:template 要素内の列の定義をコピー & ペーストした各 xsl:template 要素に分散します。例えば 1 番から 100 番までのテキストボックス列があった場合は、以下のように分散します。
     
    <xsl:template name="dvt_1.rowedit"> の要素内 : 1 番から 20 番までのテキストボックス列の定義
    <xsl:template name="dvt_1.rowedit2"> の要素内 : 21 番から 40 番までのテキストボックス列の定義
    <xsl:template name="dvt_1.rowedit3"> の要素内 : 41 番から 60 番までのテキストボックス列の定義
    <xsl:template name="dvt_1.rowedit4"> の要素内 : 61 番から 80 番までのテキストボックス列の定義
    <xsl:template name="dvt_1.rowedit5"> の要素内 : 81 番から 100 番までのテキストボックス列の定義
     
    ひとつの列の定義は以下のような <tr> 要素によって定義されております。コピー & ペーストした各 xsl:template 要素への分散はこの <tr> 要素単位で行います。
     
    テキストボックス列の定義例
    -----
    <tr>
    <td width="25%" class="ms-vb">
       <b>84:</b>
    </td>
    <td width="75%" class="ms-vb">
       <SharePoint:FormField runat="server" id="ff352{$Pos}" ControlMode="New" FieldName="_x0038_4" __designer:bind="{ddwrt:DataBind('i',concat('ff352',$Pos),'Value','ValueChanged','ID',ddwrt:EscapeDelims(string(@ID)),'@_x0038_4')}" /> 
    <SharePoint:FieldDescription runat="server" id="ff160description192{$Pos}" FieldName="_x0038_4" ControlMode="Edit" />
    </td>
    </tr>
    -----
     
    補足 : 列の定義が正しく認識されない場合は SharePoint Designer のデザインビューにて列がエラーとして表示されます。この状態で保存した場合はカスタムフォームが表示できない場合があります。
     
    8. カスタムフォームを保存し、カスタムフォームにて 70 列以上の列が正常に表示されることを確認します。
     

    補足情報

    ^^^^

    上記の対処策を実施した場合においても、前回のブログ記事にて紹介した「要因 4. XSLT の初回レンダリング時にコンパイルが失敗する」が発生する可能性があります。このため、パフォーマンスを考慮する意味でも列の数を 67 よりも少なくすることを推奨いたします。

    しかしながら、列の数を 67 列以上表示する場合は、Visual Studio にてリストを表示する Web パーツを作成することで、XSLT を使用せずにデータを表示できるため、要因 4 の発生を防ぐことができます。


    - 参考資料
    タイトル : SharePoint 2010 の視覚的 Web パーツを作成する
    アドレス : http://msdn.microsoft.com/ja-jp/library/office/ff597539(v=office.14).aspx

    タイトル : SharePoint 2010 コントロールを使用して視覚的 Web パーツを作成する
    アドレス : http://msdn.microsoft.com/ja-jp/library/office/ff728094(v=office.14).aspx

    タイトル : 方法: SharePoint Web パーツを作成する
    アドレス : http://msdn.microsoft.com/ja-jp/library/vstudio/ee231519(v=vs.110).aspx

    タイトル : 10 行でズバリ!! SharePoint のサンドボックス ソリューションの作成 (C#)
    アドレス : https://code.msdn.microsoft.com/office/10-SharePoint-C-f18f22a6

    タイトル : LINQ を使用して SharePoint 2010 Web パーツでデータにアクセスする
    アドレス : http://msdn.microsoft.com/ja-jp/library/office/ff742312(v=office.14).aspx

  • サイト コレクションのユーザー情報へのユーザー プロファイル同期の仕組みについて (まとめ)

    皆さんこんにちは。
    SharePoint サポート チームの荒川です。

    User Profile Service アプリケーションとサイト コレクションの同期についてはこれまでに何度か記事で取り上げてきましたが、今回は様々な技術情報サイト (マイクロソフト公式サポート技術情報や TechNet、MSDN ブログの過去の記事など) に分散されている情報を集約した形でまとめ記事を作成してみました。
    情報量が大変多いため、一度に全部読むことは難しいかもしれませんが、目次のリンクを活用いただくことでページ内を簡単にジャンプできるようにしていますので、包括的な情報源としてご活用ください。

     

    目的
    この資料では、User Profile Service アプリケーションとサイト コレクションの間でユーザー プロファイルが同期される仕組みと、それに関連するトラブルシューティングの方法について解説します。

     

    免責事項
    本投稿内容については SharePoint 製品サポート チームにおいてレビュー済みの内容となりますが、マイクロソフトの公式文書ではありませんのでご了承ください。
    本投稿内容は今後定期的に最新の情報を反映するようにメンテナンスしていく予定です。そのため、新たな情報が得られた際には適宜更新される可能性があります。

     

    対象製品
    本資料は、SharePoint Server 2013 を対象にしていますが、SharePoint Server 2010 および Office SharePoint Server 2007 についても一部同様にご参照いただけます。

     

    目次

     

    動作の解説
    このセクションでは User Profile Service アプリケーションとサイト コレクションの間でユーザー プロファイルが同期される仕組みについて解説します。

     

    サイト コレクションのユーザー情報について
    サイト コレクションのユーザー情報とは、主に SharePoint サイト上におけるユーザーの表示名などのユーザー情報に利用される情報を指します。
    サイト コレクションのユーザー情報が利用される個所は主に以下となります。

    • ページ右上に表示されるユーザーの表示名
    • アイテムや投稿の「作成者」として表示されるユーザーの表示名
    • 通知の設定時に参照される電子メールアドレス

    <目次に戻る>

     

    サイト コレクションのユーザー情報とユーザー プロファイルの関係
    サイト コレクションのユーザー情報は、ユーザー プロファイルのユーザー情報とは独立した形でサイト コレクション内に保存されます。したがって、ユーザー プロファイルのユーザー情報とサイト コレクションのユーザー情報はそれぞれ異なるものとして扱われます。

    〔ユーザー プロファイルのユーザー情報〕≠〔サイト コレクションのユーザー情報〕

    詳細については後述の「ユーザープロファイルの情報がサイト コレクションのユーザー情報に自動的に反映される仕組み」セクションで詳しく解説しますが、AD 上でユーザー情報を更新した後、User Profile Service アプリケーションで同期を行いユーザー プロファイルのユーザー情報を更新したとしても、直ぐにサイト コレクションのユーザー情報に反映されるわけではありません。

    <目次に戻る>

     

    サイト コレクションのユーザー情報の確認方法と編集方法
    サイト コレクションのユーザー情報の確認方法と編集方法は、サイト コレクションが User Profile Service アプリケーションと関連付けられているかどうかによって変わります。
    サイト コレクションが含まれる Web アプリケーションが User Profile Service アプリケーションと関連付けられていない環境または、SharePoint Foundation では、サイト コレクションのユーザー情報はユーザーが自分で編集して管理します。
    ユーザーは自身の個人用設定���ら、サイト コレクションのユーザー情報ページ (<サイト コレクション>/_layouts/15/userdisp.aspx) にアクセスしてユーザー情報の確認と編集ができます。

    SharePoint Server で User Profile Service アプリケーションが構成されていた場合は、サイト コレクションのユーザー情報がユーザー プロファイルの情報から管理タイマージョブにより自動同期されるため、ユーザーが自分でサイト コレクションのユーザー情報を管理することはできません。ユーザーは自身のユーザー プロファイルページ (<個人用サイトのホスト>/Person.aspx) にアクセスしてユーザー プロファイル情報の確認と、管理者によって許可されているプロパティの編集ができます。ユーザー プロファイルの情報は定期的に実行される管理タイマー ジョブによってサイト コレクションのユーザー情報に反映されます。

     

    なお、過去に一度でも User Profile Service アプリケーションに関連付けてプロファイルの同期対象となったサイト コレクションでは、後から User Profile Service アプリケーションの関連付けを解除した場合であってもサイトのユーザー情報をユーザー インターフェイス上から変更することができなくなります。この場合、サイト コレクションのユーザー情報ページ (<サイト コレクション>/_layouts/15/userdisp.aspx) にアクセスできるようにはなりますが、アイテムの編集をクリックしてもプロパティを編集できません。

    サイト コレクションの管理者は「<サイト コレクションの URL>/_catalogs/users」または「<サイト コレクションの URL>/_layouts/15/people.aspx?MembershipGroupId=0」に直接アクセスすることで、サイト コレクションに含まれるユーザーの一覧 (ユーザー情報リスト) を確認し、必要に応じてサイト コレクションのユーザー情報を管理できます。

    SharePoint Foundation ではユーザー情報リストの一覧から任意のユーザー名をクリックすることで、各ユーザーのサイト コレクションのユーザー情報の編集ページ (<サイト コレクション>/_layouts/15/userdisp.aspx) にジャンプして、ユーザー情報を編集できます。

    SharePoint Server では、ユーザー情報リストの一覧からユーザー名をクリックした際の動作がユーザー プロファイルの有無により異なります。対象のユーザーのユーザー プロファイルが存在する場合には、ユーザー名をクリックした際にユーザーのプロファイル ページ (<個人用サイトのホスト>/Person.aspx) にジャンプします。対象のユーザーのユーザー プロファイルが存在しない場合 (サイトに権限を登録した直後や User Profile Service アプリケーションが存在しない場合など) には、ユーザー名をクリックした際に SharePoint Foundation と同様にサイト コレクションのユーザー情報の編集ページ (<サイト コレクション>/_layouts/15/userdisp.aspx) にジャンプしますが、Web アプリケーションが User Profile Service アプリケーションに関連付けられており、過去にサイト コレクションでプロファイルの同期が実行されたことがある場合にはアイテムの編集はできません。

    サイト コレクションの管理者は以下のPowerShell スクリプトを使用することで、User Profile Service アプリケーションの関連付けの有無にかかわらず、サイト コレクションのユーザー情報を直接参照および編集できます。

    (サンプル コード)

    #サイト コレクションのユーザー オブジェクトを取得します。
    $username = "i:0#.w|Domain\UserName" #クラシック認証の場合は Domain\UserName
    $siteurl = "http://URLofYourSite"
    $user = Get-SPUser -Identity $username -Web $siteurl

    #ユーザーの表示名と電子メールアドレスを確認するには以下のコマンドを実行します。
    $user.Displayname, $user.Email

    #ユーザーの電子メールアドレスと表示名を AD から取得して同期するには以下のコマンドを実行します。
    Set-SPUser –Identity $user -SyncFromAD

    #ユーザーの電子メールアドレスを明示的に指定して変更するには以下のコマンドを実行します。
    $user.Email = "NewAddress@contoso.local"
    $user.Update()

    #ユーザーの表示名を明示的に指定して変更するには以下のコマンドを実行します。
    $user.DisplayName = "NewDisplayName"
    $user.Update()

    #以下のコマンドではすべてのサイト コレクションのユーザー情報を更新します。
    $title = "NewTitle"
    $emailAddress = "NewEmail@contoso.local"
    Get-SPSite -Limit all | % {$user = $_.OpenWeb().SiteUsers[$username]; if ($user -ne $null) {$user.DisplayName=$title; $user.Email=$emailAddress; $user.Update()}}

    <目次に戻る>

     

    User Profile Service アプリケーションにインポートされたユーザー プロファイルの情報の確認方法と編集方法
    User Profile Service アプリケーションにインポートされたユーザー プロファイルの情報は以下の方法で確認および編集できます。

    (手順) ユーザーが User Profile Service アプリケーションにインポートされたユーザー プロファイルの情報を確認および編集する方法

    1. サイトにアクセスして右上のユーザー名をクリックし、[プロファイル] をクリックしてユーザー プロファイル ページに移動します。
    2. [プロファイルの編集] をクリックします。
    3. 詳細の編集ページでプロファイルの情報を確認します。必要に応じて管理者により編集が許可されたユーザー プロファイルの情報を編集して保存します。

    (手順) 管理者が User Profile Service アプリケーションにインポートされたユーザー プロファイルの情報を確認および編集する方法

    1. サーバーの全体管理サイトにアクセスします。
    2. [アプリケーション構成の管理] セクションの [サービス アプリケーションの管理] をクリックします。
    3. サービス アプリケーションの一覧から User Profile Service アプリケーションの名前をクリックして User Profile Service アプリケーションの管理サイトを開きます。
    4. [ユーザー プロファイルの管理] をクリックします。
    5. [プロファイルの検索] ボックスに対象のアカウント名を入力して [検索] ボタンをクリックします。
    6. 検索結果に表示されたアカウント名を右クリックして [個人用プロファイルの編集] をクリックします。
    7. ユーザー プロファイルの編集ページでプロファイルの情報を確認します。必要に応じて任意のユーザー プロファイルの情報を編集して保存します。

    また、以下の PowerShell スクリプトではユーザー プロファイルにインポートされたユーザー情報をテキスト ファイルに出力して確認できます。

    (サンプル コード) GetUserProfileData.ps1

    #この PowerShell スクリプトではユーザー プロファイルにインポートされたユーザー情報をテキスト ファイルに出力して確認できます。
    #使用例:GetUserProfileData.ps1 -siteurl "http://URLofYourSite" -username "Domain\UserName"
    param($siteurl,$username)
    $site = Get-SPSite($siteurl);
    $ss = Get-SPServiceContext($site);
    $upm = new-object Microsoft.Office.Server.UserProfiles.UserProfileManager($ss);
    Write-Output "AccountName,DisplayName,Department,Email,JobTitle";
    Write-Output " -------------------------------------------------";
    $output = "";
    try
    {
       $u = $upm.GetUserProfile($username);
       if ($u["AccountName"].Value -ne $null){$output = $output + $u["AccountName"].ToString() + ",";}else{$output = $output + "`"`",";}
       if ($u["PreferredName"].Value -ne $null){$output = $output + $u["PreferredName"].ToString() + ",";}else{$output = $output + "`"`",";}
       if ($u["Department"].Value -ne $null){$output = $output + $u["Department"].ToString() + ",";}else{$output = $output + "`"`",";}
       if ($u["WorkEmail"].Value -ne $null){$output = $output + $u["WorkEmail"].ToString()+ ",";}else{$output = $output + "`"`",";}
       if ($u["SPS-JobTitle"].Value -ne $null){$output = $output + $u["SPS-JobTitle"].ToString();}else{$output = $output + "`"`"";}
       Write-Output $output;
    }
    catch { }

    <目次に戻る>

     

    サイト コレクションのユーザー情報が登録されるタイミング
    サイト コレクションのユーザー情報が登録されるタイミングは次のとおりです。

    • サイト管理者によりサイト コレクション内のいずれかのコンテンツ (サイト、リスト、ライブラリ、アイテム) または SharePoint グループに対して、Active Directory グループを介さずに直接権限を付与したタイミング
    • サイト コレクション内のいずれかのコンテンツ (サイト、リスト、ライブラリ、アイテム) または SharePoint グループに対して、Active Directory グループを介して権限登録されたユーザーが初めてコンテンツにアクセスしたタイミング

    この時、その時点でのユーザーの表示名や電子メールアドレス、役職や部署などの情報が LDAP クエリを介して取得され、自動的にサイト コレクションのユーザー情報に登録されます。

    <目次に戻る>

     

    ユーザー プロファイルの情報が登録されるタイミング
    ユーザー プロファイルのユーザー情報が登録されるタイミングは次のとおりです。

    • User Profile Service アプリケーションで外部ソースからプロファイルのインポート (同期) を行った
    • 管理者が User Profile Service アプリケーションの管理ページまたは SharePoint オブジェクト モデルを使用して明示的にユーザー プロファイルを作成した
    • ユーザーがサイトに初めてアクセスした
    • ユーザーが自身の個人用プロファイル ページを開いた
    • ユーザーが自身の個人用サイトにアクセスした

    <目次に戻る>

     

    ユーザー プロファイルの情報がサイト コレクションのユーザー情報に自動的に反映される仕組み
    SharePoint Server では、サイト コレクションのユーザー情報が定期的にユーザー プロファイルの情報と同期されます。
    Active Directory (AD) で更新されたユーザーの属性情報は、User Profile Service アプリケーションによって SharePoint のユーザー プロファイル情報と同期され、SharePoint のユーザー プロファイル情報はタ���マー サービスによって各サイト コレクションのユーザー情報と同期されます。

    〔Active Directory〕<=>〔User Profile Service Application〕<=>〔Site Collection〕

    したがって、AD の情報をサイト コレクションのユーザー情報に反映させるには、予め User Profile Service アプリケーションに AD の情報を同期しておく必要があります。

    <目次に戻る>

     

    プロファイル同期に関連するタイマー ジョブ
    プロファイル同期に関する主なタイマー ジョブは以下の3つです。

    • User Profile Service Application – ユーザー プロファイルの増分同期
      User Profile Service アプリケーションの同期スケジュールに直結しており、既定では毎日 1:00 に実行されるよう構成されます。
    • User Profile Service Application – ユーザー プロファイルから SharePoint へのクイック同期
      SharePoint サイト コレクションに追加した直後のユーザーに対して、User Profile Service アプリケーションにインポートされたプロファイル情報を適用するために定期的に実行されるジョブで、既定では 5 分おきに実行されるよう構成されます。
    • User Profile Service Application – ユーザー プロファイルから SharePoint への完全同期
      SharePoint サイト コレクションに登録されているすべてのアクティブ ユーザーに対して、User Profile Service アプリケーションにインポートされたプロファイル情報を適用するために定期的に実行されるジョブで、既定では 1 時間おきに実行されるよう構成されます。

    パフォーマンスの観点から、クイック同期は SharePoint サイト コレクションに追加した直後のユーザーに対して最初の 1 回のみ実行されます。
    各タイマー ジョブの設定内容はサーバーの全体管理サイトで [監視] セクションの [ジョブ定義の確認] から変更できます。

    <目次に戻る>

     

    ユーザー プロファイルから SharePoint への同期対象になるユーザーと同期対象にならないユーザー
    既定では、サイト コレクションにおいて「アクティブ ユーザー」と認識されているユーザーのみがユーザー プロファイルから SharePoint への同期対象となります。
    個人用サイトにおいては、ユーザー自身がサイト コレクションの所有者となるため、ユーザーは必ずアクティブ ユーザーになります。それ以外のサイトにおいて、ユーザーがサイト コレクションの「アクティブ ユーザー」と認識されるためには、以下のいずれかの条件を満たす必要があります。

    • サイト コレクション内のいずれかのコンテンツ (サイト、リスト、ライブラリ、アイテム) または SharePoint グループに対して、Active Directory グループを介さずに直接権限を付与されている。
      または
    • サイト コレクション内のいずれかのコンテンツ (サイト、リスト、ライブラリ、アイテム) または SharePoint グループに対して、Active Directory グループを介して「投稿」権限以上の権限を登録されており、以下のいずれかの操作を行ったことがある。
      • ライブラリのドキュメントをアップロードまたは更新する
      • リストのアイテムを作成または更新する
      • ページを作成または編集する
      • ニュースフィードやディスカッション掲示板に投稿する
      • Web パーツ ページにアクセスして個人用ビューを保存する
      • サイトをフォローする

    パフォーマンスの観点より、既定では Active Directory グループを介してサイトに権限を登録されるユーザーのうち、サイトに投稿を行わないユーザー (非アクティブ ユーザー) に対してはユーザー プロファイルの情報が同期されません。
    つまり、Active Directory グループを介してサイトに権限を登録するユーザーをプロファイルの同期対象にするには、最低限投稿権限以上の権限が必要となります。

    また、毎回すべてのユーザー プロファイルが同期の対象となるわけではなく、過去に同期が実行された後、変更が発生したユーザー プロファイルのみが同期の対象となります。User Profile Service アプリケーションのプロファイル データベースでは、ユーザー プロファイルの変更履歴を管理しており、過去に変更された内容が変更ログ (UserProfileEventLog テーブル) として記録されています。ユーザー プロファイルから SharePoint への同期タイマー ジョブが実行される際には、ユーザー プロファイルの変更ログの最終変更日時と、コンテンツ データベース単位で管理している同期情報テーブル (SiteSynch テーブル) の最終更新日時を比較して、前回同期実行日時以降に変更が加えられたユーザー プロファイル情報のみをサイトに同期します。たとえば、User Profile Service アプリケーションにおいて AD から完全同期を実行した後に一度ユーザー プロファイルから SharePoint への同期タイマー ジョブが実行された後、続けて AD から完全同期を実行したとしても、AD 上で特に変更が無ければプロファイルの変更ログにはエントリが記録されませんので、次回の同期タイマー ジョブの実行時にはサイト コレクションに対する同期は発生しません。

    <目次に戻る>

     

    非アクティブ ユーザーを同期対象にする方法
    Active Directory グループを介してサイトに権限を登録されるユーザーのうち、サイトに投稿を行わないユーザー (非アクティブ ユーザー) をプロファイルの同期対象とすることも可能です。
    非アクティブ ユーザーをプロファイルの同期対象とするには、以下の操作を実施する必要があります。

    (手順) 非アクティブ ユーザーをプロファイルの同期対象とする方法

    1. ファームのいずれか1台の SharePoint サーバーにおいて、SharePoint 2013 管理シェルを管理者権限で起動します。
    2. 以下のコマンドを実行します。
      stsadm -o sync -IgnoreIsActive 1
      Stsadm -o sync -DeleteOldDatabases 0
    3. ユーザー プロファイルから SharePoint への完全同期タイマー ジョブが実行されるまで待ちます。(急ぎの場合はタイマー ジョブを手動で実行しても構いません。)

    本操作を行うと、ユーザー プロファイルが存在し、サイト コレクションのユーザー情報に登録されたすべてのユーザーがプロファイルの同期対象になります。ユーザー数が多い (数千から数万単位の) 環境ではパフォーマンスの問題を引き起こす可能性がありますので、初回の同期はオフピークの時間帯に行うことをお勧めします。

    (補足)

    • 「stsadm -o sync -IgnoreIsActive 1」コマンドでは、非アクティブ ユーザーに対してもアクティブ ユーザーと同様にプロファイル同期の対象とするためのフラグを設定します。
    • 「Stsadm -o sync -DeleteOldDatabases 0」コマンドは、データベースの古い同期情報を削除して、次回の完全同期の際にすべてのユーザーを対象としてプロファイル同期を行うために実行します。本コマンドを実行しない場合、前回完全同期が行われた後に変更されたユーザー プロファイルのみが同期の対象となり、それ以前の変更がサイトのユーザー情報に反映されません。本コマンドは「stsadm -o sync -IgnoreIsActive 1」コマンドの実行後、最初の同期の際に 1 回のみ実行すれば、以後同じ操作は不要です。
    • IgnoreIsActive コマンドは MOSS2007 および SPS2010 でもご利用いただけますが、以下の注意点があります。
      • MOSS2007 の 2010 年 4 月の CU 適用前の環境ではサイトに新しいユーザーを登録する度に「Stsadm -o sync -DeleteOldDatabases 0」コマンドを実行する必要があります。
      • SPS2010 RTM (初期リリース版) では、製品の問題により IgnoreIsActive コマンドが動作しません。この問題は 2010 年 10 月の CU で修正されています。

    <目次に戻る>

     

    サイト コレクションのユーザー情報にユーザー プロファイルの情報が同期されない場合のトラブルシューティング
    以下に、サイト コレクションのユーザー情報にユーザー プロファイルの情報が同期されない場合のトラブルシューティングについて記載します。

    最初に確認すること
    SharePoint Server においてサイト コレクションのユーザー情報にユーザー プロファイルの情報が同期されない場合は、最初に以下の内容を確認します。

    • User Profile Service アプリケーションに正しくプロファイル情報がインポートされているか
    • 対象のユーザーはアクティブ ユーザーか

    User Profile Service アプリケーションに正しくプロファイル情報がインポートされているかについては、先述の「User Profile Service アプリケーションにインポートされたユーザー プロファイルの情報の確認方法と編集方法」をご参照ください。

    対象のユーザーがアクティブ ユーザーかどうか調べるには、コンテンツ データベースの UserInfo テーブルを参照する必要があります。
    コンテンツ データベースの UserInfo テーブルに対するクエリ結果をテキスト ファイルに出力する PowerShell のサンプル コードを以下に記載します。SQL Server の管理権限がある場合は、SQL Server Management Studio から直接データベースに対してクエリを実行しても構いません。

    (サンプル コード) コンテンツ データベースの UserInfo テーブルに対するクエリ結果をテキスト ファイルに出力する PowerShell のサンプル コード

    $query = "SELECT tp_SiteID, tp_ID, tp_IsActive, tp_Login, tp_Title FROM UserInfo WITH(NOLOCK)"

    #以下の接続文字列の Server および Database パラメータの値をご利用の環境に合わせて適宜変更します。
    $connectionstring = "Server=ServerName;Database=WSS_Content;Trusted_Connection=True;"

    $connection = New-Object -TypeName System.Data.SqlClient.SqlConnection
    $connection.ConnectionString = $connectionstring
    $command = $connection.CreateCommand()
    $command.CommandText = $query
    $adapter = New-Object -TypeName System.Data.SqlClient.SqlDataAdapter $command
    $dataset = New-Object -TypeName System.Data.DataSet
    $adapter.Fill($dataset)

    #ファイルの出力先を適宜変更します。
    $dataset.Tables[0] | ft | Out-File C:\out.txt -Width 250

    tp_IsActive の値が 1 になっているユーザーはアクティブ ユーザーです。tp_IsActive の値が 0 になっているユーザーは非アクティブ ユーザーです。
    tp_SiteID の値がサイト コレクションの ID を示します。tp_SiteID の値からサイト コレクションの URL を調べるには以下の PowerShell コマンドを実行します。

    Get-SPSite -Identity <ID>

    <目次に戻る>

     

    Web アプリケーションが User Profile Service アプリケーションに関連付けられているかチェックする
    Web アプリケーションが User Profile Service アプリケーションに関連付けられていない場合、プロファイルの同期対象となりません。
    以下の手順で Web アプリケーションが User Profile Service アプリケーションに関連付けられているか確認します。

    (手順) Web アプリケーションの関連付けを確認する

    1. サーバーの全体管理サイトにアクセスします。
    2. [アプリケーション構成の管理] をクリックします。
    3. [サービス アプリケーション] セクションの [サービス アプリケーションの関連付けの構成] をクリックします。
    4. 対象の Web アプリケーションのアプリケーション プロキシ グループ名をクリックします。
    5. サービス アプリケーションの関連付けの構成画面で User Profile Service アプリケーションのチェック ボックスがオンになっていることを確認します。

    <目次に戻る>

     

    データベースの同期情報をリセットする
    User Profile Service アプリケーションのプロファイル データベースでは、コンテンツ データベースとユーザー プロファイルの同期情報が管理されています。この��報には、同期対象となるコンテンツ データベースの ID や、最終同期日時に関する情報が記録されています。何らかの理由でこれらの同期情報の整合性が失われると、同期処理が正常に動作しない場合があります。このような場合には以下のコマンドを実行することで同期情報をリセットし状況を改善できる可能性があります。

    注意事項:データベースの同期情報をリセットすると、次回のユーザー プロファイルから SharePoint への完全同期のタイミングで、ユーザー プロファイルが存在し、サイト コレクションのユーザー情報に登録されたすべてのユーザーがプロファイルの同期対象になります。ユーザー数が多い (数千から数万単位の) 環境ではパフォーマンスの問題を引き起こす可能性がありますので、初回の同期はオフピークの時間帯に行うことをお勧めします。

    (手順) データベースの同期情報をリセットする

    1. ファームのいずれか1台の SharePoint サーバーにおいて、SharePoint 2013 管理シェルを管理者権限で起動します。
    2. 以下のコマンドを実行します。
      Stsadm -o sync -DeleteOldDatabases

    <目次に戻る>

     

    サイト コレクションのクォータ制限に達していないかチェックする
    サイト コレクションのユーザー情報リストは内部的に特殊なリストとして扱われており、各ユーザー情報は特殊なアイテムとして扱われるため、サイト コレクションがクォータ制限に達しているとユーザー情報を更新できません。
    以下の手順でサイト コレクションのクォータ制限に達していないか確認します。

    (手順) サイト コレクションのクォータ設定を確認する

    1. サーバーの全体管理サイトにアクセスします。
    2. [アプリケーション構成の管理] をクリックします。
    3. [サイト コレクション] セクションの [クォータとロックの構成] をクリックします。
    4. 対象のサイト コレクションを選択してサイトのクォータ情報を確認します。

    <目次に戻る>

     

    サイト コレクションがロックされていないか確認する
    サイト コレクションのユーザー情報リストは内部的に特殊なリストとして扱われており、各ユーザー情報は特殊なアイテムとして扱われるため、サイト コレクションが読み取り専用にロックされているとユーザー情報を更新できません。
    以下の手順でサイト コレクションがロックされていないか確認します。

    (手順) サイト コレクションのロック状況を確認する

    1. サーバーの全体管理サイトにアクセスします。
    2. [アプリケーション構成の管理] をクリックします。
    3. [サイト コレクション] セクションの [クォータとロックの構成] をクリックします。
    4. 対象のサイト コレクションを選択してサイト ロックの情報が「ロックなし」になっていることを確認します。

    <目次に戻る>

     

    コンテンツ データベースが読み取り専用となっていないか確認する
    コンテンツ データベースが SQL Server において読み取り専用となっていた場合は、データの書き込みに失敗するためプロファイルの同期が行われません。
    以下の手順でコンテンツ データベースのステータスを確認できます。

    (手順) データベースの状態を確認する方法

    1. データベース サーバーに管理者権限でログインし、SQL Server Management Studio を起動してデータベースインスタンスに接続します。
    2. 左側ペインにて [データベース] を展開し、該当のコンテンツ データベースを右クリックし、[プロパティ] をクリックします。
    3. [プロパティ] ダイアログの左側ペインにて [オプション] をクリックします。
    4. 画面右側に表示された [その他のオプション] 項目の [状態] セクションにある [読み取り専用データベース] を確認し、"True" になっていないか確認します。("False" となっていれば問題ありません。)

    <目次に戻る>

     

    Web アプリケーションが除外対象に設定されていないか確認する
    ユーザー プロファイルから SharePoint への同期機能では、特定の Web アプリケーションを同期対象から除外するための機能が備わっています。
    以下のコマンドを入力することで、ひとつまたは複数の Web アプリケーションをプロファイル同期の対象外とできます。

    例) Stsadm -o sync -ExcludeWebApps "http://WebApp01, http://WebApp02"

    過去に上記コマンドを実行された経緯がある場合、Web アプリケーション単位でサイト コレクションへのプロファイル同期が行われなくなります。設定を元に戻す際には以下のコマンドを入力して設定を初期化します。

    Stsadm -o sync -ExcludeWebApps

    過去に設定された経緯が不明な場合は、取り急ぎ上記コマンドを実施することで切り分けが可能です。

    なお、設定内容は SharePoint 構成データ オブジェクトとして保存されるため、通常は外部から参照できませんが、構成データベースに対して直接クエリをかけることで値を参照できます。
    以下のクエリの実行結果より得られた値から m_WebApplicationSyncExcludeList フィールドの値を確認し、Web Application ID の値が入っていれば設定は有効です。

    (サンプル コード) PowerShell で構成データベースに対してクエリを実行した結果をテキスト ファイルに出力するサンプル コード

    $query = "SELECT Properties FROM Objects WITH(NOLOCK) WHERE Properties LIKE N'%Microsoft.Office.Server.Administration.UserProfileServiceProxy%'"

    #以下の接続文字列の Server および Database パラメータの値をご利用の環境に合わせて適宜変更します。
    $connectionstring = "Server=SQLServerName;Database=SharePoint_Config;Trusted_Connection=True;"

    $connection = New-Object -TypeName System.Data.SqlClient.SqlConnection
    $connection.ConnectionString = $connectionstring
    $command = $connection.CreateCommand()
    $command.CommandText = $query
    $adapter = New-Object -TypeName System.Data.SqlClient.SqlDataAdapter $command
    $dataset = New-Object -TypeName System.Data.DataSet
    $adapter.Fill($dataset)

    #ファイルの出力先を適宜変更します。
    $dataset.Tables[0] | ft | Out-File C:\out.txt -Width 2000

    <目次に戻る>

     

    User Profile Service アプリケーションでユーザー プロファイルの同期処理が進行中でないか確認する
    更新の競合を避けるため、User Profile Service アプリケーションで Active Directory などの外部データソースからプロファイルをインポート (同期) している処理の最中は、サイト コレクションへのプロファイル同期ジョブがスキップされます。
    前回の同期ジョブの実行時に User Profile Service アプリケーションでユーザー プロファイルの同期処理が進行中であった可能性が考えられる場合には、User Profile Service アプリケーションで同期処理が完了したことを確認してから、サイト コレクションへのプロファイル同期ジョブを実行します。

    User Profile Service アプリケーションでユーザー プロファイルの同期処理が進行中かどうかは、以下の方法で確認できます。

    (手順) User Profile Service アプリケーションでユーザー プロファイルの同期処理が進行中でないか確認する

    1. サーバーの全体管理サイトにアクセスします。
    2. [アプリケーション構成の管理] セクションの [サービス アプリケーションの管理] をクリックします。
    3. サービス アプリケーションの一覧から User Profile Service アプリケーションの名前をクリックして User Profile Service アプリケーションの管理サイトを開きます。
    4. ページ右側の [プロファイルの同期状態] が「アイドル」になっていることを確認します。

    <目次に戻る>

     

    データベースがオフラインでないか確認する (MOSS2007 のみ)
    MOSS2007 の 2009 年 10 月の累積的な更新プログラム (CU ビルド 12.0.6518.5000) 適用前の環境では、コンテンツ データベースがオフライン状態の時にユーザー プロファイルが同期できない問題がありました。
    現在この問題は改善していますが、MOSS2007 において 2009 年 10 月の CU を適用されていない環境ではご注意ください。

    (手順) コンテンツ データベースがオフラインになっていないか確認する方法

    1. サーバーの全体管理サイトにアクセスします。
    2. [アプリケーション構成の管理] をクリックします。
    3. [SharePoint Web アプリケーション構成の管理] セクションの [コンテンツ データベース] をクリックします。
    4. 対象のコンテンツ データベース名をクリックします。
    5. データベースの状態が「準備完了」になっていることを確認します。

    <目次に戻る>

     

    コンテンツ データベースまたはサイト コレクションが Moving の状態になっていないか確認する (MOSS2007 のみ)
    MOSS2007 では、コンテンツ データベースまたはサイト コレクションを移動する前に共有サービス プロバイダとの接続を切るために、「Stsadm -o preparetomove」コマンドを実施する必要がありました。
    このコマンドを実行すると、対象のコンテンツ データベース ID またはサイト コレクション ID が共有サービス プロバイダ データベースの同期情報管理テーブル (SiteSynch テーブル) に「Moving」状態として登録され、以降のプロファイル同期の対象になりません。データベースやサイト コレクションを別の環境に移動するケースにおいて、移動元の環境でデータが再利用されなければ問題ありませんが、再利用される場合は「Stsadm -o preparetomove」コマンドで「Undo」操作を行わなければならないことに注意してください。

    MOSS2007 SP1 の移行シナリオでは、コンテンツ データベースをファームから切り離してアップグレードするシナリオにおいて「Stsadm -o preparetomove」コマンドの実施を行う必要がありました。これは、コンテンツ データベースをファームから切り離して再接続した場合、同じ環境であってもデータベース ID が変わるため、古い情報を共有サービス プロバイダから切り離す必要があったためです。しかしながら、MOSS2007 インフラストラクチャ更新プログラム以降の環境では、同じ環境でコンテンツ データベースを切り離して再接続しても、データベース ID が変わらないように動作が変更されました。このため、MOSS2007 インフラストラクチャ更新プログラム以降の環境において、同じ環境で使用するコンテンツ データベースに対して「Stsadm -o preparetomove」コマンドを実行してしまうと、データベースの再接続後に引き続き「Moving」フラグが付いたままとなり、プロファイル同期が行われな��なります。

    (手順) Preparetomove 操作を行ったコンテンツ データベースまたはサイト コレクションを再び同期対象に戻す方法

    1. ファームの任意の SharePoint Server に管理者権限でログインしてコマンド プロンプトを起動します。
    2. 以下のパスに移動します。
      %COMMONPROGRAMFILES%\Microsoft shared\Web server extensions\12\Bin
    3. 以下の例のようにコマンドを実行します。
      Stsadm -o preparetomove -ContentDB -undo
      または
      Stsadm -o preparetomove -Site -undo

    (参考資料)
    Preparetomove: Stsadm operation (Office SharePoint Server)
    http://technet.microsoft.com/en-us/library/cc262122(v=office.12).aspx

    <目次に戻る>

     

    Office Server Web Services で使用される自己発行証明書が破損していないか確認する (MOSS 2007 のみ)
    MOSS 2007 サーバーに Microsoft .NET Framework 3.5 Service Pack 1 が適用された環境では、共有サービス プロバイダによって使用される Office Server Web Services で使用される SSL 自己発行証明書が破損する問題が報告されています。この問題が発生すると、プロファイル同期が正しく動作しなくなり、ユーザープロファイルの情報がサイト コレクションに同期されなくなることが報告されています。
    現象の詳細および回避策については以下の資料を参照してください。

    (参考資料)
    SSL でセキュリティ保護された Office SharePoint Server 2007 サイトまたは共有サービス プロバイダの [検索の設定] ページを参照できない
    http://support.microsoft.com/kb/962928

    <目次に戻る>

     

    その他のトラブルシューティング
    このセクションではユーザー プロファイルの同期に関連するその他のトラブルシューティングについて記載します。

    Active Directory セキュリティ グループの表示名が更新されない
    サイト コレクションに登録した Active Directory セキュリティ グループの情報 (表示名、電子メールアドレス) は、プロファイルの同期対象になりません。
    サイト コレクションに登録した Active Directory セキュリティ グループの表示名を変更するには、以下の手順を実施します。

    (手順) サイト コレクションに登録した Active Directory セキュリティ グループの表示名を変更する

    1. 対象のセキュリティ グループのアカウント ID を調べるため、「/_catalogs/users」または「/_layouts/15/people.aspx?MembershipGroupId=0」に直接アクセスしてサイト コレクションに含まれるユーザーの一覧 (ユーザー情報リスト) を表示します。
    2. 対象のセキュリティ グループの名前をクリックしてユーザー情報ページを表示し、「アカウント」の情報を確認します。
    3. SharePoint 管理 PowerShell を管理者権限で起動して以下のコマンドを実行します。
      #手順 2 で確認したアカウント名を指定します。
      $account = "c:0+.w|s-1-5-21-2113820013-3230978303-1817385773-2103"

      #新しい表示名と電子メールアドレスを指定します。
      $title = "NewTitle"
      $emailAddress = "NewEmail@contoso.local"

      #以下のコマンドではすべてのサイト コレクションのユーザー情報を更新します。
      Get-SPSite -Limit all | % {$domainGroup = $_.OpenWeb().SiteUsers[$account]; if ($domainGroup -ne $null) {$domainGroup.DisplayName=$title; $domainGroup.Email=$emailAddress; $domainGroup.Update()}}

    <目次に戻る>

     

    通知が設定できずユーザーが有効な電子メールアドレスを持たない旨のメッセージが表示される
    サイト コレクションのユーザー情報に電子メール アドレスが登録されていない場合にこの問題が発生します。
    ユーザー プロファイルが正しく同期されているか確認するとともに、ユーザー プロファイルに電子メールアドレスが登録されているか確認します。
    必要に応じてサイト コレクションのユーザー情報を手動で編集して電子メールアドレスを登録します。

    (関連情報)
    サイト コレクションのユーザー情報の確認方法と編集方法
    User Profile Service アプリケーションにインポートされたユーザー プロファイルの情報の確認方法と編集方法
    サイト コレクションのユーザー情報にユーザー プロファイルの情報が同期されない場合のトラブルシューティング

    <目次に戻る>

     

     

  • SharePoint クラシック ベースからクレーム ベースのWindows 認証に置き換えた際の注意点

    こんにちは SharePoint サポートの森 健吾 (kenmori) です。
    今回の投稿では、SharePoint Web アプリケーションの認証プロバイダー設定を、クラシックベースの Windows 認証からクレーム ベースの Windows 認証に切り替えた際に生じるカスタム ソリューションへの影響について簡単にご紹介します。

    SharePoint 2010 ではクラシックベース (既定) とクレームベースが選択可能でしたが、SharePoint 2013 では画面を見てもクレームベースしか選択できない設計となりました。このため、アップグレード シナリオなどで、クラシック ベースからクレームベースにアップグレードすることが多くなり、問題に直面しやすいと考え情報公開することに至っています。

    従来型のクラシックベースでは Web アプリケーションごとに 1 つの認証プロバイダーを指定していました。しかし、クレームベースでは、Security Token Service (STS) が認証を仲介します。このことで、複数の認証プロバイダーを同時に Web アプリケーションに関連づけることができ、委任先の各認証プロバイダーがユーザー認証すれば STS が該当 Web アプリケーションに対するアクセス権を付与すべくクレーム トークンを発行するという動作になります。

    簡単に説明すると上記の通りですが、スペースの限られたブログでクレームベースを深く説明することは難しいですので、詳細については TechNet などを確認ください。

    タイトル : 認証方法を計画する (SharePoint Server 2010)
    アドレス : http://technet.microsoft.com/ja-jp/library/cc262350(office.14).aspx

     

    1.   ユーザー アカウントの表記が変わる

    クラシック ベースにおいて、Windows ユーザー アカウント名は Domain\User でした。クレーム ベースでは、アカウント名は i:0#.w|Domain\User という表記に変更となります。
    アカウント名をもとに条件分岐するコードは稀であるにせよ、サイトにユーザーを自動で登録する処理など様々なソリューションが考えられます。そのような処理を実装している場合は、アカウント名の変更の影響をきちんと把握しておく必要があります。

    命名規則を簡単に紹介すると、以下の様になります。 

    命名規則

    1 文字目 : "i" (メンバの場合) / "c" (ロールの場合)
    2 文字目 : ":" (固定)
    3 文字目 : "0" (固定)
    4 文字目 : "#" (ユーザーの場合) / "-" (ロールの場合) / その他
    5 文字目 : "." (文字列の場合)
    6 文字目 : "w" (Windows 認証の場合) / "f" (Form 認証の場合) / その他
    以降1    : "|" (Windows 認証の場合は省略)
    以降2    : 例.aspnetmembership (発行元の名前 : Windows 認証の場合は省略)
    以降3    : "|" (固定)
    以降4    : 例.Admin1 (ユーザー名 / ロール名)

    プログラムでユーザー名からエンコードされたプレフィックスを含むアカウント名を取得するのであれば、以下のような処理で可能です。ここで取得したアカウント名を使用して、ユーザーを登録 (SPUserCollection.Add) することも可能です。

    Windows 認証の場合 (C#)

    // 変数の指定
    string userIdentifier = "DOMAIN\\user";
    // 実際の処理
    SPClaim claim = SPClaimProviderManager.CreateUserClaim(userIdentifier,SPOriginalIssuerType.Windows);
    string loginName = SPClaimProviderManager.Local.EncodeClaim(claim);

    タイトル : SPClaimProviderManager Class
    アドレス : http://msdn.microsoft.com/en-us/library/microsoft.sharepoint.administration.claims.spclaimprovidermanager(v=office.14).aspx

    タイトル : SharePoint クレームベース ID
    アドレス ; http://msdn.microsoft.com/ja-jp/library/ee535242(v=office.14).aspx

     

    2. Windows ユーザー トークンに関連したカスタマイズに対する影響

    クラシックベースの Windows 認証では、ASP.NET 偽装により実行スレッドが Web アクセスしたユーザー権限に偽装されます。この原理を利用して、これまで Web パーツなどの様々なカスタム ソリューションにおいて、様々な処理が実装されてきたと思います。

    2-1. Windows ユーザー トークンを使用した問題の発生するシナリオ

    シナリオ 1)
    Kerberos 認証による委任の設定を構築した上で、外部サーバー リソース (SQL Server, ファイル サーバー、Web サービス等) にパススルーでアクセスする。 (C#)

    String connectionString = "Data Source=DBServer;Initial Catalog=AdventureWorks;Integrated Security=SSPI;";
    using (SqlConnection connection = new SqlConnection(connectionString))
    {
        connection.Open();
    }

    (解説)
    クラシックベース認証で Windows 認証を構築した場合、SharePoint サーバーは ASP.NET 偽装の動作に基づき、Windows 資格情報を使用してユーザーが Web アプリケーションに対して認証後は、HTTP 要求スレッドはブラウザーにログインしたユーザーの実行権限で偽装されました。
    そのため、Kerberos による委任を構築している前提があれば、現在の資格情報であるスレッド実行ユーザー アカウントを使用して第 2 のサーバーにアクセスすることができました。

    ところが、クレームベース認証で Windows 認証を構築した際、Windows 資格情報を使用してユーザーが Web アプリケーションに対して認証後は、HTTP 要求スレッドは ClaimsIdentity として偽装され、スレッドの実行ユーザーは匿名ユーザーとなります。
    ブラウザーでアクセスしたユーザーではなく匿名ユーザーとして HTTP 要求スレッドが動作するため、第 2 のサーバーにそのままアクセスする権限を獲得することはできません。

    そのため、従来通りの方法では、Kerberos 認証を構築したパススルー認証を実施することができなくなります。対処策は後述いたします。


    クラシックベースの Windows 認証では NTLM のダブルホップ制約を回避するため、Kerberos 委任を構成して第 2 のサーバーにアクセスするというソリューションが多く存在していました。

    タイトル : ASP ページの認証問題のトラブルシューティング
    アドレス : http://msdn.microsoft.com/ja-jp/library/ms180891(v=vs.90).aspx
    参考箇所 : ダブルホップの問題

    特にパススルーが必須となるシナリオの例として、第 2 のサーバー側で要求元のアクセス権を検証する必要がある場合や、要求元のユーザー アカウントに紐づく情報を返す必要がある場合 (ユーザー プロファイル, メール, カレンダー等) などがあります。
    このようなシナリオでは、RevertToSelf (ASP.NET 偽装解除、RunWithElevatedPrivileges etc.) 、つまりアプリケーション プール実行アカウントへのスレッド偽装による回避ができません。
    パススルー シナリオでは、SecureStoreService という回避策もありますが、要求元先で 1:1 のアカウント、パスワードのマッピングを維持することはとても運用工数がかかるため、広く選択されなかった経緯があります。
    これらの要因から、Kerberos 委任によるパススルー認証をクレームベースにおいても使用したいという要望は、現在も多数存在するものと想定しています。

     

    シナリオ 2)
    現在の実行ユーザーが特定のセキュリティ グループに所属しているか (WindowsPrincipal.IsInRole) を確認して、表示項目を絞り込む (C#)

    WindowsPrincipal wp = new WindowsPrincipal(WindowsIdentity.GetCurrent());
    wp.IsInRole(@"BUILTIN\Administrators");

    WindowsPrincipal.IsInRole メソッドは、実行アカウントのトークン情報をもとにセキュリティ グループへの所属確認が可能です。トークンには所属するセキュリティ グループの一覧情報も含まれているため、AD に対するネットワーク接続なしにセキュリティ グループを確認できるため、パフォーマンス上低コストな実装として広く使用されてきた経緯があります。

    しかし、残念ながら、上記のコードもクレームベース認証に移行後はそのままで動作することはありません。
    上述の通り、クレームベース認証において、HTTP 要求スレッドは ClaimsIdentity として偽装されるため、コンテキスト情報から WindowsPrincipal を取得 (new WindowsPrincipal(WindowsIdenitity.GetCurrent())) しても匿名ユーザーとして認識されます。そのため、上記のコードはクラシックベースで想定した通りの動作になりません。

     

    2-2. Claim To Windows Token Service (C2WTS) を使用した対処策

    クレーム ベース認証環境において、クラシックベースで実施していたソリューションを実行する方法があります。継続して上記シナリオのような Windows トークンを使用したカスタマイズを実装したい場合は、C2WTS を使用してクレーム トークンから Windows トークンを変換して取得する処理を実装する方法が有効です。

    C2WTS は、非 Windows セキュリティ トークンから UPN を抽出し、偽装レベルの  Windows セキュリティ トークンを生成する Windows Identity Foundation (WIF) の機能です。

    2014/05/16 追記  制限付き委任を構成する

    クラシックベースにおける委任シナリオでは、無制限の委任により第 2 のサーバーに認証情報を受け渡すことが可能です。
    しかし、C2WTS による Windows トークンの取得時には、該当の設定のままでは他サーバーに対するアクセス許可を取得することができません。
    クレーム トークンから Windows トークンに変換する際には、サービスアカウントの委任設定において、"制限付き委任" を構成することが必須となります。

    1) ドメイン コントローラーにログインします。
    2) Active Directory ユーザーとコンピューターで、Active Directory オブジェクトのプロパティを開きます。
     - 補足
      ドメイン ユーザーの場合は、該当のユーザーアカウントを指定します。
       ローカル システムなどのコンピュータ アカウントの場合は、コンピュータ アカウントを指定します。
    3) [委任] タブを表示します。
    4) [指定されたサービスへの委任でのみこのユーザーを信頼する] を選択します。
    5) [任意の認証プロトコルを使う] を選択します。
    6) [追加] ボタンをクリックします。
    7) [ユーザーまたはコンピューター] を選択します。
    8) 委任するサービスを実行中のサービス アカウントを選択します。 
    9) 接続先の SPN を指定します。
       - 補足
         接続先サービス アカウントがローカル システムなどのコンピュータ アカウントでない場合は、SPN を別途登録した上でこの画面で利用可能なサービスを選択します。
    10) [OK] をクリックします。
    11) "このアカウントが委任された資格情報を提示できるサービス"  に選択した SPN が表示されていることを確認します。
    12) [OK] をクリックします。

    上記手順を実施後、必要に応じて変更を加えたサービス アカウントで稼働しているプロセス (w3wp.exe や c2wts サービス) がありましたら、プロセスを再起動 (アプリケーション プールのリサイクル、サービスの再起動) します。

    以下にサービスを有効化する方法を記載します。

    C2WTS を開始する方法

    1) [サーバーの全体管理] サイトにアクセスします
    2) [システム設定] セクションの [サーバーのサービスの管理] をクリックします
    3) [サーバーのサービス] 画面の右上 [サーバー] の設定が Web Front サーバーであることを確認します
    4) "Claims to Windows Token Service" の "処理" の "開始" をクリックします
    5) [サーバーのサービスの管理] 画面が再度表示された際、"状態" の内容 が "開始済み" になっていることを確認します
    6) [サーバーのサービス] 画面の右上 [サーバー] の設定より、対象の Web Front サーバーを変更します
    7) 手順 3) ~ 6) をファーム上の全ての Web Front サーバーに対してご実施ください

    上記サービスを構成するにあたっては、以下の設定も同時に実施しておいた方が良いので合わせてご紹介します。

    C2WTS が自動起動しない現象を防ぐ方法

    1) C2WTS を実行するサーバーに、ローカルの管理者権限のあるユーザーでログオンします。
    2) コマンド プロンプトを管理者として開きます。
    3) 以下のコマンドを実行します。depend= の後に半角スペースが入ることに注意してください。

    >sc config "c2wts" depend= CryptSvc

    4) [スタート] - [管理ツール] - [サービス] をクリックします。
    5) "Windows トークン サービスに対するクレーム" を探してダブルクリックします。
    6) [依存関係] タブをクリックし、[このサービスが依存するシステム コンポーネント] に "Cryptographic Services" が表示されていることをご確認ください。
    7) C2WTS を実行するサーバーが複数ある場合は、すべてのサーバーでこの手順を実施します。

    詳細は以下のサイトをご参考にしてください。

    タイトル : Claims to Windows Token Service (c2WTS) not starting after rebooting server
    アドレス : http://support.microsoft.com/kb/2512597

    C2WTS は既定はローカル システム アカウントで実行されますが、ドメイン ユーザーで実行する場合は追加手順が必要となります。以下をご確認ください。

    タイトル : Windows トークン サービスに対するクレーム (C2WTS)
    アドレス : http://technet.microsoft.com/ja-jp/library/hh231678.aspx
    参考箇所 : C2WTS の構成に必要な基本的な手順

    このサービスが有効化された後は、以下のようなコーディングでクレーム トークンから Windows トークンを生成することができます。

    C2WTS によるトークン変換実装方法 (C#)

    IClaimsIdentity ci = System.Threading.Thread.CurrentPrincipal.Identity as IClaimsIdentity;
    if (ci != null)
    {
        if (ci.Claims.Count > 0)
        {
           //look for the UPN claim
           string upn = string.Empty;
           foreach (Microsoft.IdentityModel.Claims.Claim c in ci.Claims)
           {
               if (c.ClaimType == System.IdentityModel.Claims.ClaimTypes.Upn)
               {

                   upn = c.Value;
                   break;
               }
           }
           WindowsIdentity wid = S4UClient.UpnLogon(upn);

           // シナリオ 1 ) 偽装
           using (WindowsImpersonationContext context = wid.Impersonate())
           {
               // ここに他サーバーに接続・要求する処理を書きます。
           }

           // シナリオ 2) セキュリティ グループ所属確認
           WindowsPrincipal wp = new WindowsPrincipal(wid);
           wp.IsInRole(@"BUILTIN\Administrators");
        }
    }

    2014/05/16 追記 SharePoint オブジェクトモデルを使用した C2WTS によるトークン変換実装方法 (C#)

    上記のような WIF のコードをラップした SharePoint オブジェクト モデルによる実装方法も確認できましたので、下記に記載します。

    WindowsIdentity wid = WindowsIdentity.GetCurrent();

    SPSecurity.RunWithElevatedPrivileges(delegate()
    {
         wid = SPSecurityContext.GetWindowsIdentity();
    });
    // シナリオ 1 ) 偽装
    using (WindowsImpersonationContext context = wid.Impersonate())
    {
        // ここに他サーバーに接続・要求する処理を書きます。

    }
    // シナリオ 2) セキュリティ グループ所属確認
    WindowsPrincipal wp = new WindowsPrincipal(wid);
    wp.IsInRole(@"BUILTIN\Administrators");

     

    上記に記載した通り取得した WindowsIdentity クラスのインスタンスを使用し、Impersonate メソッドを実行して WindowsImpersonationContext オブジェクトを生成して偽装する、セキュリティ グループへの所属を確認する (WindowsPrincipal.IsInRole) といった従来のクラシックベース認証で実施できていたカスタマイズ コードが実装可能となります。

    タイトル : WindowsImpersonationContext クラス
    アドレス : http://msdn.microsoft.com/ja-jp/library/vstudio/system.security.principal.windowsimpersonationcontext(v=vs.90).aspx

    タイトル : WindowsPrincipal.IsInRole メソッド (String)
    アドレス : http://msdn.microsoft.com/ja-jp/library/vstudio/fs485fwh(v=vs.90).aspx 

    タイトル : Claims to Windows Token Service (c2WTS) の概要
    アドレス : http://msdn.microsoft.com/ja-jp/library/ee517278.aspx

    タイトル : c2WTS からトークンを要求する方法
    アドレス : http://msdn.microsoft.com/ja-jp/library/ee517258.aspx 

     

    補足
    Excel Service や BI 機能では、以下のホワイト ペーパーに C2WTS を使用した委任の構成について手順を含めた方法が紹介されています。併せて参考にしていただき、知識を深めていただけますと幸いです。

    タイトル : Microsoft SharePoint 2010 製品の Kerberos 認証の構成
    アドレス : http://www.microsoft.com/ja-jp/download/details.aspx?id=23176 

    タイトル : Excel Services の ID 委任 (SharePoint Server 2010)
    アドレス : http://technet.microsoft.com/ja-jp/library/gg502605(v=office.14).aspx

    いかがでしたでしょうか。是非ともアップグレードなどの移行シナリオにおいて、事前にご確認いただき、運用への影響を抑えていただけますと幸いです。

     

  • SPS2013 10月CU に含まれる検索機能強化について

    この記事では、SharePoint Server 2013 の 2013年10月のCU に含まれる検索機能強化について解説します。
    本投稿内容の元となった記事についてはこちらをご参照ください。

     

    概要
    SharePoint Server 2013 の 2013年10月のCUには、検索結果により適切なコンテンツを表示するための追加機能が含まれています。この追加機能により、Word 文書と PowerPointプレゼンテーションにおいて検索結果のタイトルにより適切な情報が表示されるようになりました。また、ドキュメント本体から最終更新日時を取得する動作が無くなりましたので、コンテンツの正確な最終更新日時を利用して検索結果の並び替えや絞り込みができるようになりました。

     

    変更点
    検索インデックス作成時のプロセスにおけるメタデータ抽出機能に改良を加え、以下の2つの新しい「クロールされたプロパティ」を追加しました。

    ・MetadataExtractorTitle
    ・MetadataExtractorAuthor

    また、従来ドキュメントの本体から意図しない更新日時が取得されていた動作を廃止し、コンテンツのメタデータより取得される更新日時が正確に検索結果に反映されるよう改善を加えました。

     

    変更の適用方法
    SharePoint Server 2013 の 2013年10月のCU の適用後、コンテンツのフル クロールを実施します。

     

    影響範囲
    この動作変更の影響により、CU の適用に伴い「Title」管理プロパティと「Author」管理プロパティに対する既存の検索スキーマのマッピングが初期化されます。これらの管理プロパティに対する既存の検索スキーマの設定を変更しているユーザーは既存の検索スキーマの設定内容を控えておく必要があります。

     

    詳細な動作について
    以下に、詳細な動作について解説します。

    タイトル表示に対する変更点
    今回の改良が適用される以前は、「Document1.docx」や「Presentation1.pptx」といったタイトルでドキュメントが保存されていた時に、検索結果において「Document1.docx」や「Presentation1.pptx」といったタイトルが表示されるケースがありました。今回の改良により、メタデータ抽出機能でドキュメント本体からより適切と考えられるタイトルが抽出されるようになりました。メタデータ抽出機能で取得されたタイトルの値は、新しい「クロールされたプロパティ」の「MetadataExtractorTitle」として出力されます。MetadataExtractorTitle は既定で「Title」管理プロパティにマッピングされ、優先順位が一番高く設定されます。これにより、検索結果により適切なタイトルが表示される可能性が高くなります。

    検索結果に表示されるタイトルを変更する方法
    ユーザーは検索スキーマの設定で「Title」管理プロパティにマッピングされる「クロールされたプロパティ」の優先順位を変更することで、検索結果に表示されるタイトルを任意のプロパティに紐づけられます。

    以下は、既定でマッピングされているプロパティの一覧です。

    優先順位クロールされたプロパティカテゴリ説明
    0MetadataExtractorTitleMetadataExtractorWord 文書と PowerPoint プレゼンテーションの本体から抽出されたタイトル
    1TermTitleSharePointSharePoint アイテムのタイトル
    2Office:2OfficeOffice ドキュメントのタイトル
    3Ows_BaseNameSharePointSharePoint ページの名前
    例) http://my/sites/wiki/Home.aspx
    4Titleドキュメント パーサーコンテンツ処理コンポーネントにより取得されたタイトル
    5MailSubjectドキュメント パーサーコンテンツ処理コンポーネントにより取得された電子メール ファイルの件名
    6Mail:5メール電子メールファイルの件名
    7People:PreferredName
    urn:schemas-microsof
    t-com:sharepoint:por
    tal:profile:PreferredName
    ひとひとの姓と名
    8Basic:displaytitle
    urn:schemas.microsof
    t.com:fulltextqueryi
    nfo:displaytitle
    基本オフィス ドキュメントのファイル名
    9ows_TitleSharePointSharePoint ページのタイトル
    10Basic:10基本ファイルのメタデータ プロパティに関連付けられたファイル名
    11Basic:9基本ファイルのメタデータ プロパティに関連付けられたファイル パス

    該当するプロパティの値が空の場合には、優先度がひとつ低いプロパティの値がマッピングされます。
    管理プロパティの設定方法については以下の資料を参照してください。

    (参考資料)
    SharePoint Server 2013 で検索スキーマを管理する
    http://technet.microsoft.com/ja-jp/library/jj219667.aspx

    SharePoint Online で検索スキーマを管理する
    http://office.microsoft.com/ja-jp/office365-sharepoint-online-enterprise-help/manage-the-search-schema-in-sharepoint-online-HA103628856.aspx

    Author 管理プロパティに対する変更点
    Author 管理プロパティに対しても、新しい「クロールされたプロパティ」の「MetadataExtractorAuthor」がマッピングされます。
    Author 管理プロパティに対するマッピングには優先順位は無い (クロールされた全プロパティからコンテンツを取り込む) ため、特にユーザーが変更を意識する必要はありません。

    以下は、既定でマッピングされているプロパティの一覧です。

    クロールされたプロパティカテゴリ説明
    Authorドキュメント パーサーコンテンツ処理コンポーネントにより取得された作成者
    MailFromMail電子メール ファイルの差出人から取得された名前
    Mail:6Mail電子メール ファイルのメタデータに含まれる作成者
    AuthorNotesOne Note ファイルの作成者
    Internal:3内部SharePoint 内部オブジェクトのメタデータに関連付けられた作成者
    Internal:105内部SharePoint 内部オブジェクトのメタデータに関連付けられた作成者
    Office:8OfficeOffice ドキュメントの ModifiedBy メタデータ プロパティ
    MetadataExtractorAuthorMetadataExtractorWord 文書と PowerPoint プレゼンテーションの本体から抽出された作成者

    クロールされた全プロパティからコンテンツを取り込む設定になっていた場合、すべてのクロールされたプロパティの値を重複を削除した形でマージしてから検索プロパティに値を格納します。検索時にはいずれか1つのプロパティの値が一致した場合に検索結果に表示します。

    LastModifiedTime 管理プロパティに対する変更点
    以前の動作では、メタデータ抽出機能によりドキュメントの本体から最終更新日と想定されるデータが抽出されていました。これにより、本来更新日とは全く関係が無い日付が最終更新日として取り込まれるケースがあり、検索結果の絞り込みや並べ替えに影響を与えることがありました。今回の動作変更では、LastModifiedTime 管理プロパティに対してドキュメント本体から最終更新日を取り込む動作を廃止しました。
    これにより、ユーザーはより正確なコンテンツの最終更新日に基づき、検索結果の並び替えや絞り込みができるようになりました。



  • 最近の SharePoint 関連ニュース (2013年11月5日)

    こんにちは。
    SharePointサポートチームの荒川です。
    今週のアップデートです。

    //日本の近畿地方では去年より6日遅く木枯らし1号が吹いたみたいですね。私が今住んでいるワシントン州ベルビューでは、最低気温が5度を下回る日もちらほらで、完全に冬模様です。朝出社の際には車のフロントガラスが見事に凍結しており、氷を溶かすのに熱湯をかけてしまいガラスが粉々になったという衝撃的な話を耳にしたりもします。そんな中、先日強風のせいで一時停電になり、あまりの寒さに生まれて初めて「暖炉」なるものを使ってみたのですが、いやはや火の力は素晴らしいものですね。遠赤外線効果のためか体の芯から温まるようで、揺らめく炎を眺めているだけで癒されます。日本でも一部の方に薪ストーブが絶賛されている理由がよくわかりました。まぁ、うっかりベントを開け忘れて火災報知器を鳴らしてしまったことは完全に誤算でしたが。。

    最近の SharePoint 関連ニュース (2013年11月5日)



  • SharePoint 2013 で SPSite.StorageManagementInformation メソッドが使用できない

    対象製品:

    SharePoint 2013

     

    こんにちは。SharePoint サポートチームの多田 信吾です。

    SharePoint 2013 では SPSite.StorageManagementInformation メソッドが使用できなくなっております。

     

    SharePoint 2013 SPSite.StorageManagementInformation メソッドが使用できない

    http://support.microsoft.com/kb/2905286/ja

     

    SPSite.StorageManagementInformationメソッドは、SharePoint 2010 の時代から obsolete (今後廃止される可能性があること) としてマークされており、使用が推奨されておりません。

    SharePoint 2013 SPSite.StorageManagementInformation メソッドを使用した場合、SPExceptionがスローされます。本来メソッドが使用不可能になっている場合は、参照できないようになっているか NotSupportedException がスローされるべきであるため、本現象はサポート部門では製品の問題であると認識しています。

     

    SPSite.StorageManagementInformation Method

    http://msdn.microsoft.com/en-us/library/office/microsoft.sharepoint.spsite.storagemanagementinformation(v=office.14).aspx

     

    補足情報:

    本現象についてサポート部門にて引き続き調査を実施した結果、SPSite.StorageManagementInformationメソッドが使用できない原因はコンテンツ データベース内に以下のビューが存在しないことに起因することがわかりました。以下のビューは SharePoint 2010 の環境では存在しております。

     

    DocVersions

    WebParts