1. 説明
具体的には、WMIからWindows Storage Management APIにあるMSFT_PhysicalDiskクラスを利用する。ただし、このWindows Storage Management APIが使えるのはWindows 8(とWindows Server 2012)以降なので、完全にこれに頼れるものでもなく、ケースバイケースで。なお、管理者権限は不要。
初めにWMIでディスクのハードウェア的な情報を取得できるものとして、新しいMSFT_DiskとMSFT_PhysicalDisk、および従来からあるWin32_DiskDriveのプロパティをざっくり比較してみた。
この中でMSFT_PhysicalDiskのSpindleSpeedとMediaTypeにSSDの情報が含まれている。
- SpindleSpeed
文字どおりディスクの回転数で、これが0であればSSD。HDDで回転数の情報が取れればその回転数(RPM)、そうでなければUInt32の上限値が返ってくる。 - MediaType
これが3であればHDD、4であればSSD。情報が取れなければ0が返ってくる。
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で代替できると思う。