PowerShellでスクリプトを作った
マイクロソフトのページがPowerShellだったので、PowerShellでスクリプト(といってもコマンドを並べたもの)を作った。ところがこれが少しハマってしまった。本質的な部分ではなく、CSVのエクスポートという部分だ。こういう情報は、CSVなどにしてExcelに放り込むに限る。重複の検出や削除、並べ替え、検索などが自由にできる。こういう大量の情報を吐くAPIの結果を分析するのにExcelは最適である。
ところが、get-CimInstanceコマンドが出力するオブジェクトと、レジストリを読み出してできるレジストリは同一ではない。PowerShellのExport-CSVコマンドは最初に出力したオブジェクトを覚えていて、追加するときにオブジェクトが違うとエラーになる。
「-Force」オプションで強制的に違うオブジェクトを出力させることもできるのだが、出力できるのは、最初のオブジェクトのプロパティと同じプロパティ名の情報だけだった。そういうわけで、なんだか出力がおかしいけど、Export-CSV使わずにコンソールで見ると何もおかしくないという状態で、問題はExport-CSVにあるということに気がつくまで半日かかった。
とりあえず解決方法として自分でカンマ区切りの出力としてCSVファイルを作成した。
$f="C:\temp\win32appInstall-ListFile.csv"
$p= "`"{0}`",`"{1}`",`"{2}`",`"{3}`",`"{4}`",`"{5}`",`"{6}`""
$o1=(Get-ChildItem -Path 'HKLM:SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall' | ForEach-Object { Get-ItemProperty $_.PsPath})
$o2=(Get-ChildItem -Path 'HKLM:SOFTWARE\WOW6432Node\Microsoft\Windows\CurrentVersion\Uninstall' | ForEach-Object { Get-ItemProperty $_.PsPath})
$o3=(Get-ChildItem -Path 'HKCU:SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall' | ForEach-Object { Get-ItemProperty $_.PsPath})
$o4=(Get-WmiObject Win32_Product)
#
$o1 | ForEach-Object {($p+",`"HKLMMS`"") -f $_.PSChildName,$_.Publisher,$_.DisplayName,$_.DisplayVersion,$_.installDate,$_.installlocation,$_.installsource } | Out-File -Encoding default $f
$o2 | ForEach-Object {($p+",`"HKLMWOW`"") -f $_.PSChildName,$_.Publisher,$_.DisplayName,$_.DisplayVersion,$_.installDate,$_.installlocation,$_.installsource } | Out-File -append -Encoding default $f
$o3 | ForEach-Object {($p+",`"HKCUMS`"") -f $_.PSChildName,$_.Publisher,$_.DisplayName,$_.DisplayVersion,$_.installDate,$_.installlocation,$_.installsource } | Out-File -append -Encoding default $f
$o4 | ForEach-Object {($p+",`"WMI`"") -f $_.IdentifyingNumber,$_.vendor,$_.name,$_.version,$_.installdate,$_.installlocation,$_.installsource } | Out-File -append -Encoding default $f
なお、これは常識かもしれないが、ExcelにCSVを読み込ませるとき、シフトJISコードにしないと、区切り位置がおかしくなることがある。仕様としてはBOM付きのUTF8をサポートしているはずなのだが、ときどき正しく読み込んでくれないことがある。タブや他の区切り文字を使うという手もあるのだが、こっちもExcelが読み込み時に勝手にセルに分割することもあれば、そうでないこともあって、面倒である。特に日本語が含まれる可能性がある場合、シフトJISのCSVにするのが一番確実な感じである。
CIMとレジストリで共通にあり、インストールされているアプリケーションを知るのに必要なプロパティの対応は、以下の表のようになる。リストのプログラムは、これを出力するようにした。なお、CSVの最後の欄は、情報ソースを示す。

出力をExcelで調べたところ、Cimから得た情報と「WOW」から得た情報は大半が重複しており、違いはわずかに3つ。そのうち1つは、何も情報が記録されておらず、エントリーだけだった。また、残り2つは、「Microsoft .NET Framework 3.5 Targeting Pack」の英語版と日本語版。これは、Visual Studioがインストールする開発時に利用するもので通常利用するプログラムではない。なので、実用的には、レジストリの値だけを調べれば十分そうだ。
CIMコマンド(Get-CimInstance)は、実行にかなり時間がかかる。前記のMicrosoftのページにも、「Win32_Product クラスはクエリ用に最適化されていません」との記述がある。このコマンドを実行すると、インストールされているパッケージの整合性のチェックが発生し、場合によっては修復も行なわれるらしい。ということで、面倒な感じである。
となると、前記の3つのレジストリだけを調べれば、Win32アプリケーションの情報が得られそうだ。たとえば、以下のリストのようにすれば、Publisherが「株式会社」で始まるアプリケーションだけを表示できる。
(Get-ChildItem -Path ('HKLM:SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall','HKLM:SOFTWARE\WOW6432Node\Microsoft\Windows\CurrentVersion\Uninstall','HKCU:SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall') | ForEach-Object { Get-ItemProperty $_.PsPath}) | Where-Object { $_.Publisher -like "*株式会社*" } | Sort-Object Publisher | Format-Table -AutoSize displayversion,displayName -GroupBy Publisher

この連載の記事
-
第471回
PC
Windowsのコマンドラインでエイリアスを使う -
第470回
PC
Windows用のパッケージマネージャー「Winget」 プレビュー版で機能が充実してきた -
第469回
PC
Windows Updateの27年 悪役だった頃から改良が進んで、徐々に目立たない存在に -
第468回
PC
2025年のWindowsどうなる!? Windows Insider Programの状況をあらためて見る -
第467回
PC
Copilot+ PCのNPUでカメラを処理する「Windows Studio Effects」 その内容や効果は? -
第466回
PC
PowerToysの最近の新機能には、複数アプリを指定位置に起動する「ワークスペース」や新規作成のカスタマイズがある -
第465回
PC
WindowsのPowerShellからBluetoothデバイスを調べる -
第464回
PC
Windows 10のサポート切れまで1年を切った さてWindows 10マシンをどうする? -
第463回
PC
Windows Terminal Preview版でSixelグラフィックスを実際に表示させてみる -
第462回
PC
Windows Terminal Preview版でSixelグラフィックスを扱う -
第461回
PC
Copilot+ PCを買ってみたが、「今焦って買う必要はない」のかもしれない - この連載の一覧へ