Jump to content

Get Home DiskDrive SerialNumber


Go to solution Solved by Andreik,

Recommended Posts

Posted
1 hour ago, Nine said:

Try powershell :

Get-PhysicalDisk | Select-Object FriendlyName, DeviceID, SerialNumber, AdapterSerialNumber

AdapterSerialNumber looks good.

nice, must be we look for it in wmi classes

Posted (edited)

I didn't read all the posts in this thread.

I found an old WMI script which returns the s/n:

Global $oErrorHandler = ObjEvent("AutoIt.Error", "ObjErrorHandler")

MsgBox(0, "Test", WMI_GetHDDSN("."))

Func WMI_GetHDDSN($host, $usr = "", $pass = "") ;coded by UEZ 2011
    If $host = "." Then $host = "localhost"
    Local $HDD_SN
    Local $ping = Ping($host, 1000)
    If @error Then Return SetError(1, 0, -1)
    Local $objWMILocator = ObjCreate("WbemScripting.SWbemLocator")
    Local $objWMIService = $objWMILocator.ConnectServer($host, "\root\cimv2", $usr, $pass, "", "", 128)
    If @error Then Return SetError(2, 0, -1)
    Local $colItems = $objWMIService.ExecQuery("SELECT Model, Name, SerialNumber FROM Win32_DiskDrive WHERE MediaType='Fixed hard disk media'", "WQL", 0x30)
    If IsObj($colItems) Then
        For $objItem In $colItems
            $HDD_SN &= "Model: " & $objItem.Model & ", S/N: " & WMI_GetHDDSN2(StringMid($objItem.Name, 5), $host, $usr, $pass) & @LF
        Next
    Else
        Return SetError(3, 0, -1)
    EndIf
    Return $HDD_SN
EndFunc

Func WMI_GetHDDSN2($Tag, $host, $usr = "", $pass = "") ;coded by UEZ 2011
    Local $HDD_SN
    Local $objWMILocator = ObjCreate("WbemScripting.SWbemLocator")
    Local $objWMIService = $objWMILocator.ConnectServer($host, "\root\cimv2", $usr, $pass, "", "", 128)
    Local $colItems = $objWMIService.ExecQuery("SELECT SerialNumber,Tag FROM Win32_PhysicalMedia WHERE Tag LIKE '%" & $Tag & "%'", "WQL", 0x30)
    If IsObj($colItems) Then
        For $objItem In $colItems
;~          ConsoleWrite($objItem.Tag & @LF)
            $HDD_SN = $objItem.SerialNumber
        Next
    Else
        Return SetError(3, 0, -1)
    EndIf
    Return $HDD_SN
EndFunc

Func ObjErrorHandler()
     ConsoleWrite(  "A COM Error has occured!" & @CRLF  & @CRLF & _
                                "err.description is: "    & @TAB & $oErrorHandler.description    & @CRLF & _
                                "err.windescription:"     & @TAB & $oErrorHandler & @CRLF & _
                                "err.number is: "         & @TAB & Hex($oErrorHandler.number, 8)  & @CRLF & _
                                "err.lastdllerror is: "   & @TAB & $oErrorHandler.lastdllerror   & @CRLF & _
                                "err.scriptline is: "     & @TAB & $oErrorHandler.scriptline     & @CRLF & _
                                "err.source is: "         & @TAB & $oErrorHandler.source         & @CRLF & _
                                "err.helpfile is: "       & @TAB & $oErrorHandler.helpfile       & @CRLF & _
                                "err.helpcontext is: "    & @TAB & $oErrorHandler.helpcontext & @CRLF _
                            )
EndFunc

 

I don't know if this is what you guys are looking for.

Edited by UEZ

Please don't send me any personal message and ask for support! I will not reply!

Selection of finest graphical examples at Codepen.io

The own fart smells best!
Her 'sikim hıyar' diyene bir avuç tuz alıp koşma!
¯\_(ツ)_/¯  ٩(●̮̮̃•̃)۶ ٩(-̮̮̃-̃)۶ૐ

Posted (edited)

Or the WinAPI way:

;Coded by UEZ build 2025-12-07 beta
;~ #RequireAdmin
#include <WinAPIFiles.au3>
#include <WinAPIHObj.au3>


