Reputation: 88
I have an odd issue. I'm attempting to return the hard drive serial number from WMIC to a variable in a batch file; the line that gives me the variable is:
for /f "skip=2 tokens=2 delims=," %%a in ('wmic diskdrive get serialnumber /FORMAT:CSV') do (set harddisk=%%a)
This assigns what wmic sees as the serial number for the hard drive to a variable, the issue is that the serial number it returns is slightly off. In one example it returns:
3ZVT01H4
But the serial number on the label is:
Z3TV104H
It seems as though it is taking the actual serial number and reversing every two characters; am I typing something wrong or is this a known (but not documented anywhere) issue?
Is there a way that I can take the variable, split it into two character chunks, reverse the order of all those characters, and then put that into a variable?
Upvotes: 6
Views: 5372
Reputation: 24476
-- It seems as though it is taking the actual serial number and reversing every two characters; am I typing something wrong or is this a known (but not documented anywhere) issue?
Best I can figure, it's apparently a bug. My characters are reversed by pair as well, and it's not limited to wmic. Same result if I SELECT SerialNumber FROM Win32_DiskDrive
from winmgmts:\\localhost\root\cimv2
in WSH.
-- Is there a way that I can take the variable, split it into two character chunks, reverse the order of all those characters, and then put that into a variable?
If you have PowerShell installed, you can do this with a regexp replace. Here's a batch script that invokes a PowerShell command to demonstrate:
@echo off
setlocal
for /f "tokens=*" %%I in ('wmic diskdrive get serialnumber ^| findstr "[0-9]"') do (
echo reversed: %%I
for /f "tokens=*" %%x in ('powershell -command "'%%I' -replace '(.)(.)','$2$1'"') do (
set "serial=%%x"
)
)
echo corrected: %serial%
goto :EOF
I guess this qualifies as a duck punch. :)
Actually, if you just want to see the serial without setting a variable, you can do this with a PowerShell one-liner:
powershell "gwmi win32_diskdrive | %{ $_.serialnumber -replace '(.)(.)','$2$1' }"
Upvotes: 5
Reputation: 1
After upgrading a Windows 7 OS install to Windows 10, I had no problems whatsoever seeing the HDD Serial Number of a WD drive displayed correctly when using: wmic diskdrive get model,name,SerialNumber,size
So it appears Microsoft decided to change how physical disk drive serial numbers are displayed.
Some helpful background info: If anyone runs the low-level ATA command to get information from a disk drive, every two characters of the model name and serial number are actually stored in reverse order! This may be related to what's called 'little endian' or it's simply how the ATA decided they should be stored.
Upvotes: 0
Reputation: 130869
All you need are some loops and basic substring operations.
I arbitrarily assume the number cannot exceed 100 characters.
@echo off
set "disk=3ZVT01H4"
echo Before: %disk%
call :swapChars disk
echo After: %disk%
exit /b
:swapChars var
setlocal enableDelayedExpansion
set "rtn="
for /l %%A in (0 2 100) do (
set /a "B=%%A+1"
for %%B in (!B!) do (
if "!%~1:~%%B,1!" equ "" goto :break
set "rtn=!rtn!!%~1:~%%B,1!!%~1:~%%A,1!"
)
)
:break
endlocal & set "%~1=%rtn%"
exit /b
Upvotes: 4