2014/04/30

SSDかどうかをWMIから判別する

SSDかどうかをC#から判別するではP/Invokeを使ったが、それよりハードルの低いWMIでもSSDかどうかを判別する方法はある(ことを知った)。

1. 説明

具体的には、WMIからWindows Storage Management APIにあるMSFT_PhysicalDiskクラスを利用する。ただし、このWindows Storage Management APIが使えるのはWindows 8(とWindows Server 2012)以降なので、完全にこれに頼れるものでもなく、ケースバイケースで。なお、管理者権限は不要。

初めにWMIでディスクのハードウェア的な情報を取得できるものとして、新しいMSFT_DiskMSFT_PhysicalDisk、および従来からあるWin32_DiskDriveのプロパティをざっくり比較してみた。
この中でMSFT_PhysicalDiskのSpindleSpeedとMediaTypeにSSDの情報が含まれている。
  • SpindleSpeed
    文字どおりディスクの回転数で、これが0であればSSD。HDDで回転数の情報が取れればその回転数(RPM)、そうでなければUInt32の上限値が返ってくる。
  • MediaType
    これが3であればHDD、4であればSSD。情報が取れなければ0が返ってくる。
ここまで分かれば、後は名前空間が従来の\root\CIMV2ではなく、\Root\Microsoft\Windows\Storageなので、それを明示的に指定する必要がある以外は従来のWMIと変わりない。

2. テスト

テスト用に作成したC#のコンソールアプリを、ThinkPad X230上のWindows 8.1で実行した結果。

1番目はUSBポータブルケースに入れたTravelstar 5K1000で、USB接続ではMediaTypeもSpindleSpeedも情報を取れなかった。2番目はUSBメモリで、これも情報を取れず。3番目は内蔵SSDで、これはMediaTypeとSpindleSpeedの両方でSSDという情報が取れた。

次にThinkPad X61s上のWindows 8で実行した結果。

1番目は内蔵HDDのTravelstar 7K1000で、MediaTypeはHDDという情報が取れたが、SpindleSpeedはなぜか情報が取れなかった。2番目と3番目のUSBメモリは両方取れなかった。

以上、とりあえず内蔵であればSSDかどうかの判別に使えると思う。

[追記] PowerShellから実行

WMIということは当然PowerShellからも実行できるわけで、例として以下のような感じ。
Get-WMiObject -namespace Root\Microsoft\Windows\Storage -class msft_physicaldisk | Select-Object FriendlyName,Model,MediaType | Sort-Object FriendlyName

これを実行したもの。MediaTypeが3であればHDD、4であればSSD。

問題なく取得できている。

3. BusType

SSDに限らないが、BusTypeについて、従来のWin32_DiskDriveのInterfaceTypeプロパティでは取れる情報が少なかったので、Win32のDeviceIoControlをIOCTL_STORAGE_QUERY_PROPERTYで実行してSTORAGE_BUS_TYPEを取得するようにしていたが、MSFT_DiskとMSFT_PhysicalDiskにはBusTypeプロパティがあるので、比較してみた。
一目瞭然だが、情報はほとんど同じで、MSFT_DiskがNVMeを取れるだけ優位にある。したがって、BusTypeに関しては条件が許せばMSFT_Diskで代替できると思う。

0 コメント :