Windows PowerShell と WPF
Windows PowerShell で WPF アプリケーションを構築する秘訣
Doug Finke
Windows PowerShell には、新しい種類のタスク オートメーションの機能が用意されています。この機能は、古いテクノロジを強化するものでも、置き換えるものでもありません。Windows PowerShell (以下、簡潔に「PowerShell」と表記) を使用する場合、この機能を利用するためにアプリケーションを作り直すことはありません。PowerShell を使用することで、既存のアプリケーションとシームレスに統合し、拡張することが可能です。
PowerShell は、コマンド ライン インターフェイス (CLI)、スクリプト言語、および API から構成されるオートメーション テクノロジです。
この記事では、PowerShell の主要技法を詳しく説明し、GUI に Windows Presentation Foundation (WPF) を使用した現在価値計算機 (http://ja.wikipedia.org/wiki/%E7%8F%BE%E5%9C%A8%E4%BE%A1%E5%80%A4) を作成します (図 1 参照)。
図 1 PowerShell の現在価値計算機
ここでは、WPF PowerShell Kit (WPK)、オブジェクト パイプライン、関数、プロパティ付きの PSObject、Microsoft .NET Framework とのシームレスな統合、モジュールなど、PowerShell の重要な要素をいくつか紹介します。
PowerShell は .NET Framework を基盤とするため、他の .NET 言語と同様、.NET Framework に無理なくアクセスできます。また、サービス、プロセス、Windows Management Instrumentation (WMI) など、Windows OS のその他の機能や OS のコンポーネントにもアクセスできるほか、(同じく、PowerShell 2.0 と Windows Remote Management が有効な) リモート サーバーにもアクセスできます。
これらはすべて、PowerShell が公開する新しいスクリプト言語を使用して実現できます。必要なものは、メモ帳と少数の PowerShell コマンドレットだけです (コマンドレットとは PowerShell 環境で使用する軽量のコマンドです)。すばらしいことに、これらはすぐに使えます。コマンドレットは PowerShell に組み込まれ、メモ帳は Windows に付属しています。主なコマンドレットには、次の 3 つがあります。1 つは Get-Help で、PowerShell のコマンドと概念についての情報を表示します。2 つ目は Get-Command で、コマンドレットや PowerShell コマンドのその他の要素についての基本情報を取得します。3 つ目は Get-Member で、オブジェクトの "メンバー" (プロパティやメソッド) を取得します。
いずれも情報検索関連の機能で、新しいタスク オートメーション プラットフォームを操作する際に役立ちます。
はじめに
質問: "Hello World" というラベルのある WPF アプリケーションの作成には、何行のコードが必要ですか。
解答: PowerShell と WPK を使用すれば 2 行 (図 2 参照) です。
図 2 2 行の PowerShell WPF アプリケーション
これは、2 行の PowerShell で記述された完全な WPF アプリケーションです。1 行目の Import-Module WPK は WPK パッケージをインポートします。このパッケージには、WPF をラップする PowerShell コマンドレットのセットが含まれています。興味深いことに、Visual Studio、XAML、または C# がなくても、これは機能します。ただし、WPK はインストールする必要があります (次のセクション参照)。
PowerShell 2.0 は Windows 7 と Windows Server 2008 R2 に標準で付属しています (それ以前の Windows システムをお使いの場合はダウンロードが可能です)。クライアント OS とサーバー OS のリリースと同時に、WPK が含まれる PowerShell Pack も (個別のダウンロードとして) リリースされました。これは、よく使用される Unix スクリプト ツールの Tcl/Tk を見習っています。
まず、PowerShell 変数の簡単なセットを作成し、最終的に対話型の WPF アプリケーションを構築します。ここでは、PowerShell Integrated Scripting Environment (ISE) を使用します。
作業の準備
Windows 7 をお使いの場合は、ほぼ作業に着手できる状態です (PowerShell は組み込まれています)。
Windows 7 をお使いでなければ、それ以前の OS 用の PowerShell をダウンロードして、インストールします。必ず、OS にとって適切なダウンロードを選択してください。Windows Management Framework Core パッケージ (bit.ly/9POYjq、英語) を参照してください。
また、OS のバージョンに関係なく、WPK (bit.ly/dFVpfL、英語) もダウンロードしてインストールする必要があります。Windows 7 Resource Kit の一部である WPK には、PowerShell ISE で使用される ISE Pack など、他に 9 つの PowerShell モジュールが含まれています。PowerShell ISE は PowerShell 2.0 に標準で付属しています。ISE Pack は学習用リソースとしても非常に優れていて、複数のレベルで ISE をカスタマイズする方法がわかります。
PowerShell を起動したら、Set-ExecutionPolicy RemoteSigned というコマンドレットを実行します。既定では、PowerShell はスクリプトを実行しないように設定されています。これは、セキュリティ機能の 1 つで、PowerShell ユーザーがこの設定を変更する必要があります。Set-ExecutionPolicy を実行するには管理者権限が必要なので、PowerShell のプログラム ファイルを右クリックして [管理者として実行] をクリックすることによって、明示的に PowerShell を管理者として実行する必要があります。
付属のコード ダウンロードをダウンロードし、スクリプトを解凍します。アプリケーションを実行する最も簡単な方法は、ISE で実行することです。Windows 7 では、[スタート] をクリックし、「ISE」と入力します (注: PowerShell スクリプトをダブルクリックしても実行できません。PowerShell スクリプト ファイルの拡張子は .ps1 です。最も簡単にサンプル スクリプトを実行するには、ISE を起動し、[ファイル] メニューの [開く] を使用してスクリプト ファイルを開きます)。
PowerShell 入門
現在価値計算機を作成します。これは簡単な数式です (図 3 参照)。
図 3 現在価値の計算
PowerShell の変数の先頭には $ を付けます。7 行目で直接 .NET Framework を使用し、System.Math 名前空間の静的メソッド Pow を呼び出しています。Pow メソッドは、指定された数値を指定された指数で累乗した結果を返します。静的 .NET メソッドの呼び出しに必要な構文は、クラスを角かっこで囲み、2 つのコロンを続けて、メソッド名を指定します。たとえば、[System.Math]::Pow(2,3) のように指定します。これを ISE で実行する場合は、F5 キーを押す (か、[実行] ボタンをクリックする) と、出力ウィンドウで結果を確認できます。また、このコードをコピーして PowerShell コマンドライン コンソールに貼り付けても、コードが実行されて、結果が出力されます。
これは、最初のアプリケーションとしてはよくできていますが、再利用性は高くありません。このまま繰り返し新しい値を入力してスクリプトを実行することもできますが、他のスクリプトからも呼び出せるようにします。出力を変えることができ、スクリプトが対話型になるように、function キーワードを追加し、変数をパラメーターに変換します (図 4 の 2 行目を参照)。
図 4 PowerShell 関数の作成
Function キーワードを追加する
関数の名前は Get-PresentValue にします。関数に名前を付けるときは、"動詞-名詞" という PowerShell の名前付け規則に従うことをお勧めします。これは、PowerShell を使用し、PowerShell 向けの開発を行う際の基本的な考え方です。PowerShell には、Get、Invoke、New、Remove など、定義済みの動詞があります (すべての定義済み動詞を確認するには「Get-Verb」と入力します)。「Get-Command」と入力すると、非常に長い一覧になりますが、PowerShell セッションで定義されているすべてのコマンドレット (と詳細情報) が表示されます。
関数の作成は簡単で、「function Get-PresentValue {}」と入力するだけです。次に、既定値と関数の本体を指定してパラメーターを作成します (図 4 参照)。
図 3 と図 4 を比べると、変数 (名前と値の両方) が 1 行に書き換えられています。変数はコンマで区切り、かっこで囲んで関数名の後ろに配置し、その関数のパラメーターにしています。これらのパラメーターには、現在、既定値があります。現在価値の計算には、手を加えていません。PowerShell の基本原則は "少ない入力" です。図 4 の 3 行目で、return ステートメントを使用することもできました。これを省略しても動作は変わりません。ただし、ロジックのフローを中断するために return ステートメントが必要になることもあります。
この例では、Get-PresentValue 関数を呼び出す方法をいくつか紹介します。1 つ目はパラメーターを指定しないで、すべてのパラメーターに既定値を適用しています。次に、パラメーターを位置で指定 (図 4 の 8 行目を参照) し、最後に名前を指定して (9 行目を参照) 渡しています。PowerShell のパラメーターについては、詳細を確認することをお勧めします。PowerShell は強力なパラメーター バインド エンジンをサポートしています。
次に、簡単なテキストではなく、.NET オブジェクトを返すように Get-PresentValue 関数を変更します。
PowerShell の基盤は .NET
PowerShell での重要な革新的機能の 1 つは、完全に型指定されるオブジェクトとしてデータを渡す機能です。図 5 は、PowerShell オブジェクトの作成、プロパティの設定、オブジェクトの戻し、PowerShell エンジンによる出力の概念を示しています。
図 5 PowerShell 関数からの完全に型指定されたオブジェクトを返す
6 行目では、.NET Framework オブジェクトのインスタンスを作成する New-Object コマンドレットを使用しています。作成するオブジェクトの型 PSObject をこのコマンドレットに指定し、PowerShell 環境内のオブジェクトの表示に一貫性をもたせます。6 行目では、ハッシュ テーブルを受け取る -Property パラメーターも使用しています。PowerShell でのハッシュ テーブルの略式構文は @{} です。ハッシュ テーブルに定義する (また、-Property パラメーターに渡す) キーと値のペアは、新しい PSObject のプロパティと値に変換されます。
最後に、15 行目で関数を呼び出しています。結果は出力ウィンドウ (ISE では青色の網掛けウィンドウ) で確認できます。PowerShell がオブジェクトの出力方法を "把握している" ことに注意してください。出力するプロパティや出力方法を特定するために、リフレクションを行う必要はありません。これは、PowerShell の重要な利点の 1 つです。
PowerShell の範囲とパイプライン
次は、PowerShell のパイプラインを使用して、さらに 2 つのコマンドレット、ForEach-Object と Format-Table を紹介します (図 6 参照)。
図 6 PowerShell の範囲とパイプライン
13 行目は説明のしがいがあるコードで、PowerShell の柔軟で組み合わせが容易な性質を知ることができます。ここでは 3 つのセクションと、2 つのパイプが定義されています。最初のセクションは範囲演算子 (2 つのピリオド) を表し、2 つ目のセクションは ForEach で、最後のセクションには Format-Table が含まれます。それぞれについて説明します。
最初のセクション、1000..1010: "1000..1010" は、1,000 から 1,010 までの整数配列を表します。PowerShell では、整数範囲が提供されるとすぐに、順次パイプラインに 1 つずつプッシュされるようになりました。PowerShell は、Unix/Linux ベースのシェルと同様、パイプラインを実装します。パイプラインでは、あるコマンドレットの出力を別のコマンドレットの入力としてパイプできます。PowerShell では、パイプラインは .NET オブジェクトから構成されます。オブジェクトを使用すると、すべてのオブジェクトが一貫性のあるインターフェイスをエクスポートするため、コマンドの任意のテキスト出力を解析してデータを抽出する必要がなくなります (bit.ly/lVJarT、英語)。
2 つ目のセクション、ForEach { Get-PresentValue $_ }: ここでは、スクリプト ブロックを受け取る ForEach (別名として % も使用) を使用しています。スクリプト ブロックは匿名メソッドのようなものです (他の言語ではラムダ式と呼ばれることもあります)。スクリプト ブロックの詳細については、Bruce Payette 著『PowerShell in Action, Second Edition』(Manning Publications、2011 年) を参照してください。
$_ は PowerShell の自動変数で、パイプラインにある現在のオブジェクトを保持します。最終的に、10 個の整数値から成る配列が、一度に 1 個ずつ Get-PresentValueに渡されます。パラメーターに名前を付けていないため、位置指定パラメーターとして $Amount にパラメーターが渡されます。図 6 の出力ウィンドウを参照してください。
最後のセクション、Format-Table: Format-Table は文字通り、出力をテーブル形式に整えます。ここでは、データの桁数に応じて列のサイズを調整するため、-AutoSize パラメーターを使用しています。
コレクション全体の繰り返しを管理していないこと、およびパイプラインにプッシュされるオブジェクトについて、PowerShell がその出力方法と出力内容を "把握している" ことに注意してください。このため、記述するコードの行数が少なくて済み、結果としてデバッグするコードの行数も少なくなります。今回の場合、デバッグに費やす時間が 90%、バグの記述に費やす時間が 10% なので、かなり有利な結果になっています。
GUI に取り掛かる — 第 1 ラウンド
今度は WPK を使用します。図 7 のスクリプトによって、図 8 の GUI が生成されます。型情報を Get-PresentValue 関数のパラメーターに追加しています (図 7 の 1 行目を参照)。これにより、この関数を使用する他のユーザーが、数値ではなく文字列など、誤ったデータを渡したかどうかを容易に確認できます。
図 7 WPK の New-ListView
図 8 GUI の表示
図 6 の基のコードの基本構造はそのままで、Get-PresentValue の呼び出しを ListView の DataContext に追加しています。DataContext は、データ アイテム セットの表示基盤を提供する WPF コントロールです。WPK の残りのコードは、WPF データバインドと統合し、ListView にビューを設定して、データを表示できるようにします。
WPK では、PowerShell の基本原則に従って、動詞-名詞の組を使用します。したがって、Window、Grid、Canvas、または ListBox を作成する場合は、先頭に "New-" を付けて New-Window、New-Grid、New-Canvas、または New-ListBox とすると、これらのフレームワーク要素を使用できるようになります。
Import-Module
モジュールは PowerShell で使用できるパッケージで、コマンドレット、スクリプト、関数、変数、その他のツールやファイルなどのメンバーを保持します。モジュールがインポートされると、モジュールのメンバーをセッションで使用できます。前述のとおり、WPK は PowerShell Pack に含まれ、WPK には、PowerShell 上に WPF GUI 層を簡単に階層化するための PowerShell 関数が 700 個あります。
これまでの WPF から考えると、図 7 の 17 行目と 18 行目は普通ではないように思えます。WPK は、DataContext と DataBinding の 2 つのパラメータを公開することで、データ バインドをサポートします。DataContext パラメーターはスクリプト ブロックを受け取るので、図 6 の 13 行目の 10 個の現在価値オブジェクトを作成する PowerShell コード行を渡します。次に、ListView の ItemsSource プロパティを設定して、18 行目にバインドします。DataBinding パラメーターはハッシュ テーブルを受け取ります (@{} に注意してください)。キーは、バインド先の GUI オブジェクトのプロパティ名です。
WPK は記述するコードを減らすうえで役立ちます。New-GridViewColumn 関数は、(Get-PresentValue 関数から渡されるオブジェクトのプロパティ名と同じ) Amount などの文字列を受け取り、それを Header に設定して、自動的にデータ バインドを実行します。
簡単な関数 Get-PresentValue から始めて、これにパラメーターを追加して再利用可能にし、.NET PowerShell PSObject を生成して、PowerShell オブジェクト パイプラインと範囲演算子を利用して現在価値アイテムを生成することで、最終的に図 8 の出力が得られました。次に、WPK をインポートして、PowerShell オブジェクトを WPF ListView コントロールの DataContext に挿入し、ItemsSource パラメーターをバインドして、挿入されたオブジェクトのプロパティ名と同じ列名を使って ListView ビューを作成しました。最終的に、PowerShell と WPK によるシンプルな現在価値アプリケーションが完成しました。これはよくできていますが、ハードコードされています。
次は、このアプリケーションを操作して、金額、利率、および他のパラメーターを変更することで、投資の結果を確認できるようにします。
GUI に取り掛かる — 第 2 ラウンド
現在の PowerShell および WPK のスクリプトでは、ユーザーがパラメーターを変更し、ファイルを保存して、スクリプトを返す必要があり、あまりすばやく処理はできません。
このスクリプトに手を加えて、GUI から 5 種類のパラメーターを調整し、ListView に新しい値を表示できるようにします。
New-Range 関数: まず、New-Range という関数を追加します (図 9 参照)。
図 9 New-Range 関数
PowerShell が提供する範囲演算子では、増分値を変えることができません。つまり、(1..10 by 2) のような指定はできません。New-Range 関数では、独自の増分値指定できるようにします。"New-Range 1 10 2" と指定すると 1 3 5 7 9 が出力されます。
次に、New-Window 関数で New-ListView をラップして、WPK GUI に肉付けします。New-ListView を使用するだけで、WPK は自動的にウィンドウにラップされます。New-Window を指定することで、より詳細な制御が可能になります (図 10 参照)。
図 10 New-Window 関数
また、DataContext を ListView から Window スコープに移動して、新しい関数 New-Range を適用します。今度は、5 つのテキスト ボックス、ラベル、および 1 つのボタンを追加します。これにより、アプリケーションを実行したまま、Get-PresentValue の出力を調整できます。WPK New-Grid、New-Label、New-TextBox、New-Button 関数を使用して、必要なコントロールを作成します。New-Grid を使用してグリッド コントロールを作成すると、ウィンドウのサイズ変更やコントロールの配置を柔軟に行うことができます。
GUI のレイアウトのため、グリッドとコントロール内にグリッドを入れ子にします。この場合も DataContext に New-Range 関数と Get-PresentValue 関数を使用します (図 11 の 2 行目を参照)。
図 11 New-Grid 関数
また、New-ListView も使用しています (図 11 の 30 ~ 37 行目)。30 行目に –Row と –Column の 2 つのパラメーターを追加し、5 行目で定義している New-Grid で、ListView が配置される行と列を指定しています。5 行目で定義している New-Grid では、Rows と Columns を使用して、グリッドをレイアウトします。2 つの列の幅を 75 ピクセルに、3 つの行の高さを 35 ピクセルにそれぞれ指定します。Rows パラメーターの 2 つ目の 75 の後にあるアスタリスクは、利用可能な領域をすべて使用することを示しています。
次に、ウィンドウに 5 組のラベルとテキスト ボックスを配置します。Row パラメーターと Column パラメーターによって、四分割したグリッドのどの位置にコントロールを配置するかを指定します。また、後でアクセスできるようにテキスト ボックスに名前を付け、-Text パラメーターによってこのテキスト ボックスに既定値を渡し、Margin パラメーターと HorizontalAlignment パラメーターによってコントロールの体裁を整えます。
最後に、New-Button 関数を使用してグリッドにボタンを配置します。Calculate の前にアンダースコアがあることに注意してください。これにより、Alt + C キーを押すことで、ボタンにアクセスできます。
現在価値計算機は、ほぼ完成です。クリック イベントを PowerShell コードにフックし、テキスト ボックスの値を読み取って、パラメーターとして Get-PresentValue に渡し、これを ListView にバインドする必要があります。
Do-Calculation 関数
$window パラメーターのみを受け取る Do-Calculation 関数を追加します (図 12 参照)。
図 12 Do-Calculation 関数
"_Calculate" コンテンツが指定されている New-Button の -On-Click プロパティから Do-Calculation を呼び出します。
Do-Calculation の動作はシンプルです。これは、すべてのテキスト ボックスの情報を取得し、その情報を PowerShell 変数に設定して、パラメーターとして New-Range 関数と Get-PresentValue 関数に渡します。ここでは $window パラメーター (図 13 の 2 行目) を渡しています。このパラメーターには、図 10 で作成した New-Window への参照が保持されています。これを使用して、ウィンドウのすべてのプロパティと子コントロール、つまりテキスト ボックスを取得できます。各テキスト ボックス コントロールに名前を付けているため、$window を Get-ChildControl にパイプできます。それには、テキスト ボックス コントロールの名前を渡し、.Text プロパティを使用して取得します (図 12 の 3~7 行目を参照)。
図 13 完成したグリッド
テキスト ボックスからすべての詳細情報を収集したので、Get-PresentValue にパイプする New-Range の結果に $window.DataContext を設定します。これにより、PresentValue の計算結果を保持する PowerShell オブジェクトの配列が生成されます (図 12 の 9 ~ 12 行目を参照)。
図 13 は、Do-Calculation 関数を呼び出し、$window 変数を渡すために、Calculate ボタンのクリック イベントがどのように関連付けられているかを示しています (28 ~ 29 行目)。ScriptBlock を受け取る -On_Click パラメーターを追加しています。このパラメーターで Do-Calculation 関数を呼び出し、New-Window 関数の使用時に自動的に作成された $window 変数に渡しています。ボタンをクリックするたびに、画面が再計算されます。また、Do-Calculation 関数も呼び出すように 図 13 では 2 行目も変更していることに注意してください。
スクリプト全体を参照するには、付属のソース コード サンプルに含まれる完成したアプリケーションをダウンロードしてください。
簡単な対話型 WPF アプリケーション
ここでは、マイクロソフトのオートメーション プラットフォームである PowerShell を基盤とした対話型の WPF アプリケーションを作成する、コードが 75 行にも満たないスクリプトを紹介しました。PowerShell は、スクリプト言語でもあり、コマンド ライン コンソールでもあります。.NET Framework と Windows の両方と密接に統合されているため、オートメーションのすばらしいチャンスを活かすことができます。もちろん、そのためには、この新しいプラットフォームの学習に時間をかける必要があります。さいわい、しきいの低いところから手を付けて生産性を上げて行き、その後、必要に応じて、マイクロソフトや一般の PowerShell コミュニティから提供される PowerShell の幅広いオートメーションに取り組むことができます。
アドホック開発モデルと Windows PowerShell の起源
Doug Finke の記事は、アド ホック開発モデルの格好の例です。PowerShell は、さまざまな点で他のプログラミング テクノロジと異なります。具体的には、高度なタスク指向の抽象化の重視、各種型システム (.NET、Windows Management Instrumentation [WMI]、XML、ADSI、ADO など) を標準化する適応性のある型システム、型やインスタンスにメンバーを追加できる機能、開発者が記述しなければならない API インピーダンス ミスマッチ コードの多くを不要にするデータフロー エンジン、アドホック開発モデルのサポートが PowerShell にはあります。
アドホック モデルでは、ラフな手法を使用して問題の解決にとりかかります。さらにこれを使用する場合は、ラフなスクリプトに変換し、このスクリプトを共有する場合は、スクリプトの形式を整えていきます。ツール開発者は、スキルが異なるユーザーに使用されるツールを開発することが多いため、利用者すべてのニーズと期待に沿えるようにすることが重要です。そこで、多くの場合、GUI を提供することになります。
Doug の記事では、まず、名前を付けていない、ハードコードされたスクリプトを使用して、特定の金額、固定利率、および固定時間で計算を行う PresentValue を生成しています。次に、このスクリプトを名前を付けた関数に変えて、単一の値を返す名前付きのパラメーターと初期値を設定しています。次に、オブジェクトを返し、他のツールから操作できるようにしています。最終的には、これをまず簡単な GUI に変え、その後、より充実した GUI に変更しました。手を加えるのは必要なときのみで、各スクリプトはその前のスクリプトよりもわずかに機能が追加されています。最後に、Doug は、他のユーザーも彼のツールを使用できるようにし、このツールをさらによくする方法についても提案しています (たとえば、提案として、文字列が渡された場合にツールがエラーにならないように、パラメーターの型を指定しています)。人は分かち合うことで恩恵を受けます。私は非常に便利なツールを手に入れ、Doug に借りができました。その恩返しの一環として、彼のコードを見直し、進言をしました。私には少しばかり PowerShell の知識がありますが、それでも私のスクリプトに対してコミュニティから提供されるすべての提案は大いに役立っています。[編注: Snover は、Windows PowerShell の生みの親で、Bruce Payette と James Truher と共に主任デザイナーの 1 人を務めています。bit.ly/696Jor (英語) を参照してください。]
アドホック開発モデルは、優れた対話型シェルであると同時に優れたスクリプト言語でもあろうとする PowerShell の目標から生まれています。Bruce Payette は PowerShell のデザイナーの 1 人で、かつて、PowerShell スクリプトの 99% の有効期間は、コマンド プロンプトに始まり、改行で終わると発言しています。PowerShell は、コマンド プロンプトで順次実行する対話型のスタイルから、$args を使用する Bash 型の関数、さらには、パラメーターに名前と型が指定され、検証、データ バインド、およびヘルプ属性が設定された、より形式的なスクリプトまで、さまざまなスクリプト スタイルをサポートしています。この方法をとったのは、莫大な量のシェル スクリプトを作成していた Unix 開発者としての私の長年の経験からです。自分が作成したスクリプトが使われて、さらに機能が求められると、そのスクリプトは捨てて、Tcl または Perl で作成し直していました。さらにそのスクリプトも捨てて、すべて C で書き直すこともよくありました。そこで、問題によって求められる形式化とパフォーマンスのレベルは異なるが、このような多岐にわたるスクリプト ニーズに対応できるツールがないのはおかしいと思うようになりました。そのようなツールがあれば、さまざまなツールで適当なスキルを身に付けるのではなく、そのツールの達人になるよう時間や労力を投資できるでしょう。少し時間はかかりましたが、ついにその目的を果たすツールをなんとか生み出すことができました。PowerShell を活用していただければさいわいです。
— Jeffrey Snover、Windows Server 担当ディスティングイッシュド エンジニア兼リード アーキテクト
Doug Finke は、Windows PowerShell の Microsoft MVP であり、金融業界向けの高度なアプリケーションを開発する企業 Lab49 のソフトウェア開発者です。過去 20 年にわたり、さまざまなテクノロジを対象に開発や執筆を行ってきました。近況はブログ Development in a Blink (dougfinke.com/blog、英語) で公開しています。
この記事のレビューに協力してくれた技術スタッフの James Brundage、Sal Mangano、Sivabalan Muthukumar、Marco Shaw、effrey Snover、および Sylvain Whissell に心より感謝いたします。