Windows PowerShell: スクリプトではなく、コマンドとして考える

スクリプトという言葉におじけ付かないでください。Windows PowerShell では、単純なコマンドを使用して、さまざまな処理を行えます。

Don Jones

Windows PowerShell は、管理者による受け入れという点で、受け止められ方に関して苦戦を強いられてきました。VBScript と同じように、シェルがスクリプト言語であるという認識は、なかなか消えません。さまざまな処理を行えるので、多くの管理者はスクリプト言語を重宝していますが、スクリプト言語の複雑さと必要な学習時間によりスクリプト言語を敬遠する管理者も多数存在しています。

これは残念なことです。シェルでは、堅牢なスクリプト ベースのアプローチがサポートされていますが、コマンド ベースのアプローチを使用した場合も、同じくらい便利です。シェルの最大の魅力は、同じタスクの実行に、どちらのアプローチも使用できることです。

単なるスクリプトです

次の関数ではコマンド ラインから入力したコンピューター名を文字列または入力オブジェクトの ComputerName プロパティとして受け取ります。また、Windows Management Instrumentation (WMI) を使用して各コンピューターから BIOS と OS の情報を取得します。

function Get-Inventory
{
   [CmdletBinding()]
   Param(
       [Parameter(Mandatory=$true,
                 ValueFromPipeline=$true,
                 ValueFromPipelineByPropertyName=$true)]
       [string] $computername
   )
   Process {
      $os = gwmi win32_operatingsystem -computername $computername
      $bios = gwmi win32_bios -computername $computername
      $obj = new-object psobject
      $obj | add-member noteproperty ComputerName $computername
      $obj | add-member noteproperty OSBuild ($os.buildnumber)
      $obj | add-member noteproperty SPVersion ($os.servicepackmajorversion)
      $obj | add-member noteproperty BIOSSerial ($bios.serialnumber)
      Write-output $obj
   }
}

かっこを使用することで、シェルでは式 ($os 変数に格納されているオブジェクトの BuildeNumber プロパティを取得するなど) を実行して、その式の計算結果を Add-Member コマンドレットのパラメーター値として渡しています。

この関数は、次のように具体的なコンピューター名をパイプ処理して実行することもできます。

'localhost','server2' | Get-Inventory

または、各行に 1 台のコンピューター名が記載されているテキスト ファイルのコンテンツを渡すことでも実行できます。

Get-Content names.txt | Get-Inventory

また、Active Directory からコンピューター オブジェクトを取得し、Name プロパティを ComputerName プロパティに変更して、プロパティをパイプ処理することもできます。

Import-Module ActiveDirectory
Get-ADComputer –filter * | Select-Object @{Label='ComputerName';Expression={$_.Name}} | Get-Inventory

ちなみに、ここでは中かっこを使用して実行可能コードをカプセル化しています。$_ プレースホルダーは、Select-Object コマンドレットにパイプライン処理されたオブジェクトを表しています。この処理の結果は、すべて 4 列の表形式で表示されます。この出力は、ファイル、プリンター、またはグリッドに簡単にリダイレクトできます。また、出力をフィルター処理して、出力を表示する前に並べ替えることもできます。次に例を示します。

Get-Content names.txt | Get-Inventory | Where { $_.BuildNumber –eq 7600 } | Sort ComputerName

ここでも、中かっこで実行可能なコード ブロック (フィルター処理する式) をカプセル化し、$_ プレースホルダーは、パイプライン処理されたオブジェクトを表しています。

コマンドのパフォーマンス

このようなスクリプトには何の問題もありませんが、高度な知識と技術が必要になります。これは、スクリプトを専門に記述している人やプログラマーが対応できるスタイルのアプローチで、多くの管理者がおじけ付くものです。ですが、少しだけ複雑な 1 つのコマンドを使用して同じ処理を実行できます。準備はいいですか。

Get-WmiObject Win32_OperatingSystem -computername (get-content names.txt) | 
Select-object @{Label="ComputerName";Expression={$_.__SERVER}},
             @{Label="OSBuild";Expression={$_.BuildNumber}},
             @{Label="SPVersion";Expression={$_.ServicePackMajorVersion}},
             @{Label="BIOSSerial";Expression={(gwmi win32_bios -comp $_.__server).serialnumber}}

このコマンドでは、多数の処理を行っています。少し詳しく説明しましょう。

  1. まず、Get-WmiObject コマンドレットを実行して、名前を指定したコンピューターから Win32_OperatingSystem オブジェクトを取得します。このコラムを定期的に読んでいただいている場合は、Get-WmiObject コマンドレットから返されるオブジェクトには、必ず __SERVER プロパティがあり、このプロパティに WMI オブジェクトの取得元コンピューターの情報が含まれていることはご存じでしょう。
  2. WMI オブジェクトは Select-Object コマンドレットにパイプライン処理されます。ここでは、ComputerName、OSBuild、SPVersion、BIOSSerial という 4 つのプロパティを定義するのに 4 つのハッシュテーブルを使用しました。各ハッシュテーブルでは、ラベル (Label) と数式 (Expression) を指定します (ラベルは、後で出力の列見出しとして使用します)。ハッシュテーブルは、@ 配列演算子を使用し、その後に Label と Expression を中かっこ内で定義することで構成されています。ハッシュテーブルの式の部分を定義する実行可能コードは、中かっこで囲んでいます。
  3. 最初の 3 列の式では、単にオブジェクトの既存のプロパティを参照して、プロパティの名前を変更しているだけです。
  4. 4 列目の式では、同じサーバーに対して別の WMI クエリを実行しています。この式では、__SERVER プロパティからコンピューター名を取得しています。WMI 呼び出し全体が中かっこで囲まれているのがおわかりになると思います。中かっこで囲まれた式は、強制的に最初に実行されます。この数式から返されるオブジェクトは、かっこで囲まれた部分に挿入されます。閉じるかっこの後にあるピリオドにより、式で返されたオブジェクトのプロパティにアクセスできるので、ここでは 4 列目の値として SerialNumber プロパティにアクセスしています。

ある意味では、この構文は、最初に紹介したスクリプトよりも解読が難しいかもしれません。コンパクトにまとまっていますが、多数の句読点を使用しています。ですが、これはテンプレートとして使用できる種類のコマンドなので、他のニーズに合わせて変更できます。コマンドが動作しない原因を特定できない場合は、私のブログ (ConcentratedTech.com、英語) に質問を投稿してください。そうしてくだされば、私が問題を解決するお手伝いをします。

スクリプトと呼ばないで

このコラムでお伝えしたかったのは、Windows PowerShell は、スクリプト言語として使用する必要がないということです。紹介したコマンドは複雑かもしれませんが、管理者が古き良き Cmd.exe シェルで実行するために記述していたコマンドの難易度と大差ありません。構文に慣れるには時間がかかりますが、慣れてしまえば、完全な機能を備えたスクリプトや関数を記述するよりも、コマンドはかなり簡単に使用できます。

スクリプト言語というだけで、シェルを拒否しないでください。Windows PowerShell は、単なる scripty です (scripty は愛情のこもったスクリプトの呼称です)。

Don Jones

Don Jones は、Concentrated Technology の創設者で、ConcentratedTech.com (英語) で Windows PowerShell や他のテクノロジに関する質問に答えています。また、Nexus.Realtimepublishers.com (英語) の創設者でもあり、このサイトでは、彼の多くの著書が無料でオンライン ブックとして提供されています。

関連コンテンツ