ChrisAdkin
ChrisAdkin

Reputation: 1316

obtain disk serial number from drive letter

I would like to get the serial number, as in the serial number returned from the PowerShell Get-Disk cmdlet, associated with the drive letter of a windows volume. I'm strugling to find anything that will point me in the correct direction for how to do this. I can see that people have managed to do this on site this via WMI queries invoked from vbscript and c#, e.g.

private string GetDiskIndex(string driveLetter)
    {
        driveLetter = driveLetter.TrimEnd('\\');

        ManagementScope scope = new ManagementScope(@"\root\cimv2");
        var drives = new ManagementObjectSearcher(scope, new ObjectQuery("select * from Win32_DiskDrive")).Get();
        foreach(var drive in drives)
        {

            var partitions = new ManagementObjectSearcher(scope, new ObjectQuery("ASSOCIATORS OF {Win32_DiskDrive.DeviceID='" + drive["DeviceID"] + "'} WHERE AssocClass = Win32_DiskDriveToDiskPartition")).Get();
            foreach(var partition in partitions)
            {
                var logicalDisks = new ManagementObjectSearcher(scope, new ObjectQuery("ASSOCIATORS OF {Win32_DiskPartition.DeviceID='" + partition["DeviceID"] + "'} WHERE AssocClass = Win32_LogicalDiskToPartition")).Get();
                foreach (var logicalDisk in logicalDisks)
                {
                    if (logicalDisk["DeviceId"].ToString() == driveLetter) return partition["DiskIndex"].ToString();
                }
            }

        }

        return null;
    }

Is there an elegant way of doing this in PowerShell ?

Upvotes: 1

Views: 14549

Answers (4)

ProgramingEnthusiast
ProgramingEnthusiast

Reputation: 91

Get the list of all available drives

$d = (Get-PSDrive).Name -match '^[a-z]$'

For each of the drivers, extract the serial number

get-partition -DriveLetter $i | get-disk 

Complete working code

$d = (Get-PSDrive).Name -match '^[a-z]$'
Foreach ($i in $d)
{
  Write-Host $i". " -nonewline
  get-partition -DriveLetter $i | get-disk 
}

Ouput

E. 0 WDC WDS240G2XXX-00JHXX 19377B803XXX Healthy Online 223.57 GB GPT
F. 13 Seagate Backup+ Hub BK NXXQWHXX Healthy Online 7.28 TB GPT
G. 12 Seagate Backup+ Hub BK NAXX58XX Healthy Online 7.28 TB GPT

Upvotes: 0

Bacon Bits
Bacon Bits

Reputation: 32145

Pretty simple to duplicate your code with the CIM cmdlets:

$DriveLetter = 'C:'

Get-CimInstance -ClassName Win32_DiskDrive |
    Get-CimAssociatedInstance -Association Win32_DiskDriveToDiskPartition |
    Get-CimAssociatedInstance -Association Win32_LogicalDiskToPartition |
    Where-Object DeviceId -eq $DriveLetter |
    Get-CimAssociatedInstance -Association Win32_LogicalDiskToPartition |
    Select-Object -Property DiskIndex

If you just want the base unsigned integer value of DiskIndex, use -ExpandProperty DiskIndex instead.

This is useful if your version of Windows doesn't have Get-Partition or Get-Drive, but you do have PowerShell v3.0+.

Your code says you want the DiskIndex, which is what the above code does. However, your question says you want the SerialNumber. Here's how to get that:

Get-CimInstance -ClassName Win32_DiskDrive |
    Get-CimAssociatedInstance -Association Win32_DiskDriveToDiskPartition |
    Get-CimAssociatedInstance -Association Win32_LogicalDiskToPartition |
    Where-Object DeviceId -eq $DriveLetter |
    Get-CimAssociatedInstance -Association Win32_LogicalDiskToPartition |
    Get-CimAssociatedInstance -Association Win32_DiskDriveToDiskPartition |
    Select-Object -Property SerialNumber

Upvotes: 3

Robin
Robin

Reputation: 166

Try this:

$drive_serialnumber = Get-Partition -DriveLetter C  | Get-Disk | select-object -ExpandProperty SerialNumber
$drive_serialnumber.trim()

Use trim to remove the blank spaces.

Upvotes: 1

Olaf Reitz
Olaf Reitz

Reputation: 694

The WMI/CIM stuff could be done with powershell too. But you can also do:

get-partition -DriveLetter C | get-disk

Upvotes: 7

Related Questions