Windows PowerShellデータのフィルタ処理と書式設定を行う

Don Jones

Windows PowerShell は、ユーザーがそれほど多くの作業をしなくても、多くの貴重な情報を返すことができます。このことに疑いの余地はありません。たとえば、単純な Get-WMIObject コマンドレットを考えてみましょう。このコマンドレットを使用すると、ローカル コンピュータ上のサービスの一覧を返すことができます。既定のビューには、実行中のサービスの状態、名前、スタートアップ モードの一覧が表示されます。

このビューは、本質的には、サービス コンソールをコマンド ラインで表示したものです。Windows PowerShell™ により、このビューの取得が非常に容易になります。

ただし、サービスに関して入手できる有用な情報は、既定のビューに表示される内容よりも多く存在します。次のコマンドを実行してみてください。

$s = get-wmiobject win32_service
$s[0] | gm

コマンドの 1 行目からは、すべてのサービス (具体的には、Windows® Management Instrumentation (WMI) の Win32_Service クラスのすべてのインスタンス) のコレクションが返され、$s 変数に格納されます。2 行目は、そのコレクション内の最初のサービス (序数 0 が角かっこ内に示されています) を取得し、Get-Member コマンドレットにパイプ処理します。このコマンドレットは、そのエイリアス gm を使用して略してあります。結果の出力には、そのデータ型に使用できるすべてのプロパティとメソッドが示されます。ここでは、Windows PowerShell の組み込みの Get-Service コマンドレットではなく、WMI の Win32_Service クラスを使用することにしました。実際には、Microsoft® .NET ServiceController オブジェクトよりも WMI の方が、StartName プロパティを含む多くの情報を公開するためです。このプロパティは、サービスの実行に使用されているユーザー アカウントの名前を示します。次のコードを実行すると、1 つのインスタンス (最初のインスタンスなど) の名前を確認できます。

PS C:\> $s[0].StartName
LocalSystem

ただし、コレクション内の序数でサービスを参照しても、サービスは特定の順序になっていないため、あまり役立ちません (サービスは通常、アルファベット順に示されていますが、必ずしもそうとは限りません)。管理の観点からいうと、すべてのサービスの一覧や、各サービスのログインに使用されているアカウントに最も関心を持つことが考えられます。たとえば、これは規程遵守の監査に役立ちます。それでは、少し戻って、WMI が既定で提供しているものを見てみましょう。Get-WMIObject の短いエイリアス gwmi を使用します (図 1 を参照)。

Figure 1 gwmi を使用する

PS C:\> gwmi win32_service

ExitCode  : 0
Name      : AcrSch2Svc
ProcessId : 1712
StartMode : Auto
State     : Running
Status    : OK

ExitCode  : 1077
Name      : Adobe LM Service
ProcessId : 0
StartMode : Manual
State     : Stopped
Status    : OK

これは明らかに単なるサンプルですが、出力が管理用レポートにはまったく適していないことはわかります。知りたいのは、サービスの名前と StartName (サービスの実行に使用されているアカウント) です。また、この少し見た目の悪い一覧ではなく、もっと読みやすい形式のレポートが欲しいと考えています。ここで活躍するのが、Windows PowerShell の強力な書式設定コマンドレットとデータのフィルタ処理コマンドレットです。

必要なデータを取得する

まず、目的のプロパティが表示されるように、Get-WMIObject を使用してデータをフィルタ処理します。この処理を行うには、Windows PowerShell の Select-Object コマンドレットまたはその簡単なエイリアス select を使用することをお勧めします。select は、オブジェクトのコレクション (Get-WMIObject によって返されるコレクションなど) を受け取り、これらのオブジェクトの目的のプロパティだけを表示するように設計されています。つまり、gwmi の出力を select にパイプ処理し、目的の 2 つのプロパティを指定できます。図 2 は結果を示しており、表形式で適切に書式設定された Name プロパティと StartName プロパティが含まれています。

図 2 Name プロパティと StartName プロパティだけを表形式で表示する

