locked
Getting serial no of hard disk. RRS feed

  • Question

  • i am currenly using this code to get the serial no of hard disk.

     Dim hddsn As String
            Dim query3 As New SelectQuery("Win32_DiskDrive")
            Dim search3 As New ManagementObjectSearcher(query3)
            Dim info3 As ManagementObject
            For Each info3 In search3.Get()
                hddsn = info3("SerialNumber").ToString.Replace(" ", "")
            Next

    this works fine, but the only issue is.( in case if more than 1 hard disk(internal or external) is there

    i want the serial no of only that hard disk(not partition) where my software is installed.


    Pradeep Yadav (Social MSDN)

    Saturday, April 6, 2013 7:50 AM

Answers

  • I think you can do that by finding which physical drive is associated with the partition: www.codeproject.com/Tips/399828/Get-a-list-of-physical-disks-and-the-partitions-on

    Also, on Windows 7 and below, the drive serial number returned by WMI has its characters swapped such that "ABCD" is returned as "BADC", so...

    Imports System.Globalization
    Imports System.Management
    
    Class Form1
    
        Public Class MyDriveInfo
            Property Name As String
            Property Serial As String
            Public Overrides Function ToString() As String
                Return (String.Format("Name: {0} Serial: {1}", Name, Serial))
            End Function
        End Class
    
        Function GetOsVersion() As Decimal
            Dim os = My.Computer.Info.OSVersion
            Dim parts = os.Split("."c)
            Dim ver = CInt(parts(0)) & "." & CInt(parts(1))
            Return Convert.ToDecimal(ver, CultureInfo.GetCultureInfo("en-GB"))
        End Function
    
        Function GetPhysicalDriveSerialNumbers() As List(Of MyDriveInfo)
            Dim info = New List(Of MyDriveInfo)
            Dim scope As New ManagementScope("\\" & Environment.MachineName & "\root\cimv2")
            Dim query As New SelectQuery("SELECT * FROM WIN32_DiskDrive")
            Dim queryResults As New ManagementObjectSearcher(scope, query)
    
            Dim sn = ""
            Dim osVersion = GetOsVersion()
    
            For Each mo As Management.ManagementObject In queryResults.Get()
                Dim di As New MyDriveInfo
    
                For Each prop As Management.PropertyData In mo.Properties
    
                    If prop.Value IsNot Nothing AndAlso prop.Name = "Name" Then
                        di.Name = CStr(prop.Value)
                    End If
    
                    If prop.Value IsNot Nothing AndAlso prop.Name = "SerialNumber" Then
    
                        ' Swap the characters if OS is Windows 7 or less
                        sn = CStr(prop.Value)
                        If osVersion <= 6.1D Then
                            Dim sn2 = ""
                            For i = 0 To sn.Length - 1 Step 2
                                sn2 &= sn(i + 1)
                                sn2 &= sn(i)
                            Next
                            di.Serial = sn2.Trim()
                        Else
                            di.Serial = sn.Trim()
                        End If
    
                        Exit For
    
                    End If
    
                Next
                info.Add(di)
    
            Next
    
            Return info
    
        End Function
    
        Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
            Dim serials = GetPhysicalDriveSerialNumbers()
            TextBox1.AppendText(String.Join(vbCrLf, serials))
    
        End Sub
    
    End Class

    EDIT: Although it worked for me with Windows 7, it doesn't retrieve the serial numbers on my Windows Server 2003 - nothing like a serial number appears in the PropertyData.

    HTH,

    Andrew



    • Proposed as answer by Carmelo La Monica Saturday, April 6, 2013 10:25 PM
    • Edited by Andrew Morton Monday, April 8, 2013 9:12 AM WS2003.
    • Marked as answer by Youen Zen Tuesday, April 23, 2013 7:08 AM
    Saturday, April 6, 2013 9:52 PM
  • Andrew - I had to change your code slightly because here, WMI returns a HEX string with the ASCII values of the serial number (and reversed)

    4457572D414D415A - Actual return
    57442D574D415A41 - Reversed
    W D - W M A Z A

    WMI is a great, inconsistent mystery to me........

    Here is the output: (X's for privacy & paranoia)

    Name: \\.\PHYSICALDRIVE1 Serial: OCZ-XXXXXXXX77E9XN4
    Name: \\.\PHYSICALDRIVE0 Serial: XXXXXXSH
    Name: \\.\PHYSICALDRIVE2 Serial: WD-WMAZAXXXXXXX

    The OCZ drive is my boot drive.

    • Marked as answer by Youen Zen Tuesday, April 23, 2013 7:08 AM
    Saturday, April 6, 2013 11:43 PM

All replies

  • I think you can do that by finding which physical drive is associated with the partition: www.codeproject.com/Tips/399828/Get-a-list-of-physical-disks-and-the-partitions-on

    Also, on Windows 7 and below, the drive serial number returned by WMI has its characters swapped such that "ABCD" is returned as "BADC", so...

    Imports System.Globalization
    Imports System.Management
    
    Class Form1
    
        Public Class MyDriveInfo
            Property Name As String
            Property Serial As String
            Public Overrides Function ToString() As String
                Return (String.Format("Name: {0} Serial: {1}", Name, Serial))
            End Function
        End Class
    
        Function GetOsVersion() As Decimal
            Dim os = My.Computer.Info.OSVersion
            Dim parts = os.Split("."c)
            Dim ver = CInt(parts(0)) & "." & CInt(parts(1))
            Return Convert.ToDecimal(ver, CultureInfo.GetCultureInfo("en-GB"))
        End Function
    
        Function GetPhysicalDriveSerialNumbers() As List(Of MyDriveInfo)
            Dim info = New List(Of MyDriveInfo)
            Dim scope As New ManagementScope("\\" & Environment.MachineName & "\root\cimv2")
            Dim query As New SelectQuery("SELECT * FROM WIN32_DiskDrive")
            Dim queryResults As New ManagementObjectSearcher(scope, query)
    
            Dim sn = ""
            Dim osVersion = GetOsVersion()
    
            For Each mo As Management.ManagementObject In queryResults.Get()
                Dim di As New MyDriveInfo
    
                For Each prop As Management.PropertyData In mo.Properties
    
                    If prop.Value IsNot Nothing AndAlso prop.Name = "Name" Then
                        di.Name = CStr(prop.Value)
                    End If
    
                    If prop.Value IsNot Nothing AndAlso prop.Name = "SerialNumber" Then
    
                        ' Swap the characters if OS is Windows 7 or less
                        sn = CStr(prop.Value)
                        If osVersion <= 6.1D Then
                            Dim sn2 = ""
                            For i = 0 To sn.Length - 1 Step 2
                                sn2 &= sn(i + 1)
                                sn2 &= sn(i)
                            Next
                            di.Serial = sn2.Trim()
                        Else
                            di.Serial = sn.Trim()
                        End If
    
                        Exit For
    
                    End If
    
                Next
                info.Add(di)
    
            Next
    
            Return info
    
        End Function
    
        Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
            Dim serials = GetPhysicalDriveSerialNumbers()
            TextBox1.AppendText(String.Join(vbCrLf, serials))
    
        End Sub
    
    End Class

    EDIT: Although it worked for me with Windows 7, it doesn't retrieve the serial numbers on my Windows Server 2003 - nothing like a serial number appears in the PropertyData.

    HTH,

    Andrew



    • Proposed as answer by Carmelo La Monica Saturday, April 6, 2013 10:25 PM
    • Edited by Andrew Morton Monday, April 8, 2013 9:12 AM WS2003.
    • Marked as answer by Youen Zen Tuesday, April 23, 2013 7:08 AM
    Saturday, April 6, 2013 9:52 PM
  • Andrew - I had to change your code slightly because here, WMI returns a HEX string with the ASCII values of the serial number (and reversed)

    4457572D414D415A - Actual return
    57442D574D415A41 - Reversed
    W D - W M A Z A

    WMI is a great, inconsistent mystery to me........

    Here is the output: (X's for privacy & paranoia)

    Name: \\.\PHYSICALDRIVE1 Serial: OCZ-XXXXXXXX77E9XN4
    Name: \\.\PHYSICALDRIVE0 Serial: XXXXXXSH
    Name: \\.\PHYSICALDRIVE2 Serial: WD-WMAZAXXXXXXX

    The OCZ drive is my boot drive.

    • Marked as answer by Youen Zen Tuesday, April 23, 2013 7:08 AM
    Saturday, April 6, 2013 11:43 PM