Windows – How to get physical partition name from iSCSI details on Windows

iscsipowershellwindowswmi

I've got a piece of software that needs the name of a partition in \Device\Harddisk2\Partition1 style, as shown e.g. in WinObj. I want to get this partition name from details of the iSCSI connection that underlies the partition. The trouble is that disk order is not fixed – depending on what devices are connected and initialized in what order, it can move around.

So suppose I have the portal name (DNS of the iSCSI target), target IQN, etc. I'd like to somehow discover which volumes in the system relate to it, in an automated fashion.

I can write some PowerShell WMI queries that get somewhat close to the desired info:

PS> get-wmiobject -class Win32_DiskPartition
NumberOfBlocks   : 204800
BootPartition    : True
Name             : Disk #0, Partition #0
PrimaryPartition : True
Size             : 104857600
Index            : 0
...

From the Name here, I think I can fabricate the corresponding name by adding 1 to the partition number: \Device\Harddisk0\Partition1Partition0 appears to be a fake partition mapping to the whole disk.

But the above doesn't have enough information to map to the underlying physical device, unless I take a guess based on exact size matching.

I can get some info on SCSI devices, but it's not helpful in joining things up (iSCSI target is Nexenta/Solaris COMSTAR):

PS> get-wmiobject -class Win32_SCSIControllerDevice
__GENUS             : 2
__CLASS             : Win32_SCSIControllerDevice
...
Antecedent          : \\COBRA\root\cimv2:Win32_SCSIController.DeviceID="ROOT\\ISCSIPRT\\0000"
Dependent           : \\COBRA\root\cimv2:Win32_PnPEntity.DeviceID="SCSI\\DISK&VEN_NEXENTA&PROD_COMSTAR...

Similarly, I can run queries like these:

PS> get-wmiobject -namespace ROOT\WMI -class MSiSCSIInitiator_TargetClass
PS> get-wmiobject -namespace ROOT\WMI -class MSiSCSIInitiator_PersistentDevices

These guys return information relating to my iSCSI target name and the GUID volume name respectively (a volume name like \\?\Volume{guid-goes-here}), but the GUID volume name is no good to me, and there doesn't appear to be a reliable correspondence between the target name and the volume that I can join on.

I simply can't find an easy way of getting from an IQN (e.g. iqn.1992-01.com.example:storage:diskarrays-sn-a8675309) to physical partitions mapped from that target.

The way I do it by hand? I start Disk Management, and look for a partition of the correct size, verify that its driver says NEXENTA COMSTAR, and look at the disk number. But even this is unreliable if I have multiple iSCSI volumes of the exact same size.

Any suggestions?

Best Answer

One possibility: if you can find the GUID volume name (your question doesn't make this clear) and if the volume has a drive letter assigned, then Win32_Volume will link the GUID volume name to the drive letter and Win32_LogicalDiskToPartition will link the drive letter to the disk number and partition number.

However, MSiSCSIInitiator_SessionClass looks to be a better option. This command works for me:

PS C:\Windows\system32> (get-wmiobject -namespace ROOT\WMI -class MSiSCSIInitiator_SessionClass -filter "TargetName='iqn.2001-05.com.equallogic:0-8a0906-d27481f06-93a000d015c4ed69-oslo-san-1'").Devices | Select -property LegacyName

LegacyName
----------
\\.\PhysicalDrive2

If there might be more than one partition, the Win32_DiskDriveToDiskPartition class can be used to list them.