PowerShell - コマンドレットやオブジェクトなどの調査に関する20問

はじめに

今日から12月。今年も残すところ1ヶ月となりました。同時に技術系コミュニティの年末行事となったAdvent Calendarがスタートする日でもあります。今年は私も初めてAdvent Calendarに参加し、PowerShell Advent Calendar 2011の12月1日分を担当することになりました。以下はそのエントリです。

概要

Windows PowerShellスクリプトを書く時に、コマンドレットの使い方や、扱うオブジェクトにどのようなメソッドやプロパティがあるのか調べたくなることはよくあります。そのようなケースでは Get-Command, Get-Help, Get-Memberといったコマンドレットが「三種の神器」として役立ちます。このエントリでは、この「三種の神器」(+α) を使ったコマンドレットやオブジェクトなどの調査に関して、基本的であったり、よくあるケースを集め、問題形式にしてみました。
PowerShellを使い始めたばかりの方は是非、PowerShellコンソール、或いはPowerShell ISEを立ち上げて、実際に手を動かしながら解答してみてください。ただし、解答はあくまでも一例です。より良い解答がありましたら、ご指摘下さい。動作確認はPowerShell 2.0でしました。

問題(全20問)

太字部分が問題で、解答はすぐ下にあります。問題だけを見たい方はこちらを参照して下さい。

【問1】PowerShellが提供するコマンドレットの名前は、Start-Serviceのように「動詞-名詞」といった形式を取る。名前の名詞部分が "Service"であるコマンドレットと関数を列挙せよ。

> Get-Command -Noun service
> gcm -Noun service


【問2】名前の動詞部分が "Convert" で始まるコマンドレットと関数を列挙せよ。

> Get-Command -Verb convert*


【問3】New-Itemコマンドレットがサポートするパラメーターとそのパラメーターエイリアスを列挙せよ。

> (Get-Command New-Item).parameters.values | select name, aliases

Name      Aliases
----      -------
Path      {}
Name      {}
ItemType  {Type}
... ...

実行結果から、New-Itemコマンドレットの ItemTypeパラメーターには Typeというパラメーターエイリアスが存在することがわかります。すなわち、以下はどちらも同じです(foo.txtという空のファイルを作成)。

> New-Item foo.txt -ItemType file
> New-Item foo.txt -Type file

ところで、自分の場合は次のようにして解答例に辿り着きます。
(1)パラメーター情報にダイレクトにアクセスできるコマンドレットとかってないのかな? Get-Command *param* や help * -Parameter *param* で調べるが、それらしきものなし。
(2)パラメーターはコマンドレット、関数といったコマンドに付随するものだから、Get-Commandが返すオブジェクトにパラメーターに関するプロパティがあるかもしれない。
(3) Get-Memberコマンドレットを使ってGet-Commandが返すオブジェクトのプロパティやメソッドを調べる。

$cmd = Get-Command New-Item; $cmd | gm

すると parameters というそれらしいプロパティの存在がわかる。
(4)この parameters プロパティについて、さらにGet-Memberで調べたり、値を覗いたりして調査する。

$cmd.parameters | gm
$cmd.parameters.values

(5)このような調査を繰り返して、欲しい情報が最終的に name と aliasesというプロパティであることに辿り着く。

調査方法の効率・非効率はあるかもしれませんが、PowerShellのパワーユーザーな方も似たような過程で解答に辿り着くと思っているのですが、どうなのでしょう?この手のレベルの問題なら、すらすらと書いてしまうのでしょうか?
メモでもしておかない限り、2週間後にこの問題を解く時に、私はまた上記のような調査過程を経て解答を得るでしょう。


【問4】名前がConfigureで始まるモジュール(Import-Module済み)がエクスポートしているコマンドを列挙せよ。

> Import-Module ConfigureWindows, ConfigureApps
> Get-Command -Module Configure*

CommandType   Name                          Definition
-----------   ----                          ----------
Function      Disable-Prefetch              ...
Function      Import-GoogleJapaneseInput    ...
... ...

ConfigureWindowsとConfigureAppsモジュールはあくまでも例です。


【問5】ni が何というコマンドのエイリアスなのか調べよ。

> Get-Alias ni
> gal ni

ni は New-Item、gal は Get-Aliasのエイリアスです。


【問6】Remove-Itemコマンドレットのエイリアスを列挙せよ。

> Get-Alias -Definition Remove-Item

CommandType  Name   Definition
-----------  ----   ----------
Alias        del    Remove-Item
Alias        erase  Remove-Item
Alias        rd     Remove-Item
Alias        ri     Remove-Item
Alias        rm     Remove-Item
Alias        rmdir  Remove-Item

Remove-Itemにはデフォルトで多くのエイリアスが割り当てられていますね。


【問7】Get-Dateコマンドレットの基本的なヘルプ情報を見たい。

> Get-Help Get-Date
> help Get-Date
> man Get-Date

Get-Helpはコマンドレット、helpは関数、manは help関数のエイリアスです。PowerShellコンソール上で help関数を使ってヘルプ情報を表示した場合、ページ分割して表示されます(PowerShell ISEではページングされない)。

基本的なヘルプ情報は以下でも表示できます。

> Get-Date -?

DOSコマンドのように /? ではない点に注意。


【問8】Get-Dateコマンドレットの使用例を知りたい。

> help Get-Date -Examples


