May 23rd, 2005

How Can I Correlate Logical Drives and Physical Disks?

Hey, Scripting Guy! Question

Hey, Scripting Guy! How can I correlate logical drives and physical disks?

— LB

SpacerHey, Scripting Guy! AnswerScript Center

Hey, LB. We’ll make a deal with you: we’ll show you a script that can tell you which logical drives are found on which physical disks, and you promise not to say, “Wait, I don’t understand how this script works.” To tell you the truth, we’re not so sure that we understand how the script works, either. As you’ll see it’s a bit wacky, to say the least.

The problem is that there is no simple, straightforward way to retrieve the logical disks associated with a given physical disk. Instead, we have to use a couple of association classes (Win32_DiskDriveToDiskPartition and Win32_LogicalDiskToPartition) to figure out the relationship between logical drives and disks. There’s nothing wrong with doing this, except that association classes can be extremely confusing, and the code required to use them can be even more confusing. If you’re a relative newcomer to scripting, this might be a time when you just use the code without trying too terribly hard to understand it all.

Here’s the script:

strComputer = “.”
Set objWMIService = GetObject(“winmgmts:\\” & strComputer & “\root\cimv2”)

Set colDiskDrives = objWMIService.ExecQuery(“SELECT * FROM Win32_DiskDrive”)

For Each objDrive In colDiskDrives Wscript.Echo “Physical Disk: ” & objDrive.Caption & ” — ” & objDrive.DeviceID strDeviceID = Replace(objDrive.DeviceID, “\”, “\\”) Set colPartitions = objWMIService.ExecQuery _ (“ASSOCIATORS OF {Win32_DiskDrive.DeviceID=””” & _ strDeviceID & “””} WHERE AssocClass = ” & _ “Win32_DiskDriveToDiskPartition”)

For Each objPartition In colPartitions Wscript.Echo “Disk Partition: ” & objPartition.DeviceID Set colLogicalDisks = objWMIService.ExecQuery _ (“ASSOCIATORS OF {Win32_DiskPartition.DeviceID=””” & _ objPartition.DeviceID & “””} WHERE AssocClass = ” & _ “Win32_LogicalDiskToPartition”)

For Each objLogicalDisk In colLogicalDisks Wscript.Echo “Logical Disk: ” & objLogicalDisk.DeviceID Next Wscript.Echo Next Wscript.Echo Next

We told you it was weird-looking, didn’t we? It actually starts off innocently enough: we simply connect to the WMI service and then use the ExecQuery method to retrieve a collection of all the physical disk drives installed on a computer. We create a For Each loop to loop through the collection of disk drives and echo the values of the Caption and DeviceID properties.

Now it starts to get a little wild. The DeviceID – which uniquely identifies each disk drive – will have a value like this: \\.\PHYSICALDRIVE0. We’re going to use this value in a query, so we have to “escape” each \ with a second \. (Why? Because a single \ is a reserved character in WMI.) That’s what this line of code does:

strDeviceID = Replace(objDrive.DeviceID, “\”, “\\”)

After we do that we can then use this query to return all the disk partitions associated with the first physical disk drive on the computer:

Set colPartitions = objWMIService.ExecQuery _
    (“ASSOCIATORS OF {Win32_DiskDrive.DeviceID=””” & _
        strDeviceID & “””} WHERE AssocClass = ” & _
            “Win32_DiskDriveToDiskPartition”)

Believe it or not we’re making progress now; after all, we now have a collection of all the disk partitions found on the first drive. With the partitions in hand we set up a second For Each loop to iterate through these partitions; for each partition in the collection we then use this query to retrieve all of the logical drives found on those partitions:

Set colLogicalDisks = objWMIService.ExecQuery _
    (“ASSOCIATORS OF {Win32_DiskPartition.DeviceID=””” & _
        objPartition.DeviceID & “””} WHERE AssocClass = ” & _
            “Win32_LogicalDiskToPartition”)

All that’s left now is to set up a third For Each loop, this one to echo back all the logical disks found on the first partition of the first physical disk:

For Each objLogicalDisk In colLogicalDisks
    Wscript.Echo “Logical Disk: ” & objLogicalDisk.DeviceID
Next

We loop around and repeat the process for all the remaining partitions on disk 1, then loop back even further and repeat the process for any additional disk drives found on the computer. When you’re all done, you’ll get back a report similar to this:

Physical Disk: IC25N040ATMR04-0 — \\.\PHYSICALDRIVE0
Disk Partition: Disk #0, Partition #0

Disk Partition: Disk #0, Partition #1 Logical Disk: C:

Disk Parititon: Disk #0, Partition #2 Logical Disk: D:

Physical Disk: Memory Stick Slot — \\.\PHYSICALDRIVE1

As you can see, the first disk has three partitions and two logical drives: drives C and D. The second disk has no partitions or logical drives. (What, you think Microsoft would give the Scripting Guys computers that actually had two disk drives in them?)

Like we said, if you don’t follow all this, don’t worry about it. No one knows how hot dogs are made, either, and the truth is, you probably don’t want to know. Just slap some mustard and relish on the thing and enjoy. The same thing applies to this script (although possibly without the mustard and relish).

Author

0 comments

Discussion are closed.