からめもぶろぐ。

俺たちは雰囲気で OAuth をやっている

PowerShell 実践ガイドブック 書籍レビュー

tech.guitarrapc.com

気になったので応募したところ当選してしまいました!ぎたぱそ氏およびマイナビ出版の方にはこの場を借りてお礼申し上げます。ということで書籍レビューです。

book.mynavi.jp

PowerShell との思い出

もともと SharePoint をやってきたので、PowerShell は基本的に SharePoint の管理のためにお世話になっています。SharePoint では 2010 からこれまでの stsadm.exe に代わってサーバー サイドの管理ツールとして SharePoint 管理シェルとして導入されました。*1 最近では SharePoint Online Management Shell だとか PnP-PowerShell だとか、クライアント サイドでの管理ツールも増えてきました。とはいえまだ PowerShell Core には対応されていないので、Windows PowerShell を使っている感じです。*2

SharePoint 以外でも Active Directory の管理や Exchange の管理など、マイクロソフト製品を使っている限りは PowerShell にはお世話になります。かつては ASP.NET から System.Management.Automation.dll を使ってリモートの Exhange に接続して New-MailBox を呼び出すとか無茶なことをしたこともありました。

客先で借り受けた PC に開発環境がなにも入ってなくて、やむなく標準で入っている PowerShell でゴリゴリやったとりか、最悪 .NET が使えるコンパイラ不要な言語として扱えるのでとてもお世話になりました。

Git の CUI としても活躍していますね。posh-git と GitPad の組み合わせがいい感じです。

前置きが長くなったので肝心のレビューをしたいと思います。

よかったところ

動作環境は PowerShell Core が前提です。かなりクロス プラットフォームが意識されており、特にコマンド プロンプトや bash との比較が多かったのが印象的でした。Windows ユーザーはコマンド プロンプトの後継製品としての PowerShell は理解しているはずが、Linux や Mac OS のユーザーにはまだ PowerShell への意識はそんなに高くないと思います。bash との比較があることで、これまでやってきたことやこれからやりたいことが、具体的にイメージできるのではないかと感じました。

PowerShell Core 限定というよりは PowerShell 全般にかかわる内容も多いため、まだ Windows PowerShell を触っている方 (おそらくこっちのほうが大多数のはず) でも役立つ内容がたくさんあります。私は PowerShell を Hey, Scripting Guy! とか個人ブログとか (もちろんぎたぱそ氏のブログも!) を見ながら勉強してきました。やりたいことを満たすための習得にはそれで十分なのですが、それだとやはり知識が偏ってしまうので、網羅的に学習するためにはとてもよい教材だと思います。トランスクリプトとか正直知りませんでした…。知ってたらもっと効率化できたのに!と悔しい思いをしています。

また、経験に裏打ちされたベスト プラクティスが随所に記載されています。個人的には、結果を Write-Output に流さないための書き方のベンチマークは参考になりました。なんとなく PowerShell っぽい書き方で Out-Null を使っていたのですが、パイプラインは時間かかるんですね。これからはほかのやり方で書くことにします。こういったテクニックは第 5 章にまとまっているので、ある程度 PowerShell を知っていて、全部読むのが大変という方は、第 5 章だけでも読むのをお勧めします。

気になったところ

よかったところと相反する形になってしまうかもしれませんが、ほかのスクリプト言語と比較するときにコマンド プロンプトや bash が適当だったかというと、疑問の余地があります。確かに PowerShell は対話型のシェルとして使えるのですが、コマンド プロンプトや bash よりは高級言語の感があるので、比較するなら、Windows であれば VBScript、Linux であれば awk, sed, Perl あたりが比較対象なのかなと。特に VBScript や VBA はパワー ユーザー向けの言語であり、PowerShell への移行が向いているので、これら言語へのサポートがあると、より PowerShell の普及に役立つのではないかと思いました。

細かいところですが、配列のところで固定長の配列を宣言する書き方が言及されていなかったような。特にバイナリの処理でたまに使うので、書いてあると手厚いかなと感じました。

$buffer = New-Object byte[] 1024

誤字がちょっと目立ったのは初版だから仕方ないかなという感じ。改版されることがあれば修正に期待します。