【問9】Get-Dateコマンドレットについて、基本的なヘルプ情報に加えてパラメーターの説明とコマンドレットの使用例も表示したい。

> help Get-Date -Detailed

ほとんど使ってないです。


【問10】Get-Dateコマンドレットの完全なヘルプ情報を見たい。

> help Get-Date -Full


【問11】Get-Dateコマンドレットのオンライン・ヘルプ情報を見たい。

> help Get-Date -Online
  • 既定ブラウザにオンラインヘルプ情報が表示されます。
  • 自分はオンラインヘルプ情報を参照することが多いです。


【問12】エイリアスに関する About Help Topicである about_aliases を表示せよ。

> help about_aliases
  • About Help Topics は、PowerShellの概念的なトピック(パイプライン, 高度な関数、リモート, ...)に関する情報を提供します。
  • help about を実行すると About Help Topicsの一覧が表示されます。
  • help about_aliases -Online としてもエラーになって、オンラインのAbout Help Topicは表示されないのですね。


【問13】概要(SYNOPSIS)に「スコープ」というキーワードを含む About Help Topicsを列挙せよ。

> Get-Help about | where { $_.Synopsis -match 'スコープ' }

Name          Category  Synopsis
----          --------  --------
about_Return  HelpFile  現在のスコープ (関数、スクリプト、スクリプト ブロックなど) ...
about_scopes  HelpFile  Windows PowerShell のスコープの概念と...


【問14】Get-Dateの完全なヘルプ情報(Get-Help Get-Date -Full)を キーワード "unix" で検索し、キーワードを含む行をその前後2行も含めて表示したい。

> Get-Help Get-Date -Full | Out-String -Stream | Select-String -Pattern unix -Context 2,2
filter GLOBAL:grep($keyword, $context=(0, 0))
{
  $_ | Out-String -Stream | Select-String -Pattern $keyword -Context $context
}

プロファイルに上記フィルターを定義しておくと、次のように実行できます。

> Get-Help Get-Date -Full | grep unix 2,2

ただ、About Help Topicに対して grepすると

> Get-Help about_aliases | grep syslog

悲しい結果に・・・

※minminnanaさんにコメントを頂き、好みのエディタ(Vim)でヘルプ情報を表示するようにしたのですが、検索が簡単で断然いいですね。この【問題14】は、Out-String -StreamとSelect-Stringを連携したサンプル程度のものということで・・・


【問15】UseTransactionパラメーターを持つコマンドレットを列挙せよ。

> help * -Parameter UseTransaction

関数などは除外し、コマンドレットだけを表示したい場合は、-Categoryパラメーターに cmdlet を指定します。

> help * -Parameter UseTransaction -Category cmdlet

ちなみに、次を実行することでも同様の結果が得られます。

> Get-Command -CommandType Cmdlet | where { $_.parameters.keys -contains 'UseTransaction' }

help * -Parameterの方が楽ですね。


【問16】変数 $obj の参照先オブジェクトのクラス名を調べよ。

> $obj.getType().ToString()
> $obj.getType().FullName


【問17】変数 $now の参照先オブジェクトのメソッド&プロパティ(staticなものは除く)を Get-Memberコマンドレットを使って調べよ。

$now = Get-Date


> Get-Member -InputObject $now
> $now | gm
  • gm は Get-Memberのエイリアスです。
  • -InputObjectは ValueFromPipeline なパラメーター。すなわち、パイプラインからのデータをパラメーターとして受け取れます。
  • 各メソッドやプロパティの詳細を知りたい場合は、MSDN でクラス名をキーワードに検索し、当該ドキュメントを参照するといいです。


【問18】変数 $list の参照先オブジェクトが配列、ArrayListなどの場合、$list | gm を実行するとコレクション自身ではなく、それに含まれる要素についての情報が表示される。

> $list = (Get-Date), "Hello PowerShell"
> $list | gm

    TypeName: System.DateTime
    ... ...

    TypeName: System.String
    ... ...

Get-Memberを使って $list自身のプロパティ&メソッドを調べるにはどうしたらよいか?

> gm -InputObject $list

    TypeName: System.Object[]
    ... ...


【問19】.NET Frameworkの System.EnvironmentクラスにはどのようなStaticメソッド、Staitcフィールドが存在するのかGet-Memberコマンドレットを使って調べよ。

> [Environment] | gm -Static
> gm -InputObject ([Environment]) -Static

gm -InputObject [Environment] -Static は×
※[Environment]を()で囲えばできるとコメントを頂き、追記しました。


【問20】System.MathクラスにはどのようなStaticメソッド(フィールドは不要)があるのか Get-Memberコマンドレットを使って調べよ。

> [Math] | gm -Static -MemberType method

フィールドのみ対象としたい場合は、-MemberTypeパラメーターに property を指定します。

おわりに

初めてのAdvent Calendarへの参加、しかもまだ自分の道具にできていないPowerShellについてだったので、ちょっと緊張感を持ちながら書きました。このエントリが「使ったことないけど、PowerShellに興味がある」「最近使い始めたばかり」という方の後押しに少しでもなればうれしいのですが。
PowerShell Advent Calendar 2011は参加者をまだまだ募集中です。こんなスクリプト書いてみたとか、こんなこと調べてみたとかブログに書いて是非是非ご参加下さい。
明日は MSMVP for PowerShell@mutaguchi さんが担当です。楽しみです。