PowerShellとは

PowerShell

本書をご覧いただいているということは、すでにどこかでPowerShellのことを見かけていることと思う。そうでなければ、世界的にもマイナーなこのスクリプト環境のことを知る由もないだろう。

PowerShellというのはシェルと何かを結びつけるためのグルー(のり)プログラミング言語であり、スクリプト言語である。昨年2016年の夏になるまでは、名前のはじめにWindowsとついていた。つまり、Windowsで生まれたプログラミング言語だった。

プログラミング言語のほかにもシェルを代替するかのような操作を行うことから、スクリプト環境と考えていたこともある。実際、2014年にリリースした電子書籍には「スクリプト環境だよ」と書いた。これはいまでも誤りではない。だが、その認識よりもずっと重要なことがグルー(のり)の性質を持っているということだ。だからそれを先にご紹介したまでだ。

PowerShellの歴史についてはWikipediaで調べるとよいだろう。もしくはマイクロソフトの公式サイトにも情報を見つけることができるかもしれない。わたしが最初に知ったのはいまから5年近く前であり、その頃にはまだVistaやXPが主流のOSだった。Windows XPからPowerShellは登場していた。その時にはまだまだ何に使ったらいいのかもわからず、いまよりもさらに情報は少なかった。それに利用できる機能もいまよりもさらに限定的だった。

大きく変わったのはバージョンが2.0を過ぎた頃からではないだろうか。Windows7にはバージョン2.0が標準でインストールされていたのだ。そのため、特にセットアップすることなくスクリプトを自由に制作できる環境が登場した。この時点からすでにISEは標準インストールされていた。

ところが、このバージョン2.0もWindowsの.Net Frameworkを駆使する必要があった。わたしはこの頃、まだWindows Scripting Hostを使用したVBScriptやJScriptによるバッチツールをつくっていた。自分が担当しているウェブサービスの運営を行う上で、Windowsに基本的に導入されている技術だけで可能な限りのオペレーションを自動的に行うためだった。

その後、バージョン3.0が登場すると景色は一気に近代的になった。このため、わたしもWSHを捨ててPowerShellの世界へ飛び込んだ。飛び込んだ理由はたったの2つだった。

  1. .Net Frameworkで開発されたDLLを直接利用することができる
  2. COM技術を使ってWSHのような操作を行うことができる

この2点さえあれば、日本人の大好きなExcel操作だけでなく、アプリケーションのバックエンドにいるデータベースやAPIとのやりとりも自由に行うことができた。

PowerShellはバージョン3.0以降ではじめて実用的になったと考えてもよいかもしれない。もしあなたの環境がWindows8以降であればそれは実用的なものだろう。Windows10であれば多くの選択肢を得たことになる。もしmacやLinuxであればアルファ版という扱いだが、最新バージョンを利用することができる。

グルー言語

グルー言語という種類には、2017年になったいまでは多くのプログラミング言語があてはまる。たとえば、次のようなものだ。

  • ruby
  • python
  • groovy

こうしたものはオペレーティングシステムのシェルとほかの何かをつなぎ、問題の解決を手助けする。rubyであればrake、gem、rack、ほかにもインフラ構築を自動化してテストしやすくするオーケストレーションツールもこうしたもので開発されてきた。あまり聞きなれないgroovyについてもGradleなら聞いたことがあるのではないだろうか。

PowerShellも同様に、Windowsというオペレーティングシステムをマネジメント、つまりほかの何かとうまく連動するようにするために開発されたプログラミング言語なのだ。ところが、上述したプログラミング言語に比較すると驚くほど人気がない。原因はWindowsでしか動作しなかったからではないかと勝手に邪推しているが、クロスプラットフォームになったいまでは確信に変わってしまっている。

