Retrieving Disk Number and SCSI ID for volumes using the Windows Powershell storage module

I was recently looking at obtaining volume information to include the volume name, capacity, free space, disk number and SCSI ID and to include information for both volumes that contained a drive letter or a folder path.

For instances running Windows 8 or Windows Server 2012 I was able to do this using a combination of retrieving WMI objects and using the Get-Partition cmdlet which is included in the storage module within these operating systems and then to export to a comma-separated values (CSV) file.

The requirement was to invoke the above agaisnt a collection of servers names, in this example I will be using a text file containing server names and loop through each one.

$Servers = Get-Content -Path "C:\Collection\Servers.txt" 
$Storage = ForEach ($Server in $Servers)
   {

I will then invoke, the Get-WMIObject cmdlet to query the Win32_Volume class to retrieve all local disks where the label is not equal to ‘System Reserved’.

$Volumes = Get-WmiObject  Win32_Volume -ComputerName $Server | Where-Object {$_.DriveType -eq "3" -and $_.Label -ne "System Reserved"}

For each volume returned I will loop through each volume to retrieve the volume information and select  the computer name, caption,  capacity and free space, to include in the output:

ForEach ($Volume in $Volumes)
   { 
   ""  | Select-Object -Property  @{N="Name";E={$Volume.PSComputerName}},
   @{N="Caption";E={$Volume.Caption}},
   @{N="Capacity (KB)";E={$Volume.Capacity}},
   @{N="Free Space (KB)";E={$Volume.FreeSpace}},

As I am initially using  the Win32_Volume to retrieve the volume information, I will not be able to return the disk number. In order to provide this information I used the Get-Partition cmdlet to compare the volume caption value returned and to filter the partitions retrieved by using the conditional operator function to return a match where the access path value was like the caption value.

@{N="Disk";E={Invoke-Command -ComputerName $Server -ScriptBlock {(Get-Partition | Where-Object {$_.AccessPaths -like $Using:Volume.Caption}).DiskNumber}}},

The final requirement is to include the SCSI ID by returning both the SCSI Port and TargetID of the volume. Again this information is not available from the Win32_volume class so as per the previous item, I will be able to return this information by retrieving the disk number using the Get-Partition cmdlet and then passing the disk number value returned to the Get-WMIObject to query the Win32_DiskDrive class and to return object where the Index value is equal to the disk number and then join both the SCSI Port and Target ID values.

@{N="SCSI Id";E={Invoke-Command -ComputerName $Server -ScriptBlock {
$Disk = (Get-Partition | Where-Object {$_.AccessPaths -like $Using:Volume.Caption}).DiskNumber
$SCSI = Get-WmiObject -Class Win32_DiskDrive | Where-Object {$_.Index -eq $Disk}
"$($SCSI.SCSIPort):$($SCSI.SCSITargetID)"}}}

Finally, I will export the information for all servers in the collections to a comma-separated values (CSV) file.

   {
{
$Storage | Export-Csv -NoTypeInformation -UseCulture -Path "C:\Output\VolumeInformation.csv"

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s