図 2** Name プロパティと StartName プロパティだけを表形式で表示する **(画像を拡大するには、ここをクリックします)

ただし、規程遵守の監査についてこのレポートを作成すると、実際に含まれる情報が多すぎる結果になります。一部のサービスは無効になっているため、無効になっているサービスによって理論上使用されているアカウントは、出力を参照するどの人にとっても重要ではないでしょう。したがって、スタートアップの種類、つまり、Win32_Service クラスの StartMode プロパティが Disabled のサービスをすべて除外しようと考えています。

Windows PowerShell では、Where-Object コマンドレットまたはその短いエイリアス where を使用してオブジェクトのフィルタ処理を実行します。where コマンドレットは、入力オブジェクトのコレクションを受け取り、各オブジェクトをスクリプト ブロックで実行し、定義済みの一連の条件に基づいて各オブジェクトがコマンドレットの出力に表示されるかどうかを判断します。条件を満たしている各オブジェクトは、True を返すため、出力に含まれます。False 値を返すオブジェクトは含まれません。

ここでは、StartMode プロパティが Disabled のオブジェクトだけが必要であると判断しました。Windows PowerShell では、その評価は次のようになります。

$object.StartMode –eq “Disabled”

もちろん、$object は単なる例です。実際にスクリプトを書いているわけではないので、$object という変数はありません。ただし、where で使用されているスクリプト ブロック内では、$_ という名前の特殊な変数を使用しています。この変数は、現在コマンドレットで評価されているオブジェクトを表します。そのため、where スクリプト ブロックは次のようになります。

$_.StartMode –eq “Disabled”

これは、次のように簡単にテストできます。

PS C:\> gwmi win32_service | where 
{$_.StartMode -eq “Disabled”}

ExitCode  : 1077
Name      : Alerter
ProcessId : 0
StartMode : Disabled
State     : Stopped
Status    : OK

もちろん、この簡単なテストでは、出力が既定の一覧形式で表示されます。また、スペースを節約するために、ここではサービスを 1 つだけ含めました。しかし、この出力が適切ではないことに気付くでしょう。無効になっているサービスを除外するのではなく、含めてしまいました。これは、私がスクリプト ブロックを逆に理解したためです。この例は次のように変更することで、StartMode が Disabled ではないすべてのサービスを含める必要があります。

PS C:\> gwmi win32_service | where 
{$_.StartMode -ne “Disabled”}

ExitCode  : 0
Name      : AcrSch2Svc
ProcessId : 1712
StartMode : Auto
State     : Running
Status    : OK

これでうまくいくでしょう。これで出力には目的のサービスだけが含まれるので、もう一度出力を select にパイプ処理し、必要なプロパティだけを指定できます。

gwmi win32_service | where {$_.StartMode -ne “Disabled”} | select name,startname

あるコマンドレットから別のコマンドレット、さらに別のコマンドレットにデータをパイプ処理するこの作業は、実際には、Windows PowerShell の機能を示しています。スクリプトはまだ作成していませんが、大量のデータ セットをフィルタ処理して、求めている出力だけを取得することができました。

適切な見た目

select の出力が依然としてオブジェクトの集まりであることに注意してください。Windows PowerShell を使用して、適切に書式設定された表を取得すると、本当に PowerShell.exe がこれらのオブジェクトを返すことがわかります。つまり、Windows PowerShell は、単なる人間である私にはオブジェクトが見えないことを理解しているので、オブジェクトをテキストとして描画します。この場合、図 2 に示すように、オブジェクトを、各プロパティの列を含む表として描画しました。

監査目的の場合は、これで十分かもしれません。しかし、十分ではない場合もあります。人によってニーズは異なりますが、Windows PowerShell では特定のニーズを認識することを想定していません。代わりに、出力を最適な形式で書式設定するツールが用意されています。4 つの組み込みのコマンドレット (Format-List、Format-Custom、Format-Table、および Format-Wide) は、オブジェクトのコレクション (select によって返されるコレクションなど) を受け取り、さまざまな方法でこれらのオブジェクトの書式設定を行うように設計されています。Format-Table は、基本的には、Windows PowerShell が select コマンドレットの出力の書式設定に既に使用しているものです。別の見た目を参照するために、Format-List を試してみましょう。