さて、PowerShellがこうしたグルー言語の仲間であることはわかった。それでは、PowerShellはどのように利用すればよいのだろうか?それはいままでVBAマクロやWindows Scripting Hostを利用していたのであればおわかりなのではないだろうか。こうしたもので開発されたものは、たいていは事業の隙間を埋めるために作成される。ある箇所までは情報システムが担っていて、そこまでは全自動でことが行われる。しかし、もうひとつの情報システムへその全自動で作成されたデータを利用させようとすると、なんらかの方法でデータを入力することが必要になる。しかも、こうしたデータはたいていの場合、それぞれの情報システムを設計、開発したときには求められていなかった事柄であり、事業が運用されていくにつれ明らかとなった事項のことが多い。

ここで情報システムと情報システムの間をデータでとりもつのがVBAマクロやWSHのツールである。あるいは、情報システムへのデータ入力がなんらかのファイル(CSVが最も多いのかもしれない)であったとして、社内担当が管理するデータはまったく異なるレイアウトの情報であることも多い。このレイアウト変更にもマクロなどのツールは利用される。

このような情報システムどうしの間をつなぐもの、「のり」としての役割を担うのがグルー言語だ。PowerShellもそのひとつだということなので、マクロやWSHで記述された内容をPowerShellスクリプトで置き換えることができるだろう。

もしもExcelの情報が必要であればマクロのように操作できるCOM技術を利用することができる。逆にデータのみが必要であれば.Net Frameworkのライブラリを活用することもできる。

最大の特徴

PowerShellの最大の特徴は、入力そして出力がすべてオブジェクトだということだ。プログラミング自体がはじめてのユーザーが最初に選んだものがPowerShellであることは極めてまれだと思うが、ほかのプログラミング言語、スクリプト環境では標準入力、出力を介したテキストのやりとりがほとんどのはずだ。そのため、あるアプリやツール、コマンドからの出力を受け取るとテキストとして解析して何かを行うことになる。一方でPowerShellはオブジェクトとして受け取る。このため、フォルダ内の拡張子がxlsxであるファイルを列挙した上でファイルサイズの多い方から順に表示するというようなよくありそうな操作はファイル列挙コマンドの出力を解析することなくオブジェクトとして扱い解決することができる。

Get-ChildItem -File | Sort-Object -Property length -Descending

この最大の特徴に気づいたとき、わたしは感動したことを覚えている。もうawkやperlでテキストをちぎっては投げしなくてもいいのだ、と。ところが同時にがっかりもしたのだ。Windowsでしか利用できなかったからだ。その当時、わたしの仕事はほとんどRedHad Linuxを操作することだった。結果として、わたしはbash、python、groovyを選択した。いずれもインストールすることなく利用でき、groovyではjarファイルだけで動作するうえデータベース操作を行うためのJavaの資産も利用することができたからだ。そのようなわたしにはWindowsでしか動作しないdllなどを利用する検討の余地は一切残っていなかった。その後、同様のことをWindows上で行う必要があり、結局PowerShellを学ぶに至った。その結果、いまこの文章を書いている。

このように、Windowsでしか動作しなかったPowerShellだが一点だけ非常に優れていることがあった。それは、ほかのプログラミング言語にはない特徴だ。Windowsでは最初からインストール済みであり、いつでも利用できるようになっているということだ。PCにもインストールすることができない環境にいたわたしは、PCではPowerShellに頼ることになる。もうExcelマクロのお守りやVBScriptのツールは書きたくなかったのだ。

もちろん、rubyもpythonもgroovyも利用していた。いずれもインストールを行わなくても圧縮ファイルを解凍してバイナリを取り出せば、すぐに利用することができた。問題はライブラリにあった。rubyやpythonはオペレーティングシステム固有のバイナリを利用するライブラリを動作させるためにコンパイルが必要になることがある。この結果、やたらと制限がある環境下ではそのすぐれた機能を発揮することなく単なるテキスト解析ツールでしかなかった。groovyについてはjarをダウンロードすればうまくいくものが多かった。しかし、PowerShellほどシェルと結びついていなかったため、わたしの仕事ではごく限られた領域でしか利用することがなかった。

PowerShellを支えるもの

