Windows PowerShell Get-Enjoy コンテスト結果発表

受賞者の皆様、おめでとうございます。

昨年末から今年2月にかけて実施していた、
Windows PowerShell Get-Enjoy コンテスト」の結果が発表されました。


このコンテストは、Windows Server 2008に標準搭載されるPowerShellを盛り上げるために、
PowerShellスクリプトを募集し、「これは面白い」「これはすごい」という作品を表彰するものです。


私は作品の選考委員という立場で参加させて頂きましたが、
PowerShellの機能を、とことん引き出している作品が多く、驚かされました。
これは、PowerShellが徐々に浸透してきたということなのでしょう。


特に、グランプリの「ウィンドウの切り替え」は、
機能はシンプルですが、非常に多くのテクニックを使って作成されていますので、
ソースコードの一読をお勧めします。


ちなみに、私が一押しした「デリゲートを使用可能にするスクリプト」は、
C#やVBを使わずに、PowerShellの言語仕様の拡張に挑戦した、意欲的(マニアック)な作品です。
コメントがなくレビューア泣かせですが、こちらもソースコードを読んでみると面白いと思います。(^^;

UIテストの自動化をサポートするコマンドレット

UIテストの自動化

2007年12月のMSDNマガジンにPowerShellの記事が掲載されています。

ここでは、.NETアプリケーションに対して、「フォームやコントロールのハンドルを取得」したり「コントロールにクリックイベントを発生」させるコマンドレットが紹介されています。
これらのコマンドレットを利用すると、PowerShellからUIを操作して、UIテストを行うことができます。

コマンドレットの内部処理

コマンドレット内部では、P/Invokeを使用して以下のWin32APIをコールしています。

  1. FindWindow
  2. FindWindowEx
  3. SendMessage
  4. PostMessage
  5. GetMenu
  6. GetSubMenu
  7. GetMenuItemID

例えば、コントールの疑似クリック処理は、コントロールに対してPostMessageを使用し、

  • WM_LBUTTONDOWMメッセージ
  • WM_LBUTTONUPメッセージ

を順に投げることで実現しています。

あれ・・・

Get-Windowコマンドレットには、第1引数にフォームタイトル(文字列)を渡しますが、
5文字までという実装がされています。なぜー。(?_?;
不便なので、書き変えちゃいましょう。

Windows PowerShell 2.0 CTP(8)文字列から連想配列を生成する(ConvertFrom-StringData)


ConvertFrom-StringDataは、以下の形式の文字列から、連想配列を生成するコマンドレットです。

name=value

使用方法

ConvertFrom-StringData [-StringData] <String>

コンバート対象文字列をStringDataオプションに指定します。

サンプル:文字列変数から連想配列を生成する

$hereString = @'
BlogName=PowerShell Memo
BlogURL=http://d.hatena.ne.jp/newpops/
'@
$hash = ConvertFrom-StringData $hereString

上記は、まず、ヒア文字列として「name=value」形式の文字列変数($hereString)を定義しています。
その後、ConvertFrom-StringDataコマンドレットで連想配列に変換し、$hashに格納しています。

型を確認する
PS C:\> $hash.GetType().FullName
System.Collections.Hashtable

型は「System.Collections.Hashtable」ですね。

連想配列の内容を確認する
PS C:\> $hash

Name                           Value
----                           -----
BlogURL                        http://d.hatena.ne.jp/newpops/
BlogName                       PowerShell Memo

間違いなく、連想配列になっています。

サンプル:ファイルに書かれた文字列から連想配列を生成する

最初に以下の内容の「HashData.txt」を用意します。

HashData.txt
BlogName=PowerShell Memo
BlogURL=http://d.hatena.ne.jp/newpops/

HashData.txtを配置したディレクトリに移動し、以下を実行してみます。

Get-Content HashData.txt | %{$hash += ConvertFrom-StringData $_}

上記では、以下の処理を行っています。

  1. Get-ContentコマンドレットでHashData.txtを1行ずつ読み込みます
  2. 各行に対してConvertFrom-StringDataで連想配列に変換します
  3. 変換後の連想配列を$hash変数に追加します
連想配列の内容を確認する
PS C:\> $hash

Name                           Value
----                           -----
BlogName                       PowerShell Memo
BlogURL                        http://d.hatena.ne.jp/newpops/

こちらも、間違いなく、連想配列になっています。

Windows PowerShell 2.0 CTP(6)24個の新しいコマンドレット

コマンドレットが24個追加されています

Ver.1.0からVer.2.0 CTPへのバージョンアップに伴って、コマンドレットが24個追加されています。

追加されたコマンドレット
  1. ConvertFrom-StringData
  2. Disable-PSBreakpoint
  3. Enable-PSBreakpoint
  4. Get-PSBreakpoint
  5. Get-PSCallStack
  6. Get-PSJob
  7. Get-Runspace
  8. Import-LocalizedData
  9. Invoke-WmiMethod
  10. New-PSBreakpoint
  11. New-Runspace
  12. Out-GridView
  13. Receive-PSJob
  14. Remove-PSBreakpoint
  15. Remove-PSJob
  16. Remove-Runspace
  17. Remove-WmiObject
  18. Set-WmiInstance
  19. Start-PSJob
  20. Step-Into
  21. Step-Out
  22. Step-Over
  23. Stop-PSJob
  24. Wait-PSJob

本ブログ「PowerShell Memo」では、これらの新コマンドレットを順次紹介していこうと思います。

Windows PowerShell 2.0 CTP(7)コマンド出力をグリッドビューに表示する(Out-GridView)


Out-GridViewは、別ウィンドウを起動し、渡されたオブジェクトをグリッドビューに表示するコマンドレットです。
実行にはMicrosoft .NET Framework 3.0が必要です。

使用方法

Out-GridView [-InputObject <PSObject>]

InputObjectオプションに指定したオブジェクトをグリッドビューに表示します。
InputObjectオプションはパイプライン入力が可能なので、以下のような記述もOKです。

<PSObject> | Out-GridView

プロセス情報をグリッドビューに表示する。

Get-Process | Out-GridView
実行結果


オブジェクトのフィルタ

指定文字列によるオブジェクトのフィルタが可能です。
上図は、「win」を含むプロパティを持つオブジェクトでフィルタしています。

プロパティによるソート

ヘッダ表示部をクリックするとプロパティによるソートが可能です。
上図は、Handlesプロパティでソートしています。

Windows PowerShell 2.0 CTP(5)スクリプトコマンドレット2

スクリプトコマンドレットで、引数を必須指定にする

スクリプトコマンドレットで、引数を必須指定にする「Mandatory」パラメータを利用してみましょう。


以下は、引数に指定した2つの文字列をスペースで区切って表示するスクリプトコマンドレットです。
ただし、1つめの引数は必須指定にしています。

Cmdlet Write-Message
{
    Param ([Mandatory]$message1, $message2)
    Begin{}
    Process{Write-Host "$message1 $message2"}
    End{}
}
実行結果1:引数を2つ指定
PS C:\> Write-Message PowerShell 2.0
PowerShell 2.0
実行結果2:引数を1つ指定
PS C:\> Write-Message PowerShell
PowerShell
実行結果3:引数を指定なし

1つめの引数を指定するように促すメッセージが表示されます。
「Mandatory」パラメータを指定しているからですね。

PS C:\> Write-Message

cmdlet Write-Message at command pipeline position 1
Supply values for the following parameters:
message1:

Windows PowerShell 2.0 CTP(4)コマンドレットの調べ方

Get-Helpが利用できない?

Get-Helpはコマンドレットや構文のヘルプを表示するコマンドレットです。
ところが、Windows PowerShell 2.0 CTPをインストールし、以下を実行すると、

Get-Processのヘルプを調べる
Get-Help Get-Process

このようなエラーが表示されます。

Get-Help : Error loading help content for Get-Process from file "Microsoft.PowerShell.Commands.Management.dll-Help.xml"
. Details: Microsoft.PowerShell.Commands.Management.dll-Help.xml.
At line:1 char:9
+ Get-Help <<<<  Get-Process

非常に不便ですね。(^^;

エラーの原因

これは、日本語用のヘルプが見つからないためのエラーです。


XPまたはVista(私の場合はVista)の日本語版に2.0 CTPをインストールした場合、PowerShellは言語を「日本語」だと認識します。


Get-Cultureを実行して実行環境の言語を調べてみると、当然ですが日本語です。

PS C:\> Get-Culture

LCID             Name             DisplayName
----             ----             -----------
1041             ja-JP            日本語 (日本)


そのため、Get-Helpコマンドレットは、日本語環境用のヘルプを検索します。
しかしながら、Windows PowerShell 2.0 CTPは英語版であり、ヘルプは英語環境用にセットアップされるため、Get-Helpはヘルプを見つけることができず、エラーとなるのです。

対応策

以下のフォルダを、

%WinDir%\System32\WindowsPowerShell\v1.0\en-US

以下のようにリネームします。(「ja-JP」「ja」のどちらでもOKです)

%WinDir%\System32\WindowsPowerShell\v1.0\ja-JP
%WinDir%\System32\WindowsPowerShell\v1.0\ja


以上の対応により、Get-Helpでヘルプを表示することができるようになります。

補足:Windows PowerShell Graphical Help File (Version 2.0)

以下から、2.0 CTPのCHMヘルプファイルがダウンロードできます。
このファイルは、コマンドレット、トピックなどを簡単に閲覧できるので便利です。
検索もできますしね。