これはもともと本書に期待することではないかもしれませんが、C# との相互運用をもっといろいろ書いて欲しかったです。本書でも C# でコマンドレットを書く方法はありますが、C# から RunSpace を作って PowerShell のコマンドレットを呼び出したりとかできるので、今後そのあたりの本を出してほしいですね!

*1:ちなみにそんな経緯もあって SharePoint 2016 でも管理シェルはモジュール化されておらずスナップインのままです。

*2:PowerShell Core で SharePoint の管理をしたい場合は SPClientCore を使ってね!

SharePoint Online Management Shell がインストールする CSOM がいけてない

発端は Japan SharePoint Support Team Blog の記事です。

blogs.technet.microsoft.com

SharePoint Online Management Shell をインストールすることで、CSOM のモジュールもインストールされます。

はい、確かに SharePoint Online Management Shell をインストールすると、CSOM が使えるようになります。ただし、SharePoint Online Management Shell が入れる CSOM はかなりイケてないので、個人的にはまったところを含めて紹介したいと思います。なお、以下はすべて 2018/03/29 時点の情報であり、今後変更される可能性があります。

(2019/03/01 追記)
PowerShell Gallery から入手できるようになりました。

blog.karamem0.jp

モジュールが不完全

SharePoint Online Management Shell に含まれる CSOM の dll は以下の通りです。

  • Microsoft.Online.SharePoint.Client.Tenant.dll
  • Microsoft.SharePoint.Client.dll
  • Microsoft.SharePoint.Client.Runtime.dll

一方、CSOM の NuGet パッケージ (Microsoft.SharePointOnline.CSOM の .NET 4.5 版) に含まれる dll は以下の通りです。

  • Microsoft.Office.Client.Policy.dll
  • Microsoft.Office.Client.TranslationServices.dll
  • Microsoft.Office.SharePoint.Tools.dll
  • Microsoft.Online.SharePoint.Client.Tenant.dll
  • Microsoft.ProjectServer.Client.dll
  • Microsoft.SharePoint.Client.dll
  • Microsoft.SharePoint.Client.DocumentManagement.dll
  • Microsoft.SharePoint.Client.Publishing.dll
  • Microsoft.SharePoint.Client.Runtime.dll
  • Microsoft.SharePoint.Client.Runtime.Windows.dll
  • Microsoft.SharePoint.Client.Search.Applications.dll
  • Microsoft.SharePoint.Client.Search.dll
  • Microsoft.SharePoint.Client.Taxonomy.dll
  • Microsoft.SharePoint.Client.UserProfiles.dll
  • Microsoft.SharePoint.Client.WorkflowServices.dll

明らかに足りない。確かに Microsoft.SharePoint.Client.dll と Microsoft.SharePoint.Client.Runtime.dll がコア機能をすべて持っているので、だいたいのことは事足りてしまうのですが、検索やソーシャル、管理されたメタデータといった機能が入っていないので、突然困ることになります。

謎のバージョンを GAC に突っ込む

SharePoint Online Management Shell の CSOM のアセンブリ バージョンは 16.0.7414.1200 です。そして、NuGet の CSOM のバージョンは 16.1.7414.1200 です。これだけならまだ困らないのですが、SharePoint Online Management Shell はなんと 16.0.7414.1200 の dll を GAC に入れてしまいます。そうすると、NuGet の CSOM でしか存在しない dll を読み込んだときに、アセンブリ バージョンの不整合が起こり、予期しないエラーが発生します。具体的には Assembly.LoadWithPartialName で dll を読み込んだときなどに発生します。*1
前掲の記事でも以下のコメントがあるのは、こういう状況が発生することを認識しているためと思われます。

なお、SharePoint Online Management Shell と SharePoint Online Client Components SDK などを同時にインストールした場合エラーが発生する可能性があるため、いずれかのみのインストールとしてください。

ともあれ、不完全に GAC に突っ込む動作はかなりいけてないので、何らかの改善を望みたいところです。せめてアセンブリ バージョンを合わせてほしいです。

*1:Assembly.LoadWithPartialName は obsolete なので使うなって話なのですが。

AppVeyor で PowerShell Core モジュールをデプロイする

