ITGuyLevi
ITGuyLevi

Reputation: 88

WMIC Returning Odd Serial Number

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

Answers (3)

rojo
rojo

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

TheStarman
TheStarman

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

dbenham
dbenham

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

Related Questions