<http://www.netikka.net/tsneti/info/tscmd101.htm>
Copyright © 2003-2012 by Prof. Timo Salmi  
Last modified Tue 28-Aug-2012 04:00:37

 
Assorted NT/2000/XP/.. CMD.EXE Script Tricks
From the html version of the tscmd.zip 1cmdfaq.txt file
To the Description and the Index
 

This page is edited from the 1cmdfaq.txt faq-file contained in my tscmd.zip command line interface (CLI) collection. That zipped file has much additional material, including a number of detached .cmd script files. It is recommended that you also get the zipped version as a companion.

Please see "The Description and the Index page" for the conditions of usage and other such information.



101} How to capture Volume Serial Number into an environment variable?

  @echo off & setlocal enableextensions
  for /f "skip=1 tokens=5" %%s in ('vol c:') do set volc_=%%s
  echo %volc_%
  endlocal & goto :EOF

The output could be e.g.
  C:\_D\TEST>cmdfaq
  D634-E1B2

Why the skip=1? Do the "math". Because the output of VOL C: is
  C:\_D\TEST>vol c:
  Volume in drive C is MY_C
  Volume Serial Number is D634-E1B2

The task of finding the Volume Serial Number can also be programmed as a subroutine, including at the same time a slightly more advanced handling
  @echo off & setlocal enableextensions
  set dr_=C
  if not "%~1"=="" set dr_=%~1
  call :GetVolSerialNr %dr_% ser_
  echo %ser_%
  endlocal & goto :EOF
  ::
  ::===============================================================
  :GetVolSerialNr
  setlocal enableextensions
  set return_=NoInfo
  dir %~1: > "%temp%\tmp$$$.dir" 2>&1
  find "The system cannot find the path specified" "%temp%\tmp$$$.dir" > nul
  if %errorlevel% EQU 0 (set return_=DeviceNotFound&goto _endGetVolSerialNr)
  dir %~1: > "%temp%\tmp$$$.dir" 2>&1
  find "The device is not ready" "%temp%\tmp$$$.dir" > nul
  if %errorlevel% EQU 0 (set return_=DeviceNotReady&goto _endGetVolSerialNr)
  for /f "skip=1 tokens=5" %%s in ('vol %~1:') do set return_=%%s
  :_endGetVolSerialNr
  for %%f in ("%temp%\tmp$$$.dir") do if exist %%f del %%f
  endlocal & set %2=%return_%&goto :EOF

The output could be e.g.
  C:\_D\TEST>cmdfaq
  D634-E1B2
or
  C:\_D\TEST>cmdfaq E
  DeviceNotFound
or
  C:\_D\TEST>cmdfaq N
  DeviceNotReady

It might be instructive to also have a Visual Basic Script solution. First, the volume name:
  @echo off & setlocal enableextensions
  ::
  :: Build a Visual Basic Script

  set vbs_=%temp%\tmp$$$.vbs
  set skip=
  findstr "'%skip%VBS" "%~f0" > "%vbs_%"
  ::
  :: Run the VBS script with Microsoft Windows Script Host Version 5.6

  for /f "delims=" %%a in ('cscript //nologo "%vbs_%" "%CD%"') do (
    set s_=%%a)
  ::
  :: Display the result

  echo %s_%
  ::
  :: Clean up

  for %%f in ("%vbs_%") do if exist %%f del %%f
  endlocal & goto :EOF
  '
  '................................................................
  'The Visual Basic Script
  '

  Set arg = WScript.Arguments 'VBS
  Wscript.Echo ShowVolumeInfo(arg(0)) 'VBS
  '
  Function ShowVolumeInfo(drvpath) 'VBS from the Windows Script Documentation
    Dim fso, d, s 'VBS
    Set fso = CreateObject("Scripting.FileSystemObject") 'VBS
    Set d = fso.GetDrive(fso.GetDriveName(fso.GetAbsolutePathName(drvpath))) 'VBS
    s = "Drive " & d.DriveLetter & ": - " & d.VolumeName 'VBS
    ShowVolumeInfo = s 'VBS
  End Function 'VBS