AppVeyor で .NET Core のビルドができると聞いたので、PowerShell Core モジュールのビルドもできるんじゃね?ということで試してみました。

Environment

公式のドキュメントによれば [Visual Studio 2015] または [Visual Studio 2017] であれば .NET Core SDK 2.0 がサポートされます。特に [Visual Studio 2015] を選択する積極的な理由はないので [Visual Studio 2017] を選択します。

www.appveyor.com

Build

[MSBUILD] は使えないので [SCRIPT]-[CMD] を選択して dotnet コマンドを実行します。通常の .NET Core アプリケーションとは違い、PowerShell Core の場合、NuGet パッケージ ソースに MyGet を指定する必要があるので、追加で指定します。

dotnet restore --source https://api.nuget.org/v3/index.json --source https://powershell.myget.org/F/powershell-core/api/v3/index.json
dotnet build --configuration Release

Deployment

PowerShell Gallery への発行を自動化します。Publish-Module を実行するだけですが、必ず [SCRIPT]-[PS CORE] を選択する必要があります。[SCRIPT]-[PS] (Windows PowerShell) だと Publish-Module の前提条件チェックでエラーになります。

Publish-Module -Name {{path}} -NuGetApiKey {{apikey}}

SPClientCore 1.0 を公開しました

SPClientCore 1.0 を公開しました。

www.powershellgallery.com

使用できるコマンドの一覧は以下の通りです。

PS C:\> Get-Command -Module SPClientCore

