As part of the same discussion as with my previous post VBA – Get Processor Id the user also wanted to determine the PC’s BIOS Serial Number. Using the same technique, but switching over to using the Win32_BIOS class we can once again easily gather this information.
Below is a function that retrieves the BIOS Serial Number using WMI.
'---------------------------------------------------------------------------------------
' Procedure : GetBIOSSerialNumber
' Author : Daniel Pineault, CARDA Consultants Inc.
' Website : http://www.cardaconsultants.com
' Purpose : Retrieve the BIOS Serial Number
' Copyright : The following is release as Attribution-ShareAlike 4.0 International
' (CC BY-SA 4.0) - https://creativecommons.org/licenses/by-sa/4.0/
' Req'd Refs: Uses Late Binding, so none required
'
' Input Variables:
' ~~~~~~~~~~~~~~~~
' sHost : Name/IP Address of the PC to query assuming you have the rights to do so
' optional, so by leaving it blank it will query the local computer
'
' Usage:
' ~~~~~~
' ? GetBIOSSerialNumber
'
' Revision History:
' Rev Date(yyyy/mm/dd) Description
' **************************************************************************************
' 1 2018-09-03 Initial Release
'---------------------------------------------------------------------------------------
Function GetBIOSSerialNumber(Optional sHost As String = ".") As String
'Win32_BIOS -> https://docs.microsoft.com/en-us/windows/desktop/cimwin32prov/win32-bios
On Error GoTo Error_Handler
Dim oWMI As Object 'WMI object to query
Dim oBIOSs As Object
Dim oBIOS As Object
Set oWMI = GetObject("winmgmts:{impersonationLevel=impersonate}!\\" & sHost & "\root\cimv2")
Set oBIOSs = oWMI.ExecQuery("SELECT SerialNumber FROM Win32_BIOS")
For Each oBIOS In oBIOSs
GetBIOSSerialNumber = GetBIOSSerialNumber & oBIOS.SerialNumber & ","
Next
If Right(GetBIOSSerialNumber, 1) = "," Then GetBIOSSerialNumber = Left(GetBIOSSerialNumber, Len(GetBIOSSerialNumber) - 1)
Error_Handler_Exit:
On Error Resume Next
If Not oBIOS Is Nothing Then Set oBIOS = Nothing
If Not oBIOSs Is Nothing Then Set oBIOSs = Nothing
If Not oWMI Is Nothing Then Set oWMI = Nothing
Exit Function
Error_Handler:
MsgBox "The following error has occurred." & vbCrLf & vbCrLf & _
"Error Number: " & Err.Number & vbCrLf & _
"Error Source: GetBIOSSerialNumber" & vbCrLf & _
"Error Description: " & Err.Description, _
vbCritical, "An Error has Occurred!"
Resume Error_Handler_Exit
End Function
Similarily, you can change the function to iterate over all the properties rather than just the BIOS Serial Number. Below is an example of how you can achieve this
'---------------------------------------------------------------------------------------
' Procedure : GetBIOSProperties
' Author : Daniel Pineault, CARDA Consultants Inc.
' Website : http://www.cardaconsultants.com
' Purpose : List all the available WMI BIOS properties
' Copyright : The following is release as Attribution-ShareAlike 4.0 International
' (CC BY-SA 4.0) - https://creativecommons.org/licenses/by-sa/4.0/
' Req'd Refs: Uses Late Binding, so none required
'
' Input Variables:
' ~~~~~~~~~~~~~~~~
' sHost : Name/IP Address of the PC to query assuming you have the rights to do so
' optional, so by leaving it blank it will query the local computer
'
' Usage:
' ~~~~~~
' ? GetBIOSProperties
'
' Revision History:
' Rev Date(yyyy/mm/dd) Description
' **************************************************************************************
' 1 2018-09-03 Initial Release
'---------------------------------------------------------------------------------------
Function GetBIOSProperties(Optional sHost As String = ".") As String
'Win32_BIOS -> https://docs.microsoft.com/en-us/windows/desktop/cimwin32prov/win32-bios
' On Error GoTo Error_Handler
Dim oWMI As Object 'WMI object to query
Dim oBIOSs As Object
Dim oBIOS As Object
Dim oPrp As Object
Set oWMI = GetObject("winmgmts:{impersonationLevel=impersonate}!\\" & sHost & "\root\cimv2")
Set oBIOSs = oWMI.ExecQuery("SELECT SerialNumber FROM Win32_BIOS")
For Each oBIOS In oBIOSs
For Each oPrp In oBIOS.Properties_
Debug.Print oPrp.Name, oPrp.Value
Next oPrp
Next
Error_Handler_Exit:
On Error Resume Next
If Not oPrp Is Nothing Then Set oPrp = Nothing
If Not oBIOS Is Nothing Then Set oBIOS = Nothing
If Not oBIOSs Is Nothing Then Set oBIOSs = Nothing
If Not oWMI Is Nothing Then Set oWMI = Nothing
Exit Function
Error_Handler:
MsgBox "The following error has occurred." & vbCrLf & vbCrLf & _
"Error Number: " & Err.Number & vbCrLf & _
"Error Source: GetBIOSProperties" & vbCrLf & _
"Error Description: " & Err.Description, _
vbCritical, "An Error has Occurred!"
Resume Error_Handler_Exit
End Function
These functions are not restricted to Access and will work in any VBA compatible application (Access, Excel, Word, …).
hi, is it possible to get hard disks real serial number using Win32_DiskDrive class.
Thanks.
Sure, you’d simply adapt the code to something like
Function GetHDSN(Optional sHost As String = ".") As String 'Win32_BIOS -> https://docs.microsoft.com/en-us/windows/win32/cimwin32prov/win32-diskdrive On Error GoTo Error_Handler Dim oWMI As Object 'WMI object to query Dim oDiskDrives As Object Dim oDiskDrive As Object Set oWMI = GetObject("winmgmts:{impersonationLevel=impersonate}!\\" & sHost & "\root\cimv2") Set oDiskDrives = oWMI.ExecQuery("SELECT SerialNumber FROM Win32_DiskDrive") On Error Resume Next For Each oDiskDrive In oDiskDrives GetHDSN = GetHDSN & Trim(oDiskDrive.SerialNumber) & "," Next If Right(GetHDSN, 1) = "," Then GetHDSN = Left(GetHDSN, Len(GetHDSN) - 1) Error_Handler_Exit: On Error Resume Next If Not oDiskDrive Is Nothing Then Set oDiskDrive = Nothing If Not oDiskDrives Is Nothing Then Set oDiskDrives = Nothing If Not oWMI Is Nothing Then Set oWMI = Nothing Exit Function Error_Handler: MsgBox "The following error has occurred." & vbCrLf & vbCrLf & _ "Error Number: " & Err.Number & vbCrLf & _ "Error Source: GetHDSN" & vbCrLf & _ "Error Description: " & Err.Description, _ vbCritical, "An Error has Occurred!" Resume Error_Handler_Exit End Functionhi, thanks Daniel.
in your code i was getting error and fixed by adding “\” at 2 locations.
kindly edit your post.
Set oWMI = GetObject(“winmgmts:{impersonationLevel=impersonate}!” & sHost & “rootcimv2”)
Set oWMI = GetObject(“winmgmts:{impersonationLevel=impersonate}!\\” & sHost & “\root\cimv2”)
Secondly, is it possible to get serial of specific hard disk if more than one is attached.
Regards.
Yes, indeed. Thank you for pointing it out. They are there in my comment, but for some reason not rendering. Let me see what I can do to correct the situation.
It should be fixed now. It’s apparently a known WordPress issue.
hi, Daniel
the code gives serial info for all drives attached. Is it possible to get serial for specific drive e.g primary drive only.
Regards.
You probably could use win32-diskpartition to identify the BootPartition and then from there get the DeviceID to then get the Serial Number.
Here, you could try the following (I haven’t had time to fully test it though)
Function GetHDSN4PrimaryHD(Optional sHost As String = ".") As String On Error GoTo Error_Handler Dim oWMI As Object 'WMI object to query Dim oPartitions As Object Dim oPartition As Object Dim oDiskDrives As Object Dim oDiskDrive As Object Dim sDeviceID As String Set oWMI = GetObject("winmgmts:{impersonationLevel=impersonate}!\\" & sHost & "\root\cimv2") Set oPartitions = oWMI.ExecQuery("SELECT BootPartition, DeviceID FROM Win32_DiskPartition") On Error Resume Next For Each oPartition In oPartitions If oPartition.BootPartition Then 'PrimaryPartition Set oDiskDrives = oWMI.ExecQuery _ ("ASSOCIATORS OF {Win32_DiskPartition.DeviceID='" & _ oPartition.DeviceID & "'} WHERE AssocClass = " & _ "Win32_DiskDriveToDiskPartition") On Error Resume Next For Each oDiskDrive In oDiskDrives 'Shouldn't really be a loop GetHDSN4PrimaryHD = GetHDSN4PrimaryHD & Trim(oDiskDrive.SerialNumber) & "," Next If Right(GetHDSN4PrimaryHD, 1) = "," Then GetHDSN4PrimaryHD = Left(GetHDSN4PrimaryHD, Len(GetHDSN4PrimaryHD) - 1) Exit For End If Next Error_Handler_Exit: On Error Resume Next If Not oPartition Is Nothing Then Set oPartition = Nothing If Not oPartitions Is Nothing Then Set oPartitions = Nothing If Not oDiskDrive Is Nothing Then Set oDiskDrive = Nothing If Not oDiskDrives Is Nothing Then Set oDiskDrives = Nothing If Not oWMI Is Nothing Then Set oWMI = Nothing Exit Function Error_Handler: MsgBox "The following error has occurred" & vbCrLf & vbCrLf & _ "Error Number: " & Err.Number & vbCrLf & _ "Error Source: GetHDSN4PrimaryHD" & vbCrLf & _ "Error Description: " & Err.Description & _ Switch(Erl = 0, "", Erl <> 0, vbCrLf & "Line No: " & Erl) _ , vbOKOnly + vbCritical, "An Error has Occurred!" Resume Error_Handler_Exit End FunctionThanks a lot.