The output might be e.g.
  C:\_D\TEST>cmdfaq
  Drive C: - MYCDRIVE
GetAbsolutePathName: Returns a complete and unambiguous path from a provided path specification.
GetDriveName: Returns a string containing the name of the drive for a specified path.
GetDrive: Returns a Drive object corresponding to the drive in a specified path.

Likewise:
  @echo off & setlocal enableextensions
  ::
  :: Build a Visual Basic Script

  set vbs_=%temp%\tmp$$$.vbs
  set skip=
  findstr "'%skip%VBS" "%~f0" > "%vbs_%"
  ::
  :: Run the VBS script with Microsoft Windows Script Host Version 5.6

  for /f "delims=" %%a in ('cscript //nologo "%vbs_%" "%CD%"') do (
    set s_=%%a)
  ::
  :: Display the result

  echo %s_%
  ::
  :: Clean up

  for %%f in ("%vbs_%") do if exist %%f del %%f
  endlocal & goto :EOF
  '
  '................................................................
  'The Visual Basic Script
  '

  Set arg = WScript.Arguments 'VBS
  Wscript.Echo ShowDriveInfo(arg(0)) 'VBS
  '
  Function ShowDriveInfo(drvpath) 'VBS
    Dim fso, d, s, t 'VBS
    Set fso = CreateObject("Scripting.FileSystemObject") 'VBS
    Set d = fso.GetDrive(fso.GetDriveName(fso.GetAbsolutePathName(drvpath))) 'VBS
    Select Case d.DriveType 'VBS
      Case 0: t = "Unknown" 'VBS
      Case 1: t = "Removable" 'VBS
      Case 2: t = "Fixed" 'VBS
      Case 3: t = "Network" 'VBS
      Case 4: t = "CD-ROM" 'VBS
      Case 5: t = "RAM Disk" 'VBS
    End Select 'VBS
    s = "Drive " & d.DriveLetter & ": - " & t 'VBS
    s = s & ", SN: " & Left(Hex(d.SerialNumber),4) 'VBS
    s = s & "-" & Right(Hex(d.SerialNumber),4) 'VBS
    ShowDriveInfo = s 'VBS
  End Function 'VBS

  C:\_D\TEST>cmdfaq
  Drive C: - Fixed, SN: D634-E1B2



You can also get the label of a volume in a very similar manner:
  @echo off & setlocal enableextensions
  set target_=C:\
  for /f "tokens=5*" %%f in (
    'dir %target_%^|find "Volume in drive "') do (
      set label_=%%g)
  echo The label of Volume %target_% is %label_%
  endlocal & goto :EOF

  C:\_D\TEST>cmdfaq
  The label of Volume C:\ is MYCDRIVE
Explanation of the 5*, %%f and %%g. Obviously, the label is the sixth token. But one has to take into account the eventuality that there might be a space in the label. If one just used 6, %%f and %%f the only the first part of such a label would be included. The 5*, %%f and %%g formulation gets into %%g everything that comes after the fifth token, which is exactly what we want.

Programmed as a subroutine we have
  @echo off & setlocal enableextensions
  set target_=D:
  ::
  call :IsDeviceReady %target_% isready_
  echo Device %target_% ready: %isready_%
  if /i "%isready_%"=="false" (endlocal & goto :EOF)
  ::
  call :GetLabel %target_% label_
  echo The label of Volume %target_% is %label_%
  endlocal & goto :EOF
  ::
  :IsDeviceReady
  setlocal
  set ready_=true
  dir "%~1" > nul 2>&1
  if %errorlevel% NEQ 0 set ready_=false
  endlocal & set "%2=%ready_%" & goto :EOF
  ::
  :GetLabel
  setlocal
  for /f "tokens=5*" %%a in (
    'vol "%~1"^|find "Volume in drive "') do (
      set label_=%%b)
  endlocal & set "%2=%label_%" & goto :EOF

The subroutine can also be written without the find as
  :GetLabel
  setlocal
  for /f "tokens=5*" %%a in (
    'vol "%~1"') do (
      set label_=%%b& goto _ExitGetLabel)
  :_ExitGetLabel
  endlocal & set "%2=%label_%" & goto :EOF