I found myself looking for a way to retrieve the serial number of the computer's hard drive as a way of preventing unauthorized copies of an Access app. I have done it before but couldn't remember how. To my surprise, I found several ways to accomplish this task. I decided to post a couple of those techniques here to help anyone else who may find himself or herself looking to do the same thing in the future.
Before we start, the first thing we need to realize is hard disk drives have more than one serial numbers. One of the serial numbers we can retrieve is the one assigned by the hard disk manufacturer. This serial number should stay consistent throughout the life of the equipment. The other serial number available to us is the logical serial number assigned by the operating system when a disk is formatted. The value for the logical serial number may change if the disk is reformatted. Each technique presented below depends on which serial number you are interested in retrieving.
Physical Disk Drive Serial Numbers
The following function uses Windows Management Instrumentation (WMI) to create a connection to the local computer. The "WinMgmts" moniker is used to create a WMI object. Once a WMI object is instantiated, we can use the InstancesOf method to query the machine for system information.
Public Function HDSerial() As String
'6/14/2017
'thedbguy@gmail.com
'Returns the hard disk drive serial number
'You are free to use this code in your applications
'provided this copyright notice is left unchanged
On Error GoTo errHandler
Dim objWMI As Object
Dim objWin32 As Object
Dim objPM As Object
Dim strSN As String
Set objWMI = GetObject("WinMgmts:")
Set objWin32 = objWMI.InstancesOf("Win32_PhysicalMedia")
For Each objPM In objWin32
strSN = strSN & (";" + objPM.SerialNumber)
Next
HDSerial = Trim(Mid(strSN, 2))
errExit:
Set objPM = Nothing
Set objWin32 = Nothing
Set objWMI = Nothing
Exit Function
errHandler:
MsgBox Err.Number & ". " & Err.Description
Resume errExit
End Function
Logicl Disk Drive Serial Numbers
The above function used the "Win32_PhysicalMedia" collection to reference all the physical drives connected to the computer. We can now modify the above function using "Win32_LogicalDisk" to get a collection of all logical or mapped drives connected to the computer for the current user.
Public Function LDSerialWMI(Optional DriveLetter As Variant) As Variant
'6/14/2017
'thedbguy@gmail.com
'Returns the logical disk drive serial number
'You are free to use this code in your applications
'provided this copyright notice is left unchanged
On Error GoTo errHandler
Dim objWMI As Object
Dim objWin32 As Object
Dim objLD As Object
Dim strSN As Variant
Set objWMI = GetObject("WinMgmts:")
Set objWin32 = objWMI.InstancesOf("Win32_LogicalDisk")
If IsMissing(DriveLetter) Then
For Each objLD In objWin32
DriveLetter = objLD.DeviceID
strSN = strSN & (";" + DriveLetter + objLD.VolumeSerialNumber)
Next
Else
For Each objLD In objWin32
DriveLetter = Left(DriveLetter,1) & ":"
If DriveLetter = objLD.DeviceID Then
strSN = ";" & objLD.VolumeSerialNumber
End If
Next
End If
LDSerialWMI = Trim(Mid(strSN, 2))
errExit:
Set objLD = Nothing
Set objWin32 = Nothing
Set objWMI = Nothing
Exit Function
errHandler:
MsgBox Err.Number & ". " & Err.Description
Resume errExit
End Function
However, there is a more straightforward way to get the serial number of a specific logical disk drive. The following function uses the File System Object.
Public Function LDSerialFSO(DriveLetter As String) As Variant
'6/14/2017
'thedbguy@gmail.com
'Returns the logical disk drive serial number
'You are free to use this code in your applications
'provided this copyright notice is left unchanged
On Error GoTo errHandler
Dim objFSO As Object
Dim objDrv As Object
Dim strSN As Variant
DriveLetter = Left(DriveLetter,1) & ":"
Set objFSO = CreateObject("Scripting.FileSystemObject")
Set objDrv = objFSO.GetDrive(DriveLetter)
If objDrv.IsReady Then
strSN = objDrv.SerialNumber
Else
strSN = Null
End If
LDSerialFSO = strSN
errExit:
Set objFSO = Nothing
Exit Function
errHandler:
MsgBox Err.Number & ". " & Err.Description
Resume errExit
End Function
There is an important difference between the two functions for logical disk drive presented above. Using WMI returns the serial number as HEX; whereas, using FSO returns the serial number as a Long Integer. However, you can use the Hex() function to either convert the return value from the LDSerialFSO() function to HEX or modify the LDSerialFSO() function to return the serial number as HEX.
I hope you find this post helpful. As usual, please feel free to submit your comments to let me know how I can improve these functions. Thank you!