Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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?

like image 838
ITGuyLevi Avatar asked Dec 04 '14 15:12

ITGuyLevi


2 Answers

-- 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' }"
like image 197
rojo Avatar answered Nov 17 '22 03:11

rojo


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
like image 4
dbenham Avatar answered Nov 17 '22 04:11

dbenham