I recently wrote about retrieving hard disks and the SCSI ID using the storage module which is available in Windows 8 and Server 20012 operating systems (http://wp.me/p15Mdc-m7).
Now, how would we retrieve this information for operating systems below this version? Well I have a look into this using a selection of WMI methods to retrieve this information. There was one limititation in I this method in that I cannot retrieve this information for where disks have been configured as folders.
Again, we will work with a collection of servers in a text file and retrieve this information using the Get-Content cmdlet.
$Servers = Get-Content -Path "C:\Collection\Servers.txt" $Storage = ForEach ($Server in $Servers) {
From our collection of servers, we will invoke the Get-WMIObject cmdlet to query the Win32_LogicalDisk class to retrieve all the available logical disks on the server.
$LogicalDisks = Get-WmiObject -Class Win32_LogicalDisk-ComputerName $Server
For each logical disk returned we will loop through and pass the variable to the Win32_LogicalDiskToPartition class to match objects returned where the Dependent property is equal to the Path property of the logical disk.
ForEach ($LogicalDisk in $LogicalDisks) { $LogicalDiskToPartitions = Get-WmiObject -Class Win32_LogicalDiskToPartition -ComputerName $Server | Where-Object {$_.Dependent -eq $Using:LogicalDisk.Path}
If we look at the below output for both these properties you can see that we can match the values:
Get-WmiObject -Class Win32_LogicalDisk | Select-Object Path Path ---- \\SERVER1\root\cimv2:Win32_LogicalDisk.DeviceID="C:" \\SERVER1\root\cimv2:Win32_LogicalDisk.DeviceID="D:" \\SERVER1\root\cimv2:Win32_LogicalDisk.DeviceID="P:" Get-WmiObject -Class Win32_LogicalDiskToPartition | Select-Object Dependent Dependent --------- \\SERVER1\root\cimv2:Win32_LogicalDisk.DeviceID="C:" \\SERVER1\root\cimv2:Win32_LogicalDisk.DeviceID="D:" \\SERVER1\root\cimv2:Win32_LogicalDisk.DeviceID="P:"
For each match we will now invoke retrieve the disk number by using regular expression to retrieve the numerical identifier of the disk by retrieving the Antecedent property from LogicalDiskToPartition output and retrieving the string between the ‘Disk’ and ‘,’:
ForEach ($LogicalDiskToPartition in $LogicalDiskToPartitions) { $Disk= [regex]::match($LogicalDiskToPartition.Antecedent ,''(?<=Disk #).+(?=\,)'',"singleline").value.trim()
If we look at the Antecedent property output from the Win32_LogicalDiskToPartition class, we would retrieve 0,1 and 5 for the below using the regular expression.
Get-WmiObject -Class Win32_LogicalDiskToPartition | Select-Object Antecedent Antecedent ---------- \\SERVER1\root\cimv2:Win32_DiskPartition.DeviceID="Disk #0, Partition #1" \\SERVER1\root\cimv2:Win32_DiskPartition.DeviceID="Disk #1, Partition #0" \\SERVER1\root\cimv2:Win32_DiskPartition.DeviceID="Disk #5, Partition #0"
Now we will query the Win32_DiskDrive with the disk number returned where this matches the Index property and then retrieve the SCSIPort and SCSITargetID and join these properties
$SCSI = Get-WmiObject -Class Win32_DiskDrive -ComputerName $Server | Where-Object {$_.Index -eq $Using:Disk} $($SCSI.SCSIPort):$($SCSI.SCSITargetID)" } } }
By invoking the script block your output returned based on the above examples would be like:
2:0
2:1
2:5
In a future blog I will discuss how I bring both these methods together for retrieving disk information from servers using the WMI class and also retrieving virtual machine disk information in vSphere to match VMDK files to disks and volumes in the guest operating system.