なぜ、PowerShellを使うのか？

#なぜ、PowerShellを使うのか？
## PowerShell Advent Calendar 2016：16日目

本記事は「<a href="http://qiita.com/advent-calendar/2016/powershell" target="_blank">PowerShell Advent Calendar 2016</a>」16日目の投稿です。

## はじめに――PowerShellの「パワー」とは何か？

「**Windows PowerShell**」（以下「**PS**」）は、名前に「パワー」が付いていますが、このパワーとは何のパワーなのかを考えていきます。（もちろんこれは、個人的に分かりやすいと考える、非公式の説明です）

そして後半では、そのパワーをビジネスなどの実世界に活かす方法も考えていきます。PSを使う人がパワーを得られて、そのことで結果的にPSが普及し、PS自体のパワーも増していく（かもしれない）、そのためのお話です。


***
## これがPowerShellの「パワー」
### オブジェクト指向パワー

WindowsOSは、「**.NetFramework**」というフレームワークによって、仮想的に**オブジェクト指向**の実行環境になります。

これは、低水準で動作するOS（API）を、高水準のオブジェクト（API）として操作できるようにする仕組みです。要するに、機械を人間に使いやすくします。

PowerShellは、この.NetFrameworkを使えますから、オブジェクト指向のパワーを利用できます。ここが従来の**コマンドプロンプト**との違いです。


### 関数型パワー

PSは、開発時に「Monad」というコードネームがついていたように、**関数型プログラミング**のパワーを使えます。

具体的には、「**オブジェクト指向パイプライン**」という機構を備えています。

もともと、パイプというのはUNIXの仕組みですので、Linuxのbashなどのシェルスクリプトでも、とうぜんパイプラインは使えます。

しかしここで、文字列とオブジェクトの違いがあります。UNIX由来のパイプラインは文字列ですが、PSのパイプラインはオブジェクトにパースされているのです。

このオブジェクト指向パイプラインは、オブジェクト指向と関数型プログラミングの両方が備わり、最強に見えます。

シェルスクリプトではデータフロー的な操作を行う機会が多いので、パイプラインの仕組みは相性が良いです。

それが、具体的にどのように便利なのかは、次項で説明しましょう。


### LLパワー

```
dir | ogv
```

論よりコードで、詳細は省きますが、上のPSコードは、たったこれだけで、ディレクトリのファイル一覧を簡易GUIで表示できます。（もちろん、これはサンプルコードで、実用的には、いろいろ他の処理を書くでしょう）

このように、PSはワンライナーが書きやすい言語です。スクリプト言語の「Tcl」にも影響されていますし、処理速度より開発速度を重視している点で、**LL言語**に分類する解釈も可能だと思います。

とくに**REPL環境**は、LLというかシェルスクリプトにとって重要な要素です。PSではこのREPLが標準で使えるところが、**WSH（VBScript、JScript）**との違いです。

PSは普通の言語機能を備えていますから、PS単体でもかなり記述力があります。簡単なバッチ的処理はPS一本で書くと、エディタの記述とコマンドラインの操作がシームレスになって楽です。

その一方で、PSはシェルスクリプトなので、「**グルー言語**」として、他の言語を組み合わせて使うのも良いと思います。


### CUIパワー

PSはバージョン5.0で**クラス構文**が追加されたように、モダンな言語です。たとえば、今どきGOTO文を使うような、レガシーなコマンドプロンプトとは大きく異なります。

私も以前は、Windowsでのコマンドライン操作が面倒に感じて、あまり好きではありませんでした。しかし、PSを覚えてから、そういう苦手意識は完全に吹っ飛びました。PSだとコマンドラインでも快適です。

GUIパワー、すなわち、マウスでウィンドウを簡単に操作できるUIのパワーは、MS-DOSからWindowsに変わって、PCが広く一般に普及した大きな原動力になりましたよね。

そこでさらにPSは、Windowsに**CUI**（CLI）パワーも加えます。


### 自動化パワー

CUIが最も威力を発揮するのは、**自動化**です。

GUIは、人間にとって分かりやすく、操作しやすいというメリットがあります。しかし、人間がマウスなどで毎回操作する必要があります。

一方でCUIは、人間には分かりにくいですが、一度コードを書いてしまえば、何度でも使い回せます。つまり、自動化できます。