gwmi win32_service | where {$_.StartMode -ne “Disabled”} | 
select name,startname | format-list

結果は、次のサンプルに少し似ています。

name      : AcrSch2Svc
startname : LocalSystem

name      : Adobe LM Service
startname : LocalSystem

Format-Wide コマンドレットは、既定では各オブジェクトの最初のプロパティを示す、複数の列から成る一覧を生成するように設計されています。たとえば、次の行を試してみます。

gwmi win32_service | where {$_.StartMode -ne “Disabled”} |
 select name,startname | format-wide

この結果、サービス名の一覧が生成されますが、これは求めているものではありません。出力には、監査レポートで必要としている重要な情報である、StartName (図 3 を参照) がありません。

図 3 Format-Wide コマンドレットを使用して表示された出力で重要な情報 StartName が除外されている

図 3** Format-Wide コマンドレットを使用して表示された出力で重要な情報 StartName が除外されている **(画像を拡大するには、ここをクリックします)

プロパティを 2 つしか扱っていないため、Format-Table または Format-List で満足できる可能性があります。ただし、監査担当者が画面上のこの情報を見て喜ぶとは考えられません。 おそらく、監査担当者は何らかのファイルが欲しいでしょう。

データをエクスポートする

では、監査担当者はデータをどのように表示したいのでしょうか。サービスとログイン名の一覧を CSV (コンマ区切り) ファイルに出力すれば、後から Microsoft Excel® で簡単に開くことができるため、満足すると考えられます。CSV ファイルを作成するには、出力を Windows PowerShell Export-CSV コマンドレットにパイプ処理するだけです。

gwmi win32_service | where {$_.StartMode -ne “Disabled”} | 
select name,startname | export-csv c:\services.csv

確かに、現在では、CSV は少し時代遅れのように思えます。おそらく、監査担当者は、データがイントラネット サーバー上の Web ページとして表示されることを望むでしょう。Web ページとして表示するには、まず、ConvertTo-HTML コマンドレットを使用して、出力を HTML に変換します。

gwmi win32_service | where {$_.StartMode -ne “Disabled”} | 
select name,startname | convertto-html

未処理の HTML を表示するのは難しいため、出力をファイルに書き込む必要があります。

gwmi win32_service | where {$_.StartMode -ne “Disabled”} | 
select name,startname | convertto-html | out-file c:\services.html

図 4 に示されている結果は、適切に書式設定された HTML ページです。このページは、それ以上変更せずに、Web サーバー上に投稿できます。

図 4 適切に書式設定された HTML ページとして表示された出力

図 4** 適切に書式設定された HTML ページとして表示された出力 **(画像を拡大するには、ここをクリックします)

関連のある事実に絞る

Windows PowerShell を使用すると、さまざまな管理データにすばやくアクセスできます。ただし、そのデータが未処理の状態の場合、ビジネスの面で必ずしも役に立つとは限りません。

(where を使用して) データをフィルタ処理し、(select を使用して) 必要なオブジェクトのプロパティを選択し、適切な書式設定オプション (Format-Table や Format-List など) を適用することで、ほとんど手間をかけずに、簡単にこの管理データを有用な情報に変換することができます。その後、簡単に共有できるファイル形式にデータをエクスポートすることで、自分のデスクトップ以外でこの情報を取得し、貴重な情報を組織内の他の人々に伝達することができます。

Don Jones は SAPIEN Technologies のプロジェクトおよびサービスの責任者であり、『Windows PowerShell: TFM』(SAPIEN Press) の共著者でもあります。**Don に対するお問い合わせについては、彼の Web サイト (www.ScriptingAnswers.com) を参照してください。

© 2008 Microsoft Corporation and CMP Media, LLC. All rights reserved; 許可なしに一部または全体を複製することは禁止されています.