検索
連載

Windowsのバージョンを識別するために昔作ったスクリプトたち山市良のうぃんどうず日記(11)

Windows 8.1とWindows 8.1 Updateは、製品名もバージョン番号もビルド番号も同じ。スタート画面やタスクバーで簡単に識別できますが、プログラム的に識別したいこともあるでしょう。昔書いたスクリプトを修正して、作ってみました。

PC用表示 関連情報
Share
Tweet
LINE
Hatena
「山市良のうぃんどうず日記」のインデックス

連載目次

簡単なバッチファイルでできた、古き良き時代

 多数のWindows PCを管理したことがある人なら、Windowsのバージョンを識別するバッチファイル(.batや.cmd)やスクリプト(.vbsや.ps1)を一度は書いたことがあると思います。

 Windows 95やWindows 98、Windows NTが全盛の90年代後半なら、以下の「NTOR9X.BAT」のような簡単な分岐で、Windows 9xで実行したいコマンドとWindows NTで実行したいコマンドを一つのバッチファイルに記述し、ログオンスクリプトなどに仕込んでいたのではないでしょうか(画面1)。

@ECHO OFF
IF "%OS%" == "Windows_NT" GOTO WINNT
:WIN9X
REM (ここに Windows 95/98/Me 向けのバッチを記述)
ECHO このコンピューターは Windows 9x 系です。
GOTO END
:WINNT
REM (ここに Windows NT 向けのバッチを記述)
ECHO このコンピューターは Windows NT 系です。
:END
「NTOR9X.BAT」はWindows 9xで実行したいコマンドとWindows NTで実行したいコマンドを一つのバッチファイルに記述している
画面1
画面1 Windows 9x/NT時代のWindowsのカーネル系統識別バッチは、現在のWindowsでも正しく識別する。ただし、この識別はもう無意味

 このバッチファイルは、最新のWindows 8.1でも問題なく機能します。ただし、Windows 9x系は2000年のWindows Millennium Edition(Me)を最後に開発が終了し、今ではWindows NT系しか存在しないので、このような分岐は何の意味もありません。

WMIとWSHの登場で、より詳細に識別できるように

 2000年のWindows 2000、Windows Meの登場で、識別したいWindowsのバージョンが増えました。しかしながら、システム管理のための「WMI」(Windows Management Instrumentation)インターフェースと、スクリプトエンジン「WSH」(Windows Script Host)が新しいWindowsには標準搭載されたことで、WSHスクリプトを駆使して、Windowsのバージョンだけでなく、エディションやサービスパック(Service Pack)のレベルまで詳細に識別できるようになりました。

 WMIおよびWSHは、Windows 95/98やWindows NTにもダウンロード提供されたので、古いWindowsでも識別することができました。

 例えば、次の画面2のスクリプト「OSINFO.VBS」は、とある雑誌向けに2006年初めに書いた、Windowsのバージョンとエディションを識別するスクリプトです。

画面2
画面2 Windows 95からWindows Server 2003 R2までを識別する古いスクリプト(2006年初めに作成)は、最新のWindows環境でも奇跡的に正常な値を返した

 このスクリプトでは、WMIのWin32_OperatingSystemクラスのOSType、OSProductSuite、Caption、CSDVersionといったプロパティを参照して、Windows 95からWindows Meまでのバージョン、およびWindows NT 4.0、Windows 2000、Windows XP、Windows Server 2003、Windows Server 2003 R2までのバージョンとエディションを識別するように記述しています。

 長くなるのでコードの掲載は省略しますが、久しぶりにコードを見てみると「Windows NT Server 4.0,Terminal Server Edition」を識別するための例外処理も記述していました。

 この古いスクリプトをWindows 8.1の最新環境で実行してみたところ、問題なく正しい情報を表示しました。Windowsのバージョンやエディションを識別する方法は工夫次第でさまざまですが、このスクリプトでは識別のために特別な処理(文字列の編集など)が必要ないものについては、Caption(製品名)プロパティとCSDVersion(サービスパック)プロパティをそのまま使用したのが幸いしたようです。