ですから、1回だけならGUIの方が楽ですが、100回繰り返すような定形的な作業は、CUIの方が圧倒的に楽になります。


***
## PowerShellのパワーを何に使うのか？
### サーバ管理 ／ システム管理

この記事前半では、PS自体の言語仕様を見てきました。後半からは、PSのパワーを何に使うのか、目的の方を見ていきましょう。

CUIによる自動化の恩恵を受ける分野では、まず何と言っても、**サーバ管理、システム管理**があります。

自動化は台数が多いほど強力になります。たとえばの話、マシンが100台あったとして、人間が1台ずつGUIで設定していくのと、CUIで自動化するのでは天地の差です。

### Linux/UNIXのパワーを取り込む

PowerShellを開発したのは**Microsoft**ですが、わざわざMSが新言語を開発した理由としては、まずサーバ市場を考慮していたようです。

MSのWindowsはデスクトップ用OSのシェアを寡占していますが、逆にサーバ用OSではLinuxに寡占されています。

この理由のひとつにOSのライセンス料の問題があります。Linuxならオープンソースでフリーですよね。もうひとつ、CUIと自動化の問題があります。サーバ管理の自動化では、Linuxに先行されてきました。

とくに、**クラウド**化の潮流が出てきてからは、クラウドサービス提供側にマシンが集約されて、サーバ管理が大規模化するため、圧倒的に差がついてしまいました。

それに、パソコンからスマートフォンへの移行という別の流れもあります。GoogleのAndroidOSがLinux系、MacOSやそれを継承したiOSがUNIX系だということも考慮すると、最近のLinux/UNIX系のパワーは相当なものでしょう。

個人的に考えるOSの勢力図としては、1995年からの十年が「Windowsの時代」、そこから今までの約十年は「Linux/UNIXの時代」だと見ています。

さて、サーバではLinuxが強いということを、MSは市場を調査するなどして当然知っていましたから、そのUNIX系のパワーを取り込む、という側面がPSにあったでしょう。

じっさい最近、PSはオープンソース化され、Linuxでも使えるようにもなりました。またその逆に、「Windows Subsystem for Linux」をMSは公開しました。これは、LinuxのパワーをWindowsに取り込んでいます。

こうしたMSのオープンソース勢力への融和政策が、ネットで最近話題になっていますが、今から十年前にPSを公開した際から、すでにその伏線であったと個人的には見ています。

### 業務の定形作業を自動化

サーバ管理やシステム管理以外でも、自動化は役に立つと思います。自動化は繰り返す回数に比例してコスパが良くなるのですが、それが台数ではなく日数でも同じことです。すなわち、**毎日行う定形的な作業を自動化する**のに、PowerShellは向いています。

リネームやフォルダの整理など、部分的な自動化なら、フリーソフトでできることもあります。しかし、言語とは自由度がまったく違いますし、連携や統合がほとんどできません。

具体的にはたとえば、なにか日報のようなものを毎日作るとします。そこで、新しいファイルを作って、別ファイルからデータをコピペしてきて、文字列を整形し、日付順に古いファイルは削除して……、と流れるように一連の作業全体を自動化したいなら、PSを使います。

もちろん、自動化は他の言語でもできます。PSやWSH以外にも、「AutoHotKey」や「UWSC」など、自動化向きの言語を過去いろいろ見てきました。しかしやはり、PSはWindows開発元のMSが提供していて、Windowsのシェルスクリプトで、かつモダンな言語仕様、「**プロバイダ**」など新機能がある、といろいろ利点があり、一番向いていると感じます。

もう少し言うと、シェルスクリプトであることのメリットに、**Windowsでのデファクトスタンダード**だということがあります。じっさい最近、Windows10のデフォルトのシェルをコマンドプロンプトからPSに変える動きもあるようです。

比較してたとえば、「IronPython」みたいなもので「IronRuby」というのがあって、PSとやや近い位置にあるWindowsの言語環境があります。しかしこれは、開発更新が2011年で止まってしまっています。こうしたことから将来性を考慮して、私はPSを学習する気になりました。


### 小規模自動化スクリプトとして見たVBAとの比較

