PowerShell.exeのここがおかしい!!

PowerShell.exeはデフォルトで用意されているPowerShellのホストなんですが、ちょっとおかしい、のではないかな? と思われる点があるので説明します。
PowerShellスクリプトから、現在のホストアプリケーションにアクセスするのには、$hostという組み込みの変数を参照します。PowerShell.exeはPSHostRawUserInterfaceまで実装してるので、$host.UI.RawUIも利用できます。$host.UI.RawUIにはこんな感じのメンバーがいます。カーソルを移動したり、背景色を変えたり、Windowのタイトルを変えたりもできます。
で、僕がおかしいのではないかと睨んでいるのは、このうちの、SetBufferContentsです。これは、ホストに対して、引数で与えたBufferCell(色を指定した文字のクラス)を表示するよう指示するメソッドです。


clear

$rui = $host.UI.RawUI
$buf = $rui.NewBufferCellArray(@("Battle Concert"), "Black", "Yellow")
$zero = New-Object System.Management.Automation.Host.Coordinates -ArgumentList 0, 0
$rui.SetBufferContents($zero, $buf)

このスクリプトでは、"Battle Concert"という、背景黄色の黒い文字列をホスト最上部に表示しています。

Battle Concert
こんな感じになると思います。これは正しい挙動です。
つぎに、先ほどの"Battle Concert"を"仲良しバトルコンサート"に変えると、

仲仲良良ししババトトル
こんな風になってしまいます。PowerTabで日本語のファイル名を補完しようとしたときにも同様の現象が起こります。
ここから先は、原因の推測です。実はBufferCellには文字、背景色、前景色の他に、BufferCellTypeというプロパティがあり、Complete、Leading、Trailingのいずれかの値を持つ、BufferCellType列挙型が保持されています。これは、ホスト上二文字分のスペースを使用する文字を区別するのに使います。基本的には、半角英数字はComplete、2バイト文字はLeading、Trailingの1セット、になります。実際、ためすとこんな感じです。

PS > $rui.NewBufferCellArray(@("x1殻"), "Black", "Yellow")

Character ForegroundColor BackgroundColor BufferCellType
--------- --------------- --------------- --------------
x Black Yellow Complete
1 Black Yellow Complete
殻 Black Yellow Leading
Black Yellow Trailing


このようにNewBufferCellArrayでは、きちんと、LeadingとTrailingを使用したBufferCellを返してくれます。また、LengthInBufferCellsという、文字列がBufferCell何個分の長さになるか計測するメソッドも用意されていて、これも仕様通りの値を返すようです。
問題なのはSetBufferContentsと、対になるGetBufferContentsです。これらは、LeadingもTrailingも無視します。BufferCellType一個につき、一個の文字を表示します。この場合、幅二つ分の文字を一つの値で表現していることになるので、当然二次元配列の後ろの方の列にある値は無視されます(表示できるスペースが奪われてしまっているため)。
ただ、GetBufferContentsも同じ挙動なので、画面のバッファを全部GetBufferContentsで取得して、それをそのままSetBufferContentsする、などの使用方法なら、問題なく動きます。