こだわりすぎたスクリプトはこうなる!

 Windows Vistaが登場したときは、エディションの多さに戸惑ったものです。Windows Vistaは、Starter(日本市場では提供なし)、Home Basic、Home Premium、Business、Enterprise、Ultimateの全6エディションがラインアップされました。Windows Server 2008のエディションを含めると、このときに新たに仲間入りしたWindowsの数はさらに増えます。

 この状況に対応してかどうかは分かりませんが、Windows VistaおよびWindows Server 2008からは、Win32_OperatingSystemクラスのOperatingSystemSKUプロパティにセットされるSKU(Stock Keeping Unit)番号が利用できるようになりました。

 SKU番号は製品のエディションごとに異なるため、エディションを正確に識別することができます。Windows Vista以降のSKU番号は、以下のドキュメントで確認できます。ドキュメントには16進数で記述されていることに留意してください。OperatingSystemSKUプロパティには、10進数の値がセットされています。

 SKU番号は文字列ではなく数字なので、スクリプトでの使用にも適していると考え、その後、筆者が作成するWindows識別スクリプトではOperatingSystemSKUプロパティを用いるようになりました。OperatingSystemSKUとVersion(Windowsのバージョン番号)プロパティを組み合わせれば、識別できないバージョンやエディションはないと考えたのです。

 次の画面3のスクリプト「GETOSSKU.VBS」は、このような考えのもと、Windows VistaからWindows 8までのバージョンおよびエディション、およびWindows Thin PC(企業向けに無償提供されるシンクライアント用軽量OS、Windows SA特典の一つ)を正確に識別するように書いたスクリプトです。

画面3
画面3 筆者が2003年初めに書いたスクリプト。当時はまだリリースされていないWindows 8.1は識別できない

 こちらもコードの掲載は省略しますが、後で修正版のコードを紹介します。このスクリプトは正確性を求め、Versionプロパティを使用したことがあだとなりました。当時、まだリリースされていないWindows 8.1の正確なバージョン番号など分かるはずもないので、Windows 8.1を正しく識別できないのです。

ついでにUpdate 1の有無まで識別してみる

 スクリプト「GETOSSKU.VBS」のように、正確さ、細かさを追求すると、新しいWindowsのバージョンが登場するたびに、スクリプトの修正が必要になります。今では、Windows 8.1のバージョン番号が「6.3.9600」と分かっているので修正は簡単です。

 しかし、細かさが信条の筆者は、Windows 8.1 Updateの存在がどうしても気になります。Windows 8.1 Updateが適用されているか否かで、Windows 8.1のユーザーインターフェース(UI)は大きく異なりますし、仕様も変わっている部分があります。しかしながら、Windows 8.1 Updateで製品名、バージョン番号、ビルド番号が変わることはありません。サービスパックでもないので、CSDVersionプロパティやServicePackMajorVersionプロパティも使えません。

 以下のWindowsのヘルプページでは、Windows 8.1 Updateに更新済みであるかどうかを確認する方法として、スタート画面の右上隅のアカウント画像の横に「検索」ボタンが表示されているかどうかと説明しています(画面4)。スクリプトからこの「検索」ボタンの有無を確認することは非常に難しいでしょう。少なくとも、筆者は確認する方法を思い付きませんでした。

画面4
画面4 Windows 8.1 Updateに更新済みであるかどうかを確認する方法の一つは、スタート画面の右上隅にある「検索」ボタンの存在だ

 筆者のアイデアはこうです。Win32_QuickFixEngineeringクラスのHotfixIDプロパティを検索し、Windows 8.1 Updateの更新プログラムを示す「KB2919355」が存在するかどうかで判断するのです。

 以下のスクリプト「GETOSSKUV2.VBS」は、問題があった古いスクリプト「GETOSSKU.VBS」を修正して、Windows 8.1およびWindows 8.1 Updateに対応させものです(画面5)。さらに、ついでに32bit版か64bit版かの情報も追加してみました。参考までに全コードを掲載します。なお、Windows Serverのバージョンとエディションの識別はコードが長くなるため、割愛しました。