CommandType     Name                                               Version    Source
-----------     ----                                               -------    ------
Cmdlet          Add-SPRoleAssignment                               1.0.0      SPClientCore
Cmdlet          Add-SPViewField                                    1.0.0      SPClientCore
Cmdlet          Connect-SPOnline                                   1.0.0      SPClientCore
Cmdlet          Connect-SPServer                                   1.0.0      SPClientCore
Cmdlet          Copy-SPFile                                        1.0.0      SPClientCore
Cmdlet          Find-SPAttachment                                  1.0.0      SPClientCore
Cmdlet          Find-SPContentType                                 1.0.0      SPClientCore
Cmdlet          Find-SPField                                       1.0.0      SPClientCore
Cmdlet          Find-SPFile                                        1.0.0      SPClientCore
Cmdlet          Find-SPFileVersion                                 1.0.0      SPClientCore
Cmdlet          Find-SPFolder                                      1.0.0      SPClientCore
Cmdlet          Find-SPGroup                                       1.0.0      SPClientCore
Cmdlet          Find-SPList                                        1.0.0      SPClientCore
Cmdlet          Find-SPListItem                                    1.0.0      SPClientCore
Cmdlet          Find-SPRecycleBinItem                              1.0.0      SPClientCore
Cmdlet          Find-SPRoleAssignment                              1.0.0      SPClientCore
Cmdlet          Find-SPRoleDefinition                              1.0.0      SPClientCore
Cmdlet          Find-SPUser                                        1.0.0      SPClientCore
Cmdlet          Find-SPView                                        1.0.0      SPClientCore
Cmdlet          Find-SPWeb                                         1.0.0      SPClientCore
Cmdlet          Find-SPWebTemplate                                 1.0.0      SPClientCore
Cmdlet          Get-SPAttachment                                   1.0.0      SPClientCore
Cmdlet          Get-SPContentType                                  1.0.0      SPClientCore
Cmdlet          Get-SPField                                        1.0.0      SPClientCore
Cmdlet          Get-SPFile                                         1.0.0      SPClientCore
Cmdlet          Get-SPFileVersion                                  1.0.0      SPClientCore
Cmdlet          Get-SPFolder                                       1.0.0      SPClientCore
Cmdlet          Get-SPGroup                                        1.0.0      SPClientCore
Cmdlet          Get-SPList                                         1.0.0      SPClientCore
Cmdlet          Get-SPListItem                                     1.0.0      SPClientCore
Cmdlet          Get-SPRecycleBinItem                               1.0.0      SPClientCore
Cmdlet          Get-SPRoleAssignment                               1.0.0      SPClientCore
Cmdlet          Get-SPRoleDefinition                               1.0.0      SPClientCore
Cmdlet          Get-SPSite                                         1.0.0      SPClientCore
Cmdlet          Get-SPUser                                         1.0.0      SPClientCore
Cmdlet          Get-SPUserProfile                                  1.0.0      SPClientCore
Cmdlet          Get-SPView                                         1.0.0      SPClientCore
Cmdlet          Get-SPWeb                                          1.0.0      SPClientCore
Cmdlet          Get-SPWebTemplate                                  1.0.0      SPClientCore
Cmdlet          Move-SPFile                                        1.0.0      SPClientCore
Cmdlet          Move-SPViewField                                   1.0.0      SPClientCore
Cmdlet          New-SPAttachment                                   1.0.0      SPClientCore
Cmdlet          New-SPContentType                                  1.0.0      SPClientCore
Cmdlet          New-SPField                                        1.0.0      SPClientCore
Cmdlet          New-SPFile                                         1.0.0      SPClientCore
Cmdlet          New-SPFolder                                       1.0.0      SPClientCore
Cmdlet          New-SPGroup                                        1.0.0      SPClientCore
Cmdlet          New-SPList                                         1.0.0      SPClientCore
Cmdlet          New-SPListItem                                     1.0.0      SPClientCore
Cmdlet          New-SPRoleDefinition                               1.0.0      SPClientCore
Cmdlet          New-SPUser                                         1.0.0      SPClientCore
Cmdlet          New-SPView                                         1.0.0      SPClientCore
Cmdlet          New-SPWeb                                          1.0.0      SPClientCore
Cmdlet          Open-SPFile                                        1.0.0      SPClientCore
Cmdlet          Remove-SPAttachment                                1.0.0      SPClientCore
Cmdlet          Remove-SPContentType                               1.0.0      SPClientCore
Cmdlet          Remove-SPField                                     1.0.0      SPClientCore
Cmdlet          Remove-SPFile                                      1.0.0      SPClientCore
Cmdlet          Remove-SPFileVersion                               1.0.0      SPClientCore
Cmdlet          Remove-SPFolder                                    1.0.0      SPClientCore
Cmdlet          Remove-SPGroup                                     1.0.0      SPClientCore
Cmdlet          Remove-SPList                                      1.0.0      SPClientCore
Cmdlet          Remove-SPListItem                                  1.0.0      SPClientCore
Cmdlet          Remove-SPRecycleBinItem                            1.0.0      SPClientCore
Cmdlet          Remove-SPRoleAssignment                            1.0.0      SPClientCore
Cmdlet          Remove-SPRoleDefinition                            1.0.0      SPClientCore
Cmdlet          Remove-SPUser                                      1.0.0      SPClientCore
Cmdlet          Remove-SPView                                      1.0.0      SPClientCore
Cmdlet          Remove-SPViewField                                 1.0.0      SPClientCore
Cmdlet          Remove-SPWeb                                       1.0.0      SPClientCore
Cmdlet          Restore-SPFileVersion                              1.0.0      SPClientCore
Cmdlet          Restore-SPRecycleBinItem                           1.0.0      SPClientCore
Cmdlet          Select-SPWeb                                       1.0.0      SPClientCore
Cmdlet          Start-SPRoleInheritance                            1.0.0      SPClientCore
Cmdlet          Stop-SPRoleInheritance                             1.0.0      SPClientCore
Cmdlet          Update-SPContentType                               1.0.0      SPClientCore
Cmdlet          Update-SPField                                     1.0.0      SPClientCore
Cmdlet          Update-SPFile                                      1.0.0      SPClientCore
Cmdlet          Update-SPFolder                                    1.0.0      SPClientCore
Cmdlet          Update-SPGroup                                     1.0.0      SPClientCore
Cmdlet          Update-SPList                                      1.0.0      SPClientCore
Cmdlet          Update-SPListItem                                  1.0.0      SPClientCore
Cmdlet          Update-SPRoleDefinition                            1.0.0      SPClientCore
Cmdlet          Update-SPUser                                      1.0.0      SPClientCore
Cmdlet          Update-SPView                                      1.0.0      SPClientCore
Cmdlet          Update-SPWeb                                       1.0.0