Func _WinAPI_GetPhysicalDriveNumber($driveLetter)
    $driveLetter = StringLeft($driveLetter, 1)

    Local $hVolume = _WinAPI_CreateFile("\\.\" & $driveLetter & ":", 2, 0, 6)
    If $hVolume = 0 Then Return SetError(1, 0, -1)

    Local $tSDN = DllStructCreate("dword DeviceType;dword DeviceNumber;dword PartitionNumber")

    Local $bResult = _WinAPI_DeviceIoControl($hVolume, $IOCTL_STORAGE_GET_DEVICE_NUMBER, 0, 0, $tSDN, DllStructGetSize($tSDN))

    _WinAPI_CloseHandle($hVolume)

    If Not $bResult Then Return SetError(2, 0, -1)
    Return $tSDN.DeviceNumber
EndFunc

Func _WinAPI_GetHDDSerialByPhysicalDrive($driveNumber = 0)
    Local $hDrive = _WinAPI_CreateFile("\\.\PhysicalDrive" & $driveNumber, 2, 0, 6)
    If $hDrive = 0 Then Return SetError(1, 0, "")

    Local $tSPQ = DllStructCreate("int PropertyId;int QueryType;byte AdditionalParameters[1]")
    With $tSPQ
        .PropertyId = 0  ; StorageDeviceProperty
        .QueryType = 0   ; PropertyStandardQuery
    EndWith

    Local $tBuffer = DllStructCreate("byte[65536]")

    Local $bResult = _WinAPI_DeviceIoControl($hDrive, $IOCTL_STORAGE_QUERY_PROPERTY, $tSPQ, DllStructGetSize($tSPQ), $tBuffer, DllStructGetSize($tBuffer))

    _WinAPI_CloseHandle($hDrive)

    If Not $bResult Then Return SetError(2, 0, "")

    ; Parse STORAGE_DEVICE_DESCRIPTOR header
    Local $tHeader = DllStructCreate("dword Version;dword Size;byte DeviceType;byte DeviceTypeModifier;" & _
                                     "byte RemovableMedia;byte CommandQueueing;dword VendorIdOffset;dword ProductIdOffset;" & _
                                     "dword ProductRevisionOffset;dword SerialNumberOffset", DllStructGetPtr($tBuffer))

    Local $serialOffset = $tHeader.SerialNumberOffset
    If $serialOffset = 0 Then Return SetError(3, 0, "")

    ; Read the serial number string
    Local $basePtr = DllStructGetPtr($tBuffer)
    Local $serial = "", $i, $tChar, $byte

    For $i = 0 To 200
        $tChar = DllStructCreate("byte b", $basePtr + $serialOffset + $i)
        $byte = $tChar.b
        If $byte = 0 Then ExitLoop
        $serial &= Chr($byte)
    Next

    Return StringStripWS($serial, 3)
EndFunc

Func _WinAPI_GetHDDModelByPhysicalDrive($driveNumber = 0)
    Local $hDrive = _WinAPI_CreateFile("\\.\PhysicalDrive" & $driveNumber, 2, 0, 6)
    If $hDrive = 0 Then Return SetError(1, 0, "")

    Local $tSPQ = DllStructCreate("int PropertyId;int QueryType;byte AdditionalParameters[1]")
    With $tSPQ
        .PropertyId = 0
        .PropertyId = 0
    EndWith

    Local $tBuffer = DllStructCreate("byte[65536]")

    Local $bResult = _WinAPI_DeviceIoControl($hDrive, $IOCTL_STORAGE_QUERY_PROPERTY, $tSPQ, DllStructGetSize($tSPQ), $tBuffer, DllStructGetSize($tBuffer))

    _WinAPI_CloseHandle($hDrive)

    If Not $bResult Then Return SetError(2, 0, "")

    Local $tHeader = DllStructCreate("dword Version;dword Size;byte DeviceType;byte DeviceTypeModifier;" & _
                                     "byte RemovableMedia;byte CommandQueueing;dword VendorIdOffset;dword ProductIdOffset;" & _
                                     "dword ProductRevisionOffset;dword SerialNumberOffset", DllStructGetPtr($tBuffer))

    Local $productOffset = $tHeader.ProductIdOffset
    If $productOffset = 0 Then Return SetError(3, 0, "")

    Local $basePtr = DllStructGetPtr($tBuffer)
    Local $product = "", $tChar, $tChar, $i

    For $i = 0 To 200
        $tChar = DllStructCreate("byte b", $basePtr + $productOffset + $i)
        $byte = $tChar.b
        If $byte = 0 Then ExitLoop
        $product &= Chr($byte)
    Next

    Return StringStripWS($product, 3)
EndFunc

Func _WinAPI_GetVolumeSerial($drive = "C:\")
    Local $aInfo = _WinAPI_GetVolumeInformation($drive)
    If @error Then Return SetError(@error, 0, "")
    Return Hex($aInfo[1], 8)
EndFunc


ConsoleWrite("=== HDD Information ===" & @CRLF & @CRLF)

Local $physDrive = _WinAPI_GetPhysicalDriveNumber("C")
ConsoleWrite("Physical drive number for C: " & $physDrive & @CRLF)

If $physDrive >= 0 Then
    Local $model = _WinAPI_GetHDDModelByPhysicalDrive($physDrive)
    ConsoleWrite("Model: " & $model & @CRLF)

    Local $serial = _WinAPI_GetHDDSerialByPhysicalDrive($physDrive)
    ConsoleWrite("Serial Number: " & $serial & @CRLF)
EndIf

Local $volSerial = _WinAPI_GetVolumeSerial()
ConsoleWrite("Volume Serial: " & $volSerial & @CRLF & @CRLF)

 

My result:

=== HDD Information ===

Physical drive number for C: 0
Model: BG6 KIOXIA 256GB
Serial Number: 8CE3_8E10_02B1_5166.
Volume Serial: 40D09020

 

Edited by UEZ

Please don't send me any personal message and ask for support! I will not reply!

Selection of finest graphical examples at Codepen.io

The own fart smells best!
Her 'sikim hıyar' diyene bir avuç tuz alıp koşma!
¯\_(ツ)_/¯  ٩(●̮̮̃•̃)۶ ٩(-̮̮̃-̃)۶ૐ

Posted
53 minutes ago, UEZ said:
Serial Number: 8CE3_8E10_02B1_5166.
Volume Serial: 40D09020

...but "8CE3_8E10_02B1_5166" is not the serial number of the NVMe drive.
Running "Get-PhysicalDisk | Select-Object FriendlyName, DeviceID, SerialNumber, AdapterSerialNumber", the "AdapterSerialNumber" is the string that is needed. For that I believe that "https://learn.microsoft.com/en-us/windows-hardware/drivers/ddi/ntddstor/ne-ntddstor-_storage_protocol_nvme_data_type" needs to be used.

Follow the link to my code contribution ( and other things too ).
FAQ - Please Read Before Posting.
autoit_scripter_blue_userbar.png

Posted (edited)

This is the same result as 

C:\Windows\System32>wmic path win32_physicalmedia get serialnumber
SerialNumber
8CE3_8E10_02B1_5166.

Yes, CrystalDiskInfo shows 7E5CT5TPZ164 as s/n. Need some more investigation...

Edited by UEZ

Please don't send me any personal message and ask for support! I will not reply!

Selection of finest graphical examples at Codepen.io

The own fart smells best!
Her 'sikim hıyar' diyene bir avuç tuz alıp koşma!
¯\_(ツ)_/¯  ٩(●̮̮̃•̃)۶ ٩(-̮̮̃-̃)۶ૐ

Posted

Another WMI  methode seems to work, too:

;Coded by UEZ build 2025-12-07

Func WMI_GetHDDSerialNumber()
    Local $oWMI = ObjGet("winmgmts:\\.\root\Microsoft\Windows\Storage")
    If Not IsObj($oWMI) Then Return "Error: WMI Storage Namespace not found (Win8+ required)"

    Local $colItems = $oWMI.ExecQuery("SELECT FriendlyName, SerialNumber, AdapterSerialNumber FROM MSFT_PhysicalDisk")
    Local $aResult[100][3], $c = 0
    For $objItem In $colItems
        With $objItem
            $aResult[$c][0] = .FriendlyName
            $aResult[$c][1] = .SerialNumber
            $aResult[$c][2] = .AdapterSerialNumber
            ConsoleWrite("-----------------------------------" & @CRLF)
            ConsoleWrite("Name:          " & $aResult[$c][0]& @CRLF)
            ConsoleWrite("SerialNumber:  " & $aResult[$c][1] & @CRLF)
            ConsoleWrite("AdapterSerial: " & $aResult[$c][2]& @CRLF)
        EndWith
        $c += 1
    Next
    ReDim $aResult[$c][3]
    Return $aResult
EndFunc

Global $a = WMI_GetHDDSerialNumber()

 

Please don't send me any personal message and ask for support! I will not reply!

Selection of finest graphical examples at Codepen.io

The own fart smells best!
Her 'sikim hıyar' diyene bir avuç tuz alıp koşma!
¯\_(ツ)_/¯  ٩(●̮̮̃•̃)۶ ٩(-̮̮̃-̃)۶ૐ

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
×
×
  • Create New...