How to Get the Serial Number of a Volume in Batch Script
Every formatted volume in Windows is assigned a unique Volume Serial Number at the time of formatting. This hexadecimal identifier (e.g., A1B2-C3D4) is different from the physical hard drive's hardware serial number, it changes every time the volume is reformatted, while the hardware serial is permanent. Volume serial numbers are used by software licensing systems that bind to a specific volume, forensic investigations that need to identify a disk image, and inventory scripts that need a per-volume fingerprint.
This guide will explain how to retrieve volume serial numbers.
Volume Serial vs. Hardware Serialβ
These are two completely different identifiers that are frequently confused:
| Property | Volume Serial Number | Hardware (Disk) Serial Number |
|---|---|---|
| What it identifies | A specific format instance of a partition | The physical drive hardware |
| Format | 8-digit hex (e.g., A1B2-C3D4) | Manufacturer-specific string |
| When it changes | Every time the volume is reformatted | Never (burned into firmware) |
| Where it's stored | Volume boot sector | Drive firmware/controller |
| Use case | Software licensing, forensic image matching | Asset tracking, warranty, hardware inventory |
| Command to retrieve | vol C: | Get-Disk or Get-PhysicalDisk |
Method 1: Quick Volume Serial Checkβ
The simplest way to see the volume label and serial number for a specific drive.
Implementationβ
@echo off
setlocal
set "Drive=%~1"
if "%Drive%"=="" set "Drive=C"
:: Normalize
set "DriveLetter=%Drive:~0,1%"
if not exist %DriveLetter%:\ (
echo [ERROR] Drive %DriveLetter%: does not exist. >&2
endlocal
exit /b 1
)
echo [INFO] Volume information for %DriveLetter%:
echo.
vol %DriveLetter%:
endlocal
exit /b 0
Sample output:β
Volume in drive C is Windows
Volume Serial Number is A1B2-C3D4
Method 2: Extract Serial Number as a Variableβ
When you need the serial number as a clean variable for use in scripting logic, license validation, file naming, or conditional processing.
@echo off
setlocal
set "Drive=%~1"
if "%Drive%"=="" set "Drive=C"
set "DriveLetter=%Drive:~0,1%"
if not exist %DriveLetter%:\ (
echo [ERROR] Drive %DriveLetter%: not found. >&2
endlocal
exit /b 1
)
:: Extract the serial number using vol (Much safer than parsing an entire dir output)
set "Serial="
for /f "usebackq tokens=*" %%a in (`vol %DriveLetter%: 2^>nul`) do (
:: Split line by spaces and check each word for the XXXX-XXXX format
for %%w in (%%a) do (
echo "%%w" | findstr /i /r "\"*[0-9A-F][0-9A-F][0-9A-F][0-9A-F]-[0-9A-F][0-9A-F][0-9A-F][0-9A-F]\"*" >nul 2>&1
if not errorlevel 1 (
:: Store value and clean up any quotes
set "Serial=%%~w"
)
)
)
:: Fallback: use PowerShell if parsing failed (Written safely on one line to prevent CMD parser crashes)
if not defined Serial (
for /f "usebackq delims=" %%s in (
`powershell -NoProfile -Command "$vol = Get-CimInstance Win32_Volume -Filter \"DriveLetter='%DriveLetter%:'\" -ErrorAction SilentlyContinue; if ($vol.SerialNumber) { '{0:X4}-{1:X4}' -f ($vol.SerialNumber -shr 16), ($vol.SerialNumber -band 0xFFFF) } else { 'UNKNOWN' }"`
) do set "Serial=%%s"
)
if "%Serial%"=="UNKNOWN" (
echo [ERROR] Could not retrieve serial number for %DriveLetter%: >&2
endlocal
exit /b 1
)
echo [RESULT] Volume Serial: %Serial%
endlocal
exit /b 0
Why dir instead of vol for parsing:β
Both vol and dir display the volume serial number, but their output format varies by locale:
- English:
Volume Serial Number is A1B2-C3D4 - German:
Volumeseriennummer: A1B2-C3D4 - French:
Le numΓ©ro de sΓ©rie du volume est A1B2-C3D4
The token position of the serial number shifts depending on the language. The script uses a regex-based approach that searches for the XXXX-XXXX hex pattern regardless of surrounding text, making it more robust across locales. If this fails, it falls back to PowerShell's Win32_Volume.SerialNumber.
Using the serial in scripts:β
:: Example: Create a license-validation filename
set "LicenseFile=license_%Serial%.dat"
:: Example: Log the serial for inventory
echo %COMPUTERNAME%,%DriveLetter%:,%Serial% >> inventory.csv
:: Example: Compare against expected serial
if "%Serial%"=="A1B2-C3D4" echo Licensed machine detected.
Method 3: All-Drive Serial Number Inventoryβ
Generates a complete inventory of all volume serial numbers on the machine.
@echo off
setlocal
echo [INFO] Volume Serial Number Inventory for %COMPUTERNAME%:
echo --------------------------------------------------
powershell -NoProfile -Command ^
"$volumes = Get-CimInstance Win32_Volume |" ^
" Where-Object { $_.DriveLetter -and $_.FileSystem };" ^
"if (-not $volumes) {" ^
" Write-Host 'No volumes with drive letters found.';" ^
" exit 0" ^
"};" ^
"$volumes | ForEach-Object {" ^
" $serial = if ($_.SerialNumber) { '{0:X8}' -f $_.SerialNumber } else { 'N/A' };" ^
" $serialFormatted = if ($serial.Length -eq 8) {" ^
" $serial.Substring(0,4) + '-' + $serial.Substring(4,4)" ^
" } else { $serial };" ^
" [PSCustomObject]@{" ^
" Drive = $_.DriveLetter;" ^
" Label = if ($_.Label) { $_.Label } else { '(none)' };" ^
" FileSystem = $_.FileSystem;" ^
" 'Serial Number' = $serialFormatted" ^
" }" ^
"} | Sort-Object Drive | Format-Table -AutoSize"
echo --------------------------------------------------
endlocal
exit /b 0
Sample output:β
Drive Label FileSystem Serial Number
----- ----- ---------- -------------
C: Windows NTFS A1B2-C3D4
D: Data NTFS E5F6-7890
E: BACKUP_USB exFAT 1234-ABCD
Why PowerShell for the inventory:β
Win32_Volume.SerialNumberreturns the serial as a 32-bit integer. Formatting with'{0:X8}' -f $valueproduces the standard 8-digit hexadecimal representation.- A single WMI query retrieves all volumes at once, no need to loop through drive letters.
- Works for all file system types (NTFS, FAT32, exFAT, ReFS).
Method 4: Combined Volume + Hardware Serial Reportβ
For complete asset documentation, this method shows both the volume serial (per partition) and the hardware serial (per physical disk).
@echo off
setlocal
echo [INFO] Complete serial number report for %COMPUTERNAME%:
echo --------------------------------------------------
echo.
echo --- Volume Serial Numbers (per partition^) ---
echo.
powershell -NoProfile -Command ^
"Get-CimInstance Win32_Volume |" ^
" Where-Object { $_.DriveLetter -and $_.FileSystem } |" ^
" Sort-Object DriveLetter |" ^
" ForEach-Object {" ^
" $serial = if ($_.SerialNumber) { '{0:X8}' -f $_.SerialNumber } else { 'N/A' };" ^
" $formatted = if ($serial.Length -eq 8) { $serial.Insert(4,'-') } else { $serial };" ^
" Write-Host \" $($_.DriveLetter) $($_.FileSystem.PadRight(6)) $formatted $(if ($_.Label) { $_.Label } else { '' })\"" ^
" }"
echo.
echo --- Hardware Serial Numbers (per physical disk^) ---
echo.
powershell -NoProfile -Command ^
"Get-Disk | ForEach-Object {" ^
" $sn = if ($_.SerialNumber) { $_.SerialNumber.Trim() } else { 'N/A' };" ^
" Write-Host \" Disk $($_.Number): $($_.FriendlyName) - SN: $sn\"" ^
"}"
echo.
echo --------------------------------------------------
endlocal
exit /b 0
Sample output:β
--- Volume Serial Numbers (per partition) ---
C: NTFS A1B2-C3D4 Windows
D: NTFS E5F6-7890 Data
--- Hardware Serial Numbers (per physical disk) ---
Disk 0: Samsung SSD 970 EVO Plus - SN: S4EWNX0M123456
Disk 1: WDC WD40EFAX-68JH4N1 - SN: WD-WCC7K1234567
Why both serials matter:β
- Volume serial changes with reformatting. Useful for tracking specific format instances, license bindings, and forensic image matching.
- Hardware serial is permanent. Useful for asset tracking, warranty claims, and identifying the physical device regardless of what partitions are on it.
Method 5: Fleet-Wide Serial Inventory CSVβ
For collecting serial numbers across multiple machines.
@echo off
setlocal
set "CSVFile=\\Server\Audit\volume_serials.csv"
if not exist "%CSVFile%" (
echo "Timestamp","Computer","Drive","FileSystem","VolumeSerial","Label","DiskNum","HardwareSerial" > "%CSVFile%" 2>nul
)
powershell -NoProfile -Command ^
"$ts = Get-Date -Format 'yyyy-MM-dd HH:mm:ss';" ^
"$volumes = Get-CimInstance Win32_Volume | Where-Object { $_.DriveLetter -and $_.FileSystem };" ^
"foreach ($v in $volumes) {" ^
" $serial = if ($v.SerialNumber) { '{0:X8}' -f $v.SerialNumber } else { 'N/A' };" ^
" $label = if ($v.Label) { $v.Label } else { 'none' };" ^
" $driveLetter = $v.DriveLetter;" ^
" $diskNum = 'N/A';" ^
" $hwSerial = 'N/A';" ^
" try {" ^
" $partition = Get-Partition | Where-Object { $_.DriveLetter -eq $driveLetter[0] } | Select-Object -First 1;" ^
" if ($partition) {" ^
" $diskNum = $partition.DiskNumber;" ^
" $disk = Get-Disk -Number $diskNum -ErrorAction SilentlyContinue;" ^
" if ($disk.SerialNumber) { $hwSerial = $disk.SerialNumber.Trim() }" ^
" }" ^
" } catch {};" ^
" Write-Output ('\"' + $ts + '\",\"' + $env:COMPUTERNAME + '\",\"' + $driveLetter + '\",\"' + $v.FileSystem + '\",\"' + $serial + '\",\"' + $label + '\",\"' + $diskNum + '\",\"' + $hwSerial + '\"')" ^
"}" >> "%CSVFile%" 2>nul
echo [OK] Serial data exported for %COMPUTERNAME%.
endlocal
exit /b 0
What to look for in the fleet CSV:β
- Volume serial changes for the same drive letter on the same machine: Indicates the volume was reformatted between scans, investigate whether this was intentional.
- Same hardware serial on different computer names: May indicate a drive was moved between machines (e.g., during hardware repair).
- Missing hardware serials: Some USB enclosures and virtual disks don't report hardware serials.
How to Avoid Common Errorsβ
Wrong Way: Confusing Volume Serial with Hardware Serialβ
:: WRONG - this shows the HARDWARE serial, not the volume serial
wmic diskdrive get serialnumber
The hardware serial identifies the physical drive. The volume serial identifies a specific format instance of a partition. They are completely different values used for different purposes.
Correct Way: Use vol C: or Win32_Volume.SerialNumber for volume serials. Use Get-Disk or Get-PhysicalDisk for hardware serials.
Problem: Locale-Dependent Output from volβ
The text surrounding the serial number in vol output is translated:
- English:
Volume Serial Number is A1B2-C3D4 - German:
Volumeseriennummer: A1B2-C3D4
Using for /f "tokens=5" to extract the serial works in English but fails in German (where it's at a different token position).
Solution: Method 2 uses pattern matching for the XXXX-XXXX hex format rather than relying on token position. For fully reliable extraction, use Win32_Volume.SerialNumber via PowerShell.
Problem: PowerShell Returns Serial as an Integerβ
Win32_Volume.SerialNumber returns the serial as a 32-bit signed integer (e.g., -1582119980). This needs to be formatted as hexadecimal to match the XXXX-XXXX format shown by vol.
Solution: Use '{0:X8}' -f $value to convert to an 8-digit hex string, then insert a hyphen at position 4 for the standard display format. All PowerShell methods in this guide handle this formatting.
Best Practices and Rulesβ
1. Know Which Serial You Needβ
For licensing audits and forensic image matching, you need the volume serial. For asset tracking and hardware inventory, you need the hardware serial. Method 4 shows both side by side.
2. Volume Serial Changes on Reformatβ
If a drive is reformatted, its volume serial changes. Software licenses bound to the old serial may deactivate. Document the serial before reformatting if licenses are tied to it.
3. Log Both Serials for Fleet Managementβ
Capture both volume and hardware serials in your inventory system. The hardware serial tracks the physical asset; the volume serial tracks the logical volume state.
4. Use PowerShell for Reliable Extractionβ
Parsing vol or dir output is fragile across locales. Win32_Volume.SerialNumber returns a consistent numeric value regardless of Windows language.
5. Include Serials in Forensic Documentationβ
When creating disk images for forensic analysis, record the volume serial number. This allows the image to be traced back to the specific volume instance on the source machine.
Conclusionsβ
Retrieving volume serial numbers provides a unique per-format-instance identifier that is essential for licensing validation, forensic traceability, and inventory management. By using Win32_Volume for reliable cross-locale extraction, distinguishing volume serials from hardware serials, and collecting both in fleet-wide inventories, you ensure that every volume in your infrastructure is properly catalogued and traceable. This small piece of metadata provides a powerful anchor for identification and compliance across your entire Windows environment.