PowerShellは.Net Framework上に構築されたプログラミング言語である。このため、.Net Frameworkとも非常に高い親和性を持っている。ごく当たり前に.Net Frameworkのオブジェクトを扱うことができるうえにC#などで書いたプログラムをその場でコンパイルして利用するといったことも可能になっている。つまりコンパイラを使ってdllやexeにしなくてもPowerShellの中からそうした機能を利用することができる。

一方でPowerShellはWindowsシェル、コマンドプロンプトとも密接に関係している。powershell.exeはコマンドプロンプトをベースに起動されるからだ。もちろんWindows以外ではbashなどの環境の上に実行される。その上でWindowsコマンド、Unixコマンド、ほかのスクリプト言語やコマンドラインツールなどともパイプ(オブジェクトパイプライン)を通じて連携することができる。クロスプラットフォームになったときのデモンストレーションにおいて、pythonで実行した結果を利用してPowerShellで結果を加工するというものがあった。pythonはpowershellから起動され、結果を標準出力へ出力していた。それはPowerShellから見れば文字列オブジェクトとなる。このため、文字列オブジェクトとして扱うことができる。また、複数行になれば文字列オブジェクトの配列とみなして動作するため、各行ごとに加工を行うことができる。このあたりはawkとも通じるものがあると考えている。

さらに、Windows環境に限定すれば古き良き時代を支えてきた技術であるCOMとも連携することができる。つまりExcelマクロのようなことがPowerShellからも利用できるということだ。一点辛いことがあるとしたらCOMオブジェクトは明示的に解放をしてやる必要があるということだろう。

もう一つ言えば、.Net Frameworkを経由してDllImportを利用することでアンマネージドdllも利用することができる。2017年現在においてiniファイルを読み取り書き出しすることがあるのかどうかわからないが、GetPrivateProfileString関数を利用することもできる。

PowerShellができないこと

ここまでくると、PowerShellにもできないことがあることを紹介しておかなければならない。「”なんでもできる”は”なにもできない”」ということが多い。PowerShellもできないことがあるし、苦手なことがある。そうした場合にはグルー言語である特性を最大限に活用して他の環境にその作業を委ねるべきだ。

面白いことに、普通のプログラミング言語にできることでPowerShellにはできないことがいろいろ存在する。本当にしょうもないことまでできない。たとえば、テキストの先頭や末尾に半角スペースがいくつもついていたとしよう。これを除去したいとする。rubyやpythonではstripメソッドを使えばいい。

"    aaaaa    ".strip()  #==> aaaaa

マクロ(VBA)でさえTrim関数を使えば除去することができる。

Trim("    aaaaa    ")  ' ==> aaaaa

PowerShellにはこのTrim関数にあたる関数や演算子、コマンドレットは存在しない。ではどうするのか?非常に簡単なことで、すべて.Net Frameworkオブジェクトであるから、Stringオブジェクトとしてtrimメソッドを利用すればよい。

"    aaaaa    ".Trim()  #==> aaaaa

このようにほかの方法で代替できることは用意しないというのがPowerShellの方針のようだ。似たようなものに-replace演算子というものがある。テキスト中に見つけることができるパターンを別のテキストに置き換えをするものなのだが、これには正規表現が使用される。これを知らずに利用すると、意図しない置換がなされる結果となる。単純な完全一致するものを置換したいときは.Net FrameworkとしてStringオブジェクトのReplaceメソッドを利用しなければならない。

また昨今ではニーズのある並列処理についても似たような動作をさせるためにつくりこみを行う必要がある。こうした分野はGo言語やNode.jsなどの方がよりやりやすいうえ、macやLinuxに限らずWindowsでも利用できるため無理にPowerShellを採用すべきではないかもしれない。考え方次第だが、PowerShellを利用すべき箇所はオペレーティングシステムのかなり近く、他のなんらかのアプリやツールが離陸するまでの間に位置するべきなのだと考えている。

results matching ""

    No results matching ""