はじめに
システム運用管理の現場ではソフトウェアのバージョン調査という作業が度々発生します。理想的には設計書などのドキュメントに記載されているはずですが、実機とドキュメント情報が乖離していることは少なくありません。そのため、例えばセキュリティパッチがリリースされれば適用要否を判断するために運用されている全サーバ(!)でバージョン調査を実施する必要に迫られるのです。
この記事では Windows OS に標準的に搭載されている .NET Framework について、レジストリから詳細なバージョン情報を取得する方法をまとめます。
課題
.NET Framework は Windows OS に標準的に搭載されているソフトウェアです。.NET Framework のバージョン情報は A.B.C.D 形式で表されますが、コントロールパネルの「プログラムと機能」からは確認できません。正確なバージョン情報を確認するためにはレジストリを見る必要があります。
.NET Framework のバージョン情報が格納されているレジストリキーは以下の通りです1。
HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\NET Framework Setup\NDP\{Version}
HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\NET Framework Setup\NDP\v4\Full
バージョン1から4の場合は、レジストリキーにバージョン番号({Version}
)が含まれています。面倒なことに、正確なバージョンを知るためにはバージョンの情報が必要になるのです。これは reg
コマンドでバージョン情報を取得しようとする場合に問題になります。なぜならインストールされる可能性のある全てのバージョンについて reg
コマンドを実行しなければならないからです。どのようなバージョン名のキーがあるのかを事前に把握しておくことは難しいので、網羅しようとする場合は for
コマンドが必要になります。
参考に for
コマンドを使う場合の例をあげます。
C:\> for /f "usebackq tokens=*" %k in (`reg query "HKLM\SOFTWARE\Microsoft\NET Framework Setup\NDP"`) do @(reg query "%k" | find "Version")
Version REG_SZ 2.0.50727.4927
Version REG_SZ 3.0.30729.4926
Version REG_SZ 3.5.30729.4926
一方で、バージョン4.5以上の場合は、レジストリキーは固定されています(ただし、キーに v4 が含まれるので今後 v5 が現れるかもしれません)。ただし、こちらはバージョンを表す数値(ID?)が格納されており、バージョンを知りたい場合は数値とバージョン番号の照合が必要です。
参考に、私の PC での実行結果を挙げます。
C:\> reg query "HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\NET Framework Setup\NDP\v4\Full"
HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\NET Framework Setup\NDP\v4\Full
CBS REG_DWORD 0x1
Install REG_DWORD 0x1
InstallPath REG_SZ C:\Windows\Microsoft.NET\Framework64\v4.0.30319\
Release REG_DWORD 0x60632
Servicing REG_DWORD 0x0
TargetVersion REG_SZ 4.0.0
Version REG_SZ 4.6.01586
上記の「バージョンを表す数値」が Release
であるという点に注意してください。reg
コマンドの出力結果には Version
が含まれていますが、そこには 4.6.0...
と表示されています。しかし Release
が示している(正確な)バージョンは 4.6.2
です2。
コマンドプロンプトを使う場合、reg
コマンドの結果から Release
の値を切り出し、照合してバージョン名を出力するには複雑なコマンドを使わざるを得ません。
解決方法
レジストリの情報を取得するには PowerShell を使うことができます。PowerShell はコマンドプロンプトと比較して、高級な構文を備えているため、複雑な処理でも読みやすく記述することができます。
以下は、.NET Framework のバージョン情報をレジストリから取得するための PowerShell スクリプトとその実行結果の例です。
ls -r "HKLM:\software\microsoft\net framework setup\ndp" | % {
$_.GetValue("Version") | ? { $_ } | % {
New-Object PSObject |
Add-Member NoteProperty -PassThru -Name "Type" -Value "Version" |
Add-Member NoteProperty -PassThru -Name "Value" -Value $_
}
$_.GetValue("Release") | ? { $_ } | % {
switch ($_) {
"378389" { $r = "4.5" }
"378675" { $r = "4.5.1 installed with Windows 8.1 or Windows Server 2012 R2" }
"378758" { $r = "4.5.1 installed on Windows 8, Windows 7 SP1, or Windows Vista SP2" }
"379893" { $r = "4.5.2" }
"393295" { $r = "4.6 installed on Windows 10" }
"393297" { $r = "4.6" }
"394254" { $r = "4.6.1 installed on Windows 10 Novermber Update" }
"394271" { $r = "4.6.1" }
"394802" { $r = "4.6.2 installed on Windows 10 Anniversary Update" }
"394806" { $r = "4.6.2" }
"460798" { $r = "4.7 installed on Windows 10 Creators Update" }
"460805" { $r = "4.7"}
"461308" { $r = "4.7.1 installed on Windows 10 Fall Creators Update"}
"461310" { $r = "4.7.1"}
"461808" { $r = "4.7.2 installed on Windows 10 April 2018 Update"}
"461814" { $r = "4.7.2"}
"528040" { $r = "4.8 installed on Windows 10 May 2019 Update"}
"528049" { $r = "4.8"}
default { $r = "Unknown: $_" }
}
New-Object PSObject |
Add-Member NoteProperty -PassThru -Name "Type" -Value "Release" |
Add-Member NoteProperty -PassThru -Name "Value" -Value $r
}
} | Sort -Unique -Property Value
Type Value
---- -----
Version 2.0.50727.4927
Version 3.0.30729.4926
Version 3.0.30729.8763
Version 3.0.4506.4926
Version 3.0.6920.4902
Version 3.5.30729.4926
Version 4.0.0.0
Version 4.6.01586
Release 4.6.2 installed on Windows 10 Anniversary Update
おわりに
.NET Framework は、レジストリにバージョン情報を持ち、且つバージョン情報の格納されるキーの規則が複雑でした。しかし PowerShell の特性を利用して、シンプルなスクリプトでバージョン情報を列挙することができました。