先日、仕事場の同僚から、「使っているPCに英語キーボードがつながっているか日本語キーボードがつながっているか調べる方ありませんか?」って尋ねられました。
実際に接続されているキーボードを調べることが出来るかどうかは知らないものの、USキーボードを使っている私は、キーボードレイアウトはレジストリに格納されていることを知っています。また、Powershell でレジストリを読み出せることも知っています。
つまり、出来そうって事。
では実際どうすればいいか?
答えは、対象PCの「HKLM:\SYSTEM\CurrentControlSet\Services\i8042prt\Parameters」というキーに格納されている、名前「LayerDriver JPN」のデータを読み取ればいいということ。
具体的には、Get-ItemProperty -path で対象キーの値を表示。(以下)
> Get-ItemProperty -path HKLM:\SYSTEM\CurrentControlSet\Services\i8042prt\Parameters
PollingIterations : 12000
PollingIterationsMaximum : 12000
ResendIterations : 3
WppRecorder_TraceGuid : {7ffb8eb8-2c86-45d6-a7c5-c023d9c070c1}
LayerDriver JPN : kbd101.dll
LayerDriver KOR : kbd101a.dll
OverrideKeyboardIdentifier : PCAT_101KEY
OverrideKeyboardType : 7
OverrideKeyboardSubtype : 0
PSPath : Microsoft.PowerShell.Core\Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\i8042prt\Parameters
PSParentPath : Microsoft.PowerShell.Core\Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\i8042prt
PSChildName : Parameters
PSDrive : HKLM
PSProvider : Microsoft.PowerShell.Core\Registry
実際やってみると、LayerDriver と JPN の間にスペースが入っている!
これ、どうやって指定するの?例えば、PSDriveのデータを知りたければ、
(Get-ItemProperty -path HKLM:\SYSTEM\CurrentControlSet\Services\i8042prt\Parameters).PSDrive
と書けばいいのですけど、PSDriveはひと続き。間にスペースがある名前はどう指定する?
試行錯誤した結果、名前をシングルクォートで囲めばいいって事のようです。変数にしてしまうという手もあるのかな〜?と思いましたけど、これは駄目みたい。
(Get-ItemProperty -path HKLM:\SYSTEM\CurrentControlSet\Services\i8042prt\Parameters).'LayerDriver JPN' kbd101.dll
これをリモートPCに対して行おうとすると、Invoke-Command で囲めばいいので、以下のような感じになるはず。ドメイン参加PCなら、認証は不要かもしれませんが、ワークグループだと、以下の赤部分、-Credential で管理者情報を入力しないとリモートレジストリの値は読み出せないかもしれません。
$c = Get-Credential $target = "pc_name" (Invoke-Command -ComputerName $target -Credential $c -ScriptBlock { Get-ItemProperty -path HKLM:\SYSTEM\CurrentControlSet\Services\i8042prt\Parameters }).'LayerDriver JPN'
あとは、読み出した値が、kbd101.dll か kbd106.dll かを判断すればいいってことになるはずです。
試してみると、一応値は読み出せましたが、invoke-command は実行が遅い遅い。
他にもっとスマートな方法があるかもしれませんが、今はこれ以上調べる気にならないので、これをメモしておくことにしました。