Reputation: 56357
I like to know if there is any win32 class that can detect if a hard drive is eide or sata. Thanks in advance.
Upvotes: 1
Views: 12938
Reputation: 32170
@Richard's answer is fantastic, but it's a bit old and dated at this point.
His code can be significantly simplified on newer versions of Powershell (v3+). Further, on Powershell v6+ the old Get-WmiObject
command is no longer available at all. In both cases, you can use the Get-CimInstance
command and the Get-CimAssociatedInstance
command:
Get-CimInstance -ClassName Win32_DiskDrive -KeyOnly |
Get-CimAssociatedInstance -ResultClassName Win32_PnpEntity -KeyOnly |
Get-CimAssociatedInstance -ResultClassName Win32_IDEController |
Select-Object CreationClassName, DeviceID, Caption, Description |
Format-List
Get-CimInstance
works basically the same as Get-WmiObject
, though it has improved output in most cases. Get-CimAssociatedInstance
does all the obnoxious ASSOCIATORS OF
stuff you used to have to do manually with gwmi.
The -KeyOnly
parameter tells the commands earlier in the pipeline to on return the unique idenfiers for the objects they return. Since we just want the early commands in the pipeline to identify the hardware items there's no need to have those commands return anything else.
That said,the above is probably unnecessary on newer versions of Powershell that have Get-Volume
, Get-Partition
, Get-PhysicalDisk
or Get-Disk
. If you're on a newer version of Windows, you can probably just run Get-PhysicalDisk | Select-Object FriendlyName, BusType
. You can often get much better (though not necessarily perfect) attributes this way.
You can still use the CIM classes, but be aware that CIM mapping between the different newer CIM storage classes is complicated because it can represent quite complex arrangements, but it helps when you know most of them can go through MSFT_StorageSubSystem
.
For example this gives you the physical disks associated with drive C:
Get-CimInstance -Namespace ROOT/Microsoft/Windows/Storage -ClassName MSFT_Volume -Filter "DriveLetter='C'" -KeyOnly |
Get-CimAssociatedInstance -ResultClassName MSFT_StorageSubSystem -KeyOnly |
Get-CimAssociatedInstance -ResultClassName MSFT_PhysicalDisk |
Select-Object -Property FriendlyName, SerialNumber, MediaType, BusType, Size, OperationalStatus, ObjectID -Unique
Note that the namespace ROOT/Microsoft/Windows/Storage
must be specified on the first command because the new storage classes are not in the default namespace.
Here, the -Unique
parameter along with including the ObjectID
property on the physical disk is helping to ensure that the command is not returning duplicates due to how things are mapped. This is part of the "bad news" that Richard's answer discussed.
Upvotes: 1
Reputation: 126
I know, this queston is a little bit old, but what about using another WMI-Object:
Get-WmiObject -Class MSFT_PhysicalDisk -Namespace root\Microsoft\Windows\Storage | Select FriendlyName, MediaType, BusType
The BusType 2 stands for ATAPI, 3 for ATA and 11 means SATA. Some more are USB, SCSI oder SSD. According to Wikipedia (https://en.wikipedia.org/wiki/Parallel_ATA) ATA and ATAPI are both parallel interfaces (IDE / EIDE) for harddisks.
The object is available since Windows 7 as far as I know and delivers many interesting values.
Upvotes: 0
Reputation: 109005
As noted in the other answer the drive's caption (ie. model name) might include this information you can navigate the WMI objects associations until you get to a device with a more definitive name/caption/other property.
Keeping devmgmt.msc
open with View | Devices by Connection open while developing will make things easier.
The key to navigating the WMI object graph is "ASSOCIATORS OF" queries.
So (using lots of aliases and other shortcuts to make this easier: I would avoid this in something I plan to reuse):
gwmi win32_DiskDrive |
%{gwmi -query "ASSOCIATORS OF {$($_.__RELPATH)} where resultclass = Win32_PnpEntity"}
will get the Win32_PnpEntity
objects for each disk drive.
Repeating this on the first (for the purposes of exploration) disk drive to another level to find what kind of associations exist:
gwmi win32_DiskDrive |
%{gwmi -query "ASSOCIATORS OF {$($_.__RELPATH)} where resultclass = Win32_PnpEntity" |
%{gwmi -query "ASSOCIATORS OF {$($_.__RELPATH)}"}} | fl __CLASS,__RELPATH
shows a mix of WMI classes:
__CLASS : Win32_SystemDriver __RELPATH : Win32_SystemDriver.Name="disk" __CLASS : Win32_ComputerSystem __RELPATH : Win32_ComputerSystem.Name="hostname" __CLASS : Win32_IDEController __RELPATH : Win32_IDEController.DeviceID="PCIIDE\\IDECHANNEL\\4&5ECF4F&0&2" __CLASS : CIM_DataFile __RELPATH : CIM_DataFile.Name="c:\\windows\\system32\\drivers\\disk.sys" __CLASS : Win32_DiskDrive __RELPATH : Win32_DiskDrive.DeviceID="\\\\.\\PHYSICALDRIVE0"
The last of these is just navigating back to the disk drive, and every device is associated with a computer system. But that Win32_IDEController
object looks interesting.
It had a ProtocolSupported
property with values for different buses, but all instances here are 37 ("IDE"), and there are instances for both the controller channels and the controllers:
PS[64bit] C:\bin\PowerShell> gwmi win32_idecontroller | ft -auto -wrap caption,description caption description ------- ----------- ATA Channel 1 IDE Channel ATA Channel 0 IDE Channel ATA Channel 1 IDE Channel Standard AHCI 1.0 Serial ATA Controller Standard AHCI 1.0 Serial ATA Controller Standard AHCI 1.0 Serial ATA Controller Standard AHCI 1.0 Serial ATA Controller Standard Dual Channel PCI IDE Controller Standard Dual Channel PCI IDE Controller ATA Channel 0 IDE Channel ATA Channel 1 IDE Channel ATA Channel 2 IDE Channel ATA Channel 3 IDE Channel ATA Channel 4 IDE Channel ATA Channel 5 IDE Channel ATA Channel 0 IDE Channel
So it isn't going to be as easy as getting to a Win32_IDEController
.
Going back and expanding the Win32_IDEController
associated with Win32_PnpDevice
for my disk:
gwmi win32_DiskDrive |
%{gwmi -query "ASSOCIATORS OF {$($_.__RELPATH)} where resultclass = Win32_PnpEntity" |
%{gwmi -query "ASSOCIATORS OF {$($_.__RELPATH)} where resultclass = Win32_IDEController"}} |
fl Caption,Description
caption : ATA Channel 2 description : IDE Channel
So that's the SATA channel, will the channel be associated with the controller? And simplifying: the output of a foreach-object
doesn't need an inner pipeline:
gwmi win32_DiskDrive |
%{gwmi -query "ASSOCIATORS OF {$($_.__RELPATH)} where resultclass = Win32_PnpEntity"} |
%{gwmi -query "ASSOCIATORS OF {$($_.__RELPATH)} where resultclass = Win32_IDEController"} |
%{gwmi -query "ASSOCIATORS OF {$($_.__RELPATH)} where resultclass = Win32_IDEController"} |
fl __CLASS,__RELPATH.Caption,Description
This finds nothing, but a little exploring (capturing the __RELPATH
from one query to paste into another to keep pipeline under control) indicates that following the associations:
DiskDrive --> PnpDevice --> IDEContoller --> PnpDevice --> IDEController
should get the result. Avoiding looping (as the IDEController has two associated PnpDevice objects) is left as an exercise.
Once the true controller is reached, the caption will need to be parsed.
Repeating the query for controllers on another system gave three instances of Standard Dual Channel PCI IDE Controller
despite having four controller (1×IDE and 3×SATA), this might be related to the non-trivial mapping due to one running as RAID?
And of course SATA has essentially the same logical (programming) interface as IDE to make new hardware work with software (the same applies with PCI and PCI-Express) means the OS doesn't really need to know.
Upvotes: 9
Reputation: 25810
There is no straight way to find that. However, you can use the caption property of Win32_DiskDrive and parse it to see if you have a ATA or SCSI disk. On my system, SATA disk has a caption ST9500420AS ATA Device
.
The way you do this is:
Get-WMIObject -Class Win32_DiskDrive | Select Caption, Index
You can parse the Caption
property to find if it contains ATA or SCSI.
Upvotes: 2