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

この連載の記事
-
第520回
PC
WindowsターミナルのPreview版 v1.25では「操作」設定に専用エディタが導入 -
第519回
PC
「セキュアブート」に「TPM」に「カーネルDMA保護」、Windowsのセキュリティを整理 -
第518回
PC
WindowsにおけるUAC(ユーザーアカウント制御)とは何? 設定は変えない方がいい? -
第517回
PC
Windows 11の付箋アプリはWindowsだけでなく、スマホなどとも共有できる -
第516回
PC
今年のWindows 11には26H2以外に「26H1」がある!? 新種のCPUでのAI対応の可能性 -
第515回
PC
そもそも1キロバイトって何バイトなの? -
第514回
PC
Windows用のPowerToysのいくつかの機能がコマンドラインで制御できるようになった -
第513回
PC
Gmailで外部メール受信不可に! サポートが終わるPOPってそもそも何? -
第512回
PC
WindowsのPowerShellにおけるワイルドカード -
第511回
PC
TFS/ReFS/FAT/FAT32/exFAT/UDF、Windows 11で扱えるファイルシステムを整理する -
第510回
PC
PowerShellの「共通パラメーター」を理解する - この連載の一覧へ












