からめもぶろぐ。

SharePoint が得意なフレンズなんだね!すごーい!

SharePoint 管理シェルで使用されている PipeBind オブジェクトについて

この記事は「PowerShell Advent Calendar 2017」の参加記事です。

qiita.com

SharePoint 管理シェルでは、例えば Get-SPWeb の Identity パラメーターに URL または ID (GUID) を渡すことができます。下記の例ではあえてキャストしていますが、もちろん文字列そのままを渡すこともできます。

$web1 = Get-SPWeb -Identity [uri]'http://server/sites/site'
$web2 = Get-SPWeb -Identity [guid]'909fb5bd-2ae3-4968-8ca6-b23f962d7300'

あるいは、SPWeb オブジェクトそのものを渡すこともできます。

$web3 = Get-SPWeb -Identity $web1

これがどのように実現されているかを見てみたいと思います。まずは Get-SPWeb のヘルプを見てみます。

docs.microsoft.com

Get-SPWeb
   [[-Identity] <SPWebPipeBind>]
   [-AssignmentCollection <SPAssignmentCollection>]
   [-Confirm]
   [-Filter <ScriptBlock>]
   [-Limit <String>]
   [-Regex]
   [-Site <SPSitePipeBind>]
   [-WhatIf]
   [<CommonParameters>]

Identity パラメーターの型は SPWebPipeBind です。PipeBind とはなんでしょうか。その答えは以下に説明があります。

SharePoint 管理シェル用コマンドレットの作成に関する重要な概念

PipeBind オブジェクトは、SharePoint 用の Windows PowerShell に固有の特別なオブジェクトであり、SharePoint Foundation 用に最適化された特殊なパラメーター セットという第 2 のレイヤーを提供します。

たとえば、SPSite パラメーターを取るコマンドレットは、SPSite オブジェクト自体を取ることも、そのサイト コレクションの GUID 識別子を取ることも、そのサイト コレクションの URL を取ることもできます。Windows PowerShell ランタイムによってどんな表現が与えられようとも、実際の SPSite オブジェクトがコマンドレット自体に間違いなく与えられるようにするのは、SPSitePipeBind オブジェクトの役目です。

つまり PipeBind オブジェクトがいい感じに受け皿となって、ユーザーが意識しなくても適切な表現として解釈してくれるというわけですね。この PipeBind オブジェクトのトリックは PowerShell の型変換の仕組みに依存しています。PowerShell は型変換をするときに、いくつかの手順で型変換を試みます。その中の手順のひとつである Constructor conversion により、元の値を渡してコンストラクターを呼び出してくれます。

blogs.msdn.microsoft.com

大事なのは、データの種類を型で判断しているので、同じ型のデータでは判断ができないことと*1、常に値が文字列で渡ってくる可能性を考慮することです。

ちなみに、同様の仕組みは、Active Directory モジュールなどにもあります。ただし、こちらは PipeBind という名前はついていません。例えば Get-ADUser の場合、インプットとアウトプットのどちらも ADUser です。個人的には SharePoint 管理シェルのように別の型になっていたほうが好みです。

*1:PnP-PowerShell の ContentTypePipeBind を見ると無理やり感が漂っています。

SPClientCore 0.1 をリリースしました

PowerShell Core 向けの SharePoint モジュールを作りました。現時点での最新の PowerShell Core 6.0.0-beta.9 に対応しています。

github.com

拙作の SPClient や Patterns & Practices の PnP-PowerShell は内部的に SharePoint Client Components SDK を使用しています。SharePoint Client Components SDK は .NET Standard 対応していないため、前記のモジュールは PowerShell Core では使用できません。そこで、SharePoint Client Components SDK を使用せず、SharePoint REST API を呼び出すことで、PowerShell Core で動作するようにしています。なお SharePoint REST API のリファレンスが 2013 ベースのため、2016 や Online で新しく追加されたプロパティには対応していませんが、動作自体は Online でも確認してします。

PowerShell Core に対応したモジュール開発環境を作ってみる

PowerShell Core が 6.0.0-beta になり .NET Core 2.0 に対応しました。いよいよ PowerShell Core も本格的になってきたので Visual Studio で PowerShell Core なモジュールを作成するための手順をまとめました。

MyGet への参照の追加

PowerShell Core のライブラリはまだ NuGet には展開されておらず、MyGet から入手する必要があります。そこで [ツール] - [オプション] - [NuGet パッケージ マネージャー] - [パッケージ ソース] に https://powershell.myget.org/F/powershell-core/api/v3/index.json を追加します。


プロジェクトの作成

[新しいプロジェクト] のプロジェクトの種類で [クラス ライブラリ (.NET Core)] を選択します。単体テストプロジェクトを作成する場合は [単体テスト プロジェクト (.NET Core)] を選択します。


NuGet パッケージの追加

[NuGet パッケージの管理] を開くと [パッケージ ソース] で MyGet を選択できるようになり、PowerShell Core のライブラリを追加できます。モジュール本体は System.Management.Automation を追加すれば大丈夫ですが、単体テスト プロジェクトは Runspace を作成してテストすることになるので*1、合わせて以下のパッケージも追加する必要があります

  • Microsoft.PowerShell.SDK
  • Microsoft.PowerShell.Commands.Diagnostics
  • Microsoft.PowerShell.Commands.Management
  • Microsoft.PowerShell.Commands.Utility
  • Microsoft.PowerShell.ConsoleHost
  • Microsoft.WSMan.Management
  • Microsoft.WSMan.Runtime

追加するパッケージが足りないと Runspace を作ったときにエラーが発生します。

System.Management.Automation.Runspaces.PSSnapInException: 'Cannot load Windows PowerShell snap-in Microsoft.PowerShell.Diagnostics because of the following error: Could not load file or assembly 'C:\Users\...\Documents\Visual Studio 2017\Projects\Module1.Tests\bin\Debug\netcoreapp2.0\Microsoft.PowerShell.Commands'. 指定されたファイルが見つかりません。'

OAuth + Office 365 API ではじめるアプリ開発を公開しました

話す機会がないのでスライドだけ。
Azure Active Directory での OAuth の使い方をまとめました。

v1.0 と v2.0 のエンドポイントが混在している状況は開発者の混乱の元になるので改善を期待したいところです。

(2017/9/6 追記) Resource Owner Password Credentials Grant について誤った表現があったため修正しました。