strComputer = "."  
Set objWMIService = GetObject("winmgmts:¥¥" & strComputer & "¥root¥cimv2")   
Set colItems = objWMIService.ExecQuery("Select * from Win32_OperatingSystem")
'↓ここから追加
Set colItems2 = objWMIService.ExecQuery("Select * from Win32_QuickFixEngineering")
'↑ここまで追加
For Each objItem in colItems 
  Select Case objItem.ProductType
    Case 1	'Workstation
      strVersion = "Windows Unkown Version"
      strEdition = " (Unkown Edition)"
      strServicePack = " (Unkonwn Service Pack)"
      If objItem.ServicePackMajorVersion = 0 Then
        strServicePack = " (RTM)"
      Else
        strServicePack = " (Service Pack " & objItem.ServicePackMajorVersion & ")"
      End If
      If InStr(objItem.Version, "6.0.") Then
        strVersion = "Windows Vista"
        Select Case objItem.OperatingSystemSKU
          Case 1 strEdition = " Ultimate"
          Case 2 strEdition = " Home Basic"
          Case 3 strEdition = " Home Premium"
          Case 4 strEdition = " Enterprise"
          Case 6 strEdition = " Business"
        End Select
      ElseIf InStr(objItem.Version, "6.1.") Then
        strVersion = "Windows 7"
        Select Case objItem.OperatingSystemSKU
          Case 1 strEdition = " Ultimate"
          Case 3 strEdition = " Home Premium"
          Case 4 strEdition = " Enterprise"
          Case 11 strEdition = " Starter"
          Case 65
                  strVersion = "Windows Thin PC"
                  strEdition = ""
        End Select
      ElseIf InStr(objItem.Version, "6.2.") Then
        strVersion = "Windows 8"
        Select Case objItem.OperatingSystemSKU
          Case 4 strEdition = " Enterprise"
          Case 48 strEdition = " Pro"
          Case 72 strEdition = " Enterprise Evalution"
          Case 101 strEdition = "" '無印
          Case 103 strEdition = " Pro with Media Center"
        End Select
      '↓ここから追加
      ElseIf InStr(objItem.Version, "6.3.") Then
        strVersion = "Windows 8.1"
        Select Case objItem.OperatingSystemSKU
          Case 4 strEdition = " Enterprise"
          Case 48 strEdition = " Pro"
          Case 72 strEdition = " Enterprise Evalution"
          Case 101 strEdition = "" '無印
          Case 103 strEdition = " Pro with Media Center"
        End Select
        For Each objItem2 in colItems2
          If objItem2.HotfixID = "KB2919355" Then
            If strServicePack = " (RTM)" Then
               strServicePack = " (Update 1)"
            End If
          End If
          If objItem2.HotfixID = "KBxxxxxxx" Then    '次の大きな更新が出たときに、それを識別したかったらKB番号をここに!
               strServicePack = " (" & objItem2.HotfixID & " 適用済み)"
          End If
        Next
      End If
      '↑ここまで追加↓ここから修正
      WScript.Echo strVersion & strEdition & strServicePack & " " & objItem.OSArchitecture
      '↑ここまで修正
    Case 2	'Domain Controller
      WScript.Echo "Windows Server (Domain Controller)"
    Case 3	'Server
      WScript.Echo "Windows Server"
  End Select
Next
「GETOSSKUV2.VBS」はWindows 8.1およびWindows 8.1 Updateを含め、全てのWindowsのバージョンおよびエディションを正確に識別するスクリプト。なお、コメント('↓↑)は「GETOSSKU.VBS」からの変更点(本スクリプトをコピー&ペーストして使う場合には、2行目の「\」を半角文字に変更してください)
画面5
画面5 Windows 8.1 Updateあり(画面左)となし(画面右)の環境で、修正版の「GETOSSKUV2.VBS」を実行したところ

 さて、ちまたでは次の大きな更新である「Windows 8.1 Update 2」や、Windowsの次のバージョンである開発コード名「Threshold」(Windows 9という名称になるのかどうかは不明)のウソかホントかよく分からないうわさが聞こえてくるようになりました。これらが登場したとき、スクリプト「GETOSSKUV2.VBS」は対応のための修正が必要になります。情報がない現時点では対応しようがありませんが、一応、識別したいような次の大きな更新がWindows 8.1 Update 1と同じように通常の更新プログラムとして提供されると予想して、コードに含めておきました。

※Windows 8.1 Update 2が8月にも提供されるとのうわさがありましたが、マイクロソフトはUpdate 2を提供する計画はないようです。


「山市良のうぃんどうず日記」バックナンバー

筆者紹介

山市 良(やまいち りょう)

岩手県花巻市在住。Microsoft MVP:Hyper-V(Oct 2008 - Sep 2014)。SIer、IT出版社、中堅企業のシステム管理者を経て、フリーのテクニカルライターに。マイクロソフト製品、テクノロジを中心に、IT雑誌、Webサイトへの記事の寄稿、ドキュメント作成、事例取材などを手がける。個人ブログは『山市良のえぬなんとかわーるど』。


Copyright © ITmedia, Inc. All Rights Reserved.

ページトップに戻る