連載
» 2009年10月15日 00時00分 公開

第3回 進化したPowerShell 2.0Windows Server 2008 R2の真価(2/4 ページ)

[牟田口大介(Microsoft MVP for Data Center Management - PowerShell),著]

 PowerShell 2.0の解説の前に、PowerShellの基本について、簡単にまとめておこう。

コマンドレットについて

 コマンド・プロンプトではコマンド(内部コマンドと外部コマンド)を使って処理を実行させることはすでに述べたが、PowerShellにおいてコマンド・プロンプトのコマンドに相当するものは「コマンドレット(Cmdlet)」と呼ばれるコマンドライン・ツール群である。デフォルトの状態で約230個のコマンドレットが用意されている。これらのコマンドレットを単独で、あるいは組み合わせて使用するのがPowerShellの基本である。

 コマンドレットは従来のコマンド・プロンプト+コマンドという環境と比較すると大きく進化している。そのポイントをいくつか挙げよう。

1.統一化されたツール群である
 コマンドレットはあらゆる面で統一化が図られたツール群である。まずコマンドレットの命名規則は極めて明快であり、それは「動詞の原形-名詞の単数形」で統一化されている(動詞の後に前置詞、名詞の前に名詞や形容詞が付くことはある)。例えば、テキスト・ファイルなどの内容を取得し表示するコマンドレットは、Get-Contentである。また、ファイルなどをコピーするコマンドレットは、Copy-Itemである。ディレクトリの子アイテム(ファイルやフォルダなど)を列挙するコマンドレットはGet-ChildItemである。このように、コマンドレットの命名規則は統一化されているため、覚えやすい、どんなコマンドレットがあるのか類推しやすい、そのコマンドレットが何をするためのものか把握しやすい、などの特長を有している。

 また、コマンドレットに渡すパラメータの名前は、「-(ハイフン)」から始まる英単語である。例えば、先ほど挙げたGet-Contentコマンドレットにパスを指定するパラメータ名は「-Path」である。すなわち、C:\Users\Administrator\test.txtというファイルの内容を取得したい場合は、

Get-Content -Path C:\Users\Administrator\test.txt

のようにする。コマンド・プロンプトのコマンドのパラメータ名は、-から始まるもののほかに、/から始まったり、記号から始まらないものがあるほか、1文字のものや単語のものが混在しているなど、とても統一されているとはいえない。

2.さまざまな種類のリソースに同じコマンドレットでアクセスできる
 コマンド・プロンプトでは基本的にファイル・システムしかアクセスできなかった。それに対しPowerShellには「PSプロバイダ」という仕組みが備わっており、ファイル・システムのみならず、レジストリや環境変数、Active Directoryなど、ディレクトリ構造を持つリソースにも同じコマンドレットを用いてアクセスできる。例えばGet-ChildItemを用いると、ファイル・システム・プロバイダが提供するファイル・システム・ドライブでは(PSプロバイダが提供するドライブを「PSドライブ」という)、コマンド・プロンプトと同様、カレント・フォルダ内のサブフォルダとファイルの一覧を取得できるが、レジストリ・プロバイダが提供するレジストリ・ドライブでは、カレント・キーにあるサブ・キーの一覧を取得できる。ほかにも、Get-Content、Copy-Item、Set-Location(カレント・ディレクトリの移動)などのコマンドレットが、異なるPSドライブに対して共通して使用できる。

 このような特徴を備えているため、管理者が覚える必要のあるコマンドレット数が減らせ、また複数のリソースを同様の方法で扱えるため習熟が容易になっているといえる。

3.データをオブジェクトとして扱う
 PowerShellが従来のコマンドライン・シェルと大きく異なる点の1つに、データをすべてオブジェクトとして取り扱う点が挙げられる。従来のコマンドライン・シェルでは、コマンド同士を連携させるのにパイプ(|)を使用し、あるコマンドの出力結果を次のコマンドに入力することができた。しかしながら、パイプを介する場合、そこで渡されているのは単なるテキスト・データであるため、渡された先のコマンドではそのテキスト・データを適切に解釈してやる必要がある。場合によっては、テキスト解析、整形用のコマンドを仲介して多段階のパイプを通す必要も出てくる。

 PowerShellは従来のコマンドライン・シェルとは違い、コマンドレットの出力はすべてオブジェクトである。これをGet-ChildItemコマンドレットをファイル・システム・ドライブで用いた場合で説明しよう。Get-ChildItemコマンドレットを実行するとファイルとサブフォルダ一覧が文字列として表示される。