ただ一方で、PSはそのパワーや汎用性のわりに、地味な印象があります。「PSはもっと評価されるべき」と思うこともあります。この話題に関しては、**VBA**と比較してみたいと思います。

VBAはExcelのマクロ言語なので、Excelを自動化できますよね。PSはWindowsのシェルスクリプトなので、Windows全体を自動化できます。とすれば、VBA以上のパワーと汎用性があるはずです。もし、PSを使ったことがない場合、あるいは使ってない人に対する説明としては、VBAの延長線上をイメージすると、分かりやすいと思います。

ですから、PSはポテンシャルがあるはずなのですが、実際にはネットを検索したり書店の棚を見るに、PSはVBAほど一般層に普及していない気がします。これは、入門書不在でハードルが高いことが原因だと思います。PSの本はプログラミング言語を習得している前提で、VBAの本はしていない前提という場合が多いです。結果、初心者にはVBAの方がハードルが低いでしょう。

メジャーなプログラミング言語を何かひとつすでに習得していれば、PSで極端に難しい部分はそうないと思います。たとえば、パイプラインはメソッドチェーンの仕組みに似ているから、私はRubyをやっていたのですんなり覚えられました。しかし、前述のように初心者向けの情報は少ないので、プログラミングを始めるための入門言語にPSが向くかどうかは微妙です。

一方でじつは、PSには小規模開発／運用向けの側面があると考えます。それがなぜかを本格的に論旨展開すると長くなるので、紙幅の都合から、次に箇条書きでまとめます。

- PSは実行速度が遅い。パイプラインでオブジェクトにパースするため
- だから、Linuxのシェルスクリプトより遅いし、遅いと言われるRubyよりもっと遅い
- つまり、処理速度より開発速度を重視している。これは小規模の開発運用に向く
- また、Windowsサーバは小規模向けで使われている
- 規模が大きくないと、ライセンス料を考慮しても、Linux技術者の人件費、もしくは社員の学習コストがペイしないから
- 技術者以外には、やはり普段使っているWinデスクトップの延長線上の方が使いやすい
- ビジネスでExcelを使う都合上、同じWindowsなのも都合が良い

だから、中小企業や個人事業者などの小規模な開発運用に、PSが向いていると思います。前述のようにサーバー／システム／業務など、様々な自動化にPSは向いています。そうして業務を効率化できれば、人件費を削減できますから、社員数が少ない中小零細では効果が大きいと思います。

こうしたことの参考事例にたとえば、「ユニケージ」という開発手法があります。これは、Linux/UNIX系のシェルスクリプトと、それを用いたDSLなどを駆使して、簡易な開発体制を敷くことで、開発コストを抑える手法です。

これをPSでも応用できないかと考えます。ただし、PSのパイプラインはLinuxのそれと違ってマルチスレッドが効かないので、大幅に遅くなります。そのかわり、オブジェクト指向パイプラインは開発効率を上げるので、さらに小規模向きになるでしょう。

ようするに、PSのパワーが活かせる分野で、まだ開拓する余地があるのでないか、と考えます。


### PCの身体化言語としてのSmalltalkとの比較

後半ではここまでなるべく、ビジネスにつながる話をしてきましたが、それとはまた別に、私自身には思うところあります。

私はすでにRubyを覚えてしまったし、本格的なオブジェクト指向の言語環境が欲しいので、PS一本だけで書くことはしませんが、PSをグルー言語として利用します。

UNIXの思想に、小さいプログラムを組み合わせて機能を実現する、という考え方があります。具体的には、ひとつの大きなアプリを作るのではなく、Rubyなどで小機能のコマンドを数多く作って、それらをPSから実行します。PSから見てDSLを使っているような感じです。

それは、昔のWindowsでもできなくもないけれど、レガシーなコマンドプロンプトではやる気になれませんでした。PSはCUIを使う良い機会になります。

さらに、たんにバラバラの部品をグルー（糊）でくっつける、というイメージからもう少し踏み込んで、運転する、身体化していくというイメージを描いてみます。

日常ではたとえば、自転車や自動車を自分で運転するのと、他人が運転する車に乗せてもらうのでは、まったく違った感覚ですよね。自分で運転すると身体化します。道具を身体の一部のように感じるわけです。とくに、REPLで対話的に使うときに感じます。

だから、ビジネスうんぬんの実利を抜きにしても、PSを使って運転することで道具が身体化していく、サイクリングしていくような面白さがあります。Webを見ることを「ネットサーフィン」などと言いますが、それをパソコンの内側に対して行うようなイメージです。

こうしたPC環境を自分の自由に操作したいという考えを、より洗練させたもので、アラン・ケイの「（暫定）ダイナブック」構想というのが過去にありました。長くなるのでその詳細は省きますがさしあたり、言語とその実行環境としての（Squeakなどの）「Smalltalk」が暫定ダイナブックになります。とつぜん出てきた話題のようですが、WinOSもMacOSも、GUIOSの祖先は同じ「Alto」（Smalltalk）にさかのぼります。それにオブジェクト指向の源流でもあります。

たしかに、Smalltalkは何もかも自由だし、美しい設計思想で、オブジェクト指向の神髄を感じました。しかし一方で、Smalltalkは難解で学習コストが高過ぎるとも感じました。それは本質的な難しさというより、たんに使用人口が少ないから情報も少ないことによる難しさが大半ですが、利用のハードルが高いことには変わりありません。これは、Lisp実行環境としてのEmacsにも同じようなことを感じました。

また、Smalltalkの実行環境は一種の仮想OSのようにみなされますが、けっきょくはWindowsなどのOS上で動いているわけで、OS環境と二重化します。すると、その違いが開発運用のボトルネックになりがちです。他のスクリプト言語でもありますが、言語の標準的なライブラリで済むうちは快適でも、より深い処理はC/C++を通じてWin32APIを呼ぶ必要がある、といったことです。そういう段差がPSだと少なく、かなりシームレスです。

それから、Smalltalkでは環境自体もアプリもオープンソースですが、現実的には大量のコードをひとりで追い切れず、もてあましてしまいます。だから個人的には、あまり低水準のカスタマイズまでは求めていません。たとえると、自給自足で畑を耕すレベルの自作までは求めていなくて、料理を自炊するレベルの自作で、私の場合は十分だということです。

Smalltalk側の利点もあえて言えば、開発環境と実行環境が一体化しているため、IDEがとても使いやすいです。しかし、現在では「**Visual Studio Code**」があって、これが使いやすいです。同じMSなので、PS用の機能や拡張もあります。ですので、VSCodeとPS、あとRubyなどで開発運用すれば、不満を感じることが以前より少なくなっています。

けっきょく、日常的に使うものが難しいと大変だと考えて、今の私はコスパ重視でPowerShellを選んでいるということです。


***
## 結論：PowerShellを使う理由

最後にまとめ直しましょう。PowerShellは、コマンドプロンプトに代わる、新世代のモダンなシェルスクリプトです。

PSを使うと、オブジェクト指向パイプラインという機構で、データフローが有効な処理を簡潔に書くことができます。

PSの用途は、まずCUIによる自動化、とくにサーバ管理やシステム管理が主でしょう。

しかし、VBAによるエクセルの自動化の延長線上で、日常的な定形作業の自動化にも使えます。

今はまだ十分に普及しているとは言いがたいですが、個人事業などの小規模開発に本来は向いているので、開拓の余地があると考えます。

そして、とくにREPLで対話的に使っているときには、パソコンを自分の手足のように一体感を持って使う、たとえば自転車を自分の足として使うような感覚も得られます。

インターネットのパワーは今さら説明する必要もないでしょう。そうしたネットワークがパソコン外側で自由に動き回れるパワーなのに対して、PSのパワーとは、パソコンの内側を自由に動き回れるパワーなのです。


***
## 参照
### 公式サイト
- <a href="http://social.technet.microsoft.com/wiki/contents/articles/14301.windows-powershell-ja-jp.aspx" target="_blank">Windows PowerShell (ja-JP) - TechNet Articles - TechNet Wiki</a>（概要）
- <a href="https://technet.microsoft.com/ja-jp/scriptcenter/powershell_owner01.aspx" target="_blank">Windows PowerShell 入門</a>（オーナーマニュアル）

### 関連記事
- <a href="http://qiita.com/lldev2/items/46d55f71bdc1af2e3b10" target="_blank">なぜ、VSCodeを使うのか？ - Qiita</a>