Get-ChildItemコマンドレットを実行したところ
カレント・ディレクトリがファイル・システムの場合Get-ChildItemを実行すると、そのフォルダに含まれるサブフォルダとファイルが表示される。
  (1)コマンドレットの実行。
  (2)実行結果。ファイル・システムに対してGet-ChildItemを実行すると、このようにフォルダやファイル名の一覧が得られる。

 しかし実際の動きは次のようになっている。

1. Get-ChildItemコマンドレット実行
2.サブフォルダを表すFolderInfoオブジェクトおよびファイルを表すFileInfoオブジェクトの配列を取得
3.配列に含まれるMode(ファイル属性)、LastWriteTime(最終更新日時)、Length(サイズ)、Name(ファイル名)プロパティのみを抽出して表として整形出力


 すなわち、Get-ChildItemが返しているものは、ファイルやフォルダに対応するオブジェクトであり、それらは上記のプロパティを持っているということになる。そのため、例えば出力を最終更新日時の順にソートするならば、次のようにGet-ChildItemコマンドレットの出力結果(オブジェクト配列)をSort-Objectコマンドレットにパイプを通して渡せばよい。

Get-ChildItem | Sort-Object -Property LastWriteTime

 また、3.の段階で表示されていないプロパティも、2.の段階ではしっかり保持されているので、これを表示させることも可能だ。例えば、「名前」と「作成日時」と「最終更新日時」をカラムとして持つ表を出力するには、次のようにFormat-Tableコマンドレットに出力結果を渡すとよい。

Get-ChildItem | Format-Table -Property Name,CreationTime,LastWriteTime

 ほかにも、Where-Objectコマンドレットを用いた配列のフィルタリングなどがよく使われる。

 このようなことが可能になるのは、コマンドレットの出力がオブジェクト(の配列)であり、それらがプロパティという形で情報を持っているからである。テキスト・ベースのコマンドライン・シェルとは一線を画すオブジェクト・ベースのシェルであることの利点が見いだせるだろう(:これらのオブジェクトは.NET Frameworkのオブジェクトである。そのため、.NET Frameworkの元のクラスに定義されているプロパティやメソッドが参照、設定、呼び出し可能である)。

 もちろん、PowerShellは管理用シェルとして基本的な処理をこなすためのコマンドレットがほかにもいくつも用意されている。よく使われるのは次のコマンドレット群であろう。

よく用いられるコマンドレット
*-Process プロセスの列挙、起動、終了など
*-Service サービスの列挙、起動、終了など
*-EventLog イベントログの列挙、書き込み、消去など
Get-WmiObject WMIを用いたシステム情報の取得
よく用いられるコマンドレット(抜粋)
よく用いられるコマンドレットの例。*はGetやStartなどの動詞。

 以上のようにコマンドレットは習熟が容易で、かつ強力な機能性を有している。コマンドレットを用いることでさまざまな操作が簡便に行える。

スクリプティングについて

 PowerShellではバッチ・ファイルやWSHスクリプト・ファイルと同様に、処理をあらかじめテキスト・ファイルに記述しておき、実行したいときに処理をまとめて実行させることが可能である。PowerShellスクリプト・ファイルは拡張子が*.ps1となり、ここにシェルで行っていたのと同じようにコマンドレットを単独、あるいはパイプで組み合わせたものを複数行記述していくのが基本となる。

 これだけでも十分強力であるが、PowerShellではさらに各種制御構文を用い、より複雑な処理を行うことも可能である。バッチ・ファイルとは異なりPowerShell言語は、モダンな言語と同様に構造化された言語であるため、各種制御構文を用いることでより複雑かつ可読性および保守性の高いコードが記述可能である。

 また、PowerShellは.NET Frameworkを扱うシェルであるため、C#などの.NET系プログラミング言語と同様に、PowerShellスクリプト内から任意の.NETクラスを利用することも可能だ。もっとも、積極的に.NETクラスを使用しなくとも、多くの場合はコマンドレットと制御構文の組み合わせでほとんどのことができてしまう。しかしコマンドレットだけでは実現不可能な処理に遭遇しても、.NETクラスをじかに呼び出せば解決するという特徴があるのだ。

 このページで紹介した内容は、基本的にはPowerShell 1.0ですでに実現されていたことである。ご覧いただいたとおり、PowerShell はシェルとしてもスクリプト実行環境としてもVer.1.0の段階ですでに洗練されていることが感じていただけたと思う。しかしPowerShellは2.0になってさらにパワーアップしており、さまざまな機能が追加されている。次のページではそれらを紹介していこう。

Copyright© Digital Advantage Corp. All Rights Reserved.

RSSについて

アイティメディアIDについて

メールマガジン登録

@ITのメールマガジンは、 もちろん、すべて無料です。ぜひメールマガジンをご購読ください。