通过批处理和WMI,找出指定目录或文件的物理磁盘信息。
- 当前逻辑磁盘盘符
- 物理磁盘型号
- 物理磁盘总容量
- 物理磁盘接口类型
- ...
::############################################################################################
::#
::# Name : driveinfo
::#
::# Purpose: Obtain disk information.
::#
::# File : driveinfo.cmd
::#
::# Authors: perry <ppsoft268@gmail.com>
::#
::# Date : June 14, 2011
::#
::# Version: 1.0.0
::#
::#
::# Usage : driveinfo.cmd /T:[IDE/ATA/USB/SATA] [/P:path] [/H] [/?]
::# /T: type specify the bus type of drive, (e.g IDE/ATA/USB/SATA)
::# /P: path specify the path of drive, (e.g F:\)
::# /H help show help information.
::# /? help same as /H.
::#
::#
::#
::# Version History and Revision List:
::# Date Version Auther Description
::# ----------------------------------------------------------------------
::# 2011/06/14 V1.0.0 perry initial version.
::#
::############################################################################################
:SA1-0
@setlocal enabledelayedexpansion
@title drive
@echo off
::# clear arguments.
for /f "tokens=1 delims==" %%i in ('set $p2_ 2^>nul') do (
set %%i=)
set $r1_1=1
set $p1_1=
set $p1_2=
set $p1_3=%*
set $p1_4=
set $p2_1=/T:
set $p2_2=/P:
set $p2_3=/H
set $p2_4=/?
set $t1_1=wmic.exe
::#
::# command parsing.
::# switch options: /P: /T: /H /?
::# /T: type specify the bus type of drive, (e.g IDE/ATA/USB/SATA)
::# /P: path specify the path of drive, (e.g F:\)
::# /H help show help information.
::# /? help same as /H.
::# the switch flag only can be [/].
:SA1-1
for /l %%i in (0, 1, 512) do (
::# moving $p1_4 to $p1_3 at offset %%i.
set $p1_4=!$p1_3:~%%i!
::# if find the end of the string, exit!
if "!$p1_4!" == "" goto :SA1-2
::# determine the first character is equal "/".
if "!$p1_4:~0,1!" == "/" (
::# list out all the variables by the name beginning with $p2_.
for /f "tokens=1 delims==" %%j in ('set $p2_ 2^>nul') do (
::# find all the defined keywords. the name prefix of these variables must be [$p2_].
set $p1_1=!%%~j!
::# assumption is based on two characters to compare.
set $p1_2=!$p1_4:~0,2!
::# whether have one or more match parameters?
if /i "!$p1_2!" == "!$p1_1!" (
set %%~j=+)
::# assumption is based on three characters to compare.
set $p1_2=!$p1_4:~0,3!
::# whether have one or more match parameters?
if /i "!$p1_2!" == "!$p1_1!" (
::# call the function [argstr] to obtain the correct parameters.
call :f2-1 "%%~j", "!$p1_4:~3!"))))
:SA1-2
::# display help information.
if not "%$p2_3%" == "/H" (
call :f6-1
goto :SA1-3)
::# display help information.
if not "%$p2_4%" == "/?" (
call :f6-1
goto :SA1-3)
::# confirm each executable files whether correct, we need to ensure that they work normally
::# in this script. if the check is fails, this script will report an error.
for /f "tokens=2 delims==" %%i in ('set $t1_ 2^>nul') do (
if not exist "%%~$PATH:i" (
echo.%%~i is missing.
goto :SA1-3))
::# if ignore the $p2_2 param, we'll set it to path of this script.
if "%$p2_2%" == "/P:" (
set $p2_2=%~0) else (
if "%$p2_2%" == "%$p2_2::=%" (
set $p2_2=!$p2_2!:))
::# the $p2_2 must exist.
if not exist "%$p2_2%" (
echo.ERROR: path not found.
goto :SA1-3)
::# the $p2_1 must be valid.
if "%$p2_1%" == "/T:" (
echo.ERROR: Invalid parameters.
goto :SA1-3)
::# default is root path for this script.
set $d1-0=%~d0
set $d1-1=N/A
set $d1-2=N/A
set $d1-3=N/A
set $d1-4=0
set $d1-5=GB
::# if $p2_2 is not a script path,
::# we need to get the drive letter for $p2_2.
for /f "delims=/" %%i in ("%$p2_2%") do (
set $d1-0=%%~di) 2>&1 1>nul
::# Obtain the disk index for the drive.
for /f "delims=/" %%i in ('%$t1_1% Path CIM_LogicalDiskBasedOnPartition Get Antecedent^, Dependent') do (
set /p=%%~i<nul | findstr /I "Win32_LogicalDisk.DeviceID=.%$d1-0%." && (
call :f4-1 "$d1-1", "Disk #", "%%~i")) 2>&1 1>nul
::# if can't get the disk index, exit script.
call :f1-1 "%$d1-1%" || (
echo.ERROR: disk not found.
goto :SA1-3)
::# Obtain model/size/bus for disk drive. use the WMIC tool.
for /f "tokens=1,* delims==" %%i in ('%$t1_1% DiskDrive Where "Index=%$d1-1%" Get Model^, Size^, InterfaceType /Value') do (
if /i "%%~i" == "Model" (
set $d1-2=%%~j)
if /i "%%~i" == "InterfaceType" (
set $d1-3=%%~j)
if /i "%%~i" == "Size" (
call :f3-1 "$d1-4", "$d1-5", "%%~j" || (
set $d1-4=%%~j
set $d1-4=!$d1-4: =!
set $d1-4=!$d1-4:~0,-7!
set /a $d1-4/=0x3e8
set $d1-5=GB)))
::# show disk information.
echo.Disk Information:
echo. Letter: %$d1-0%
echo. Index: %$d1-1%
echo. Model: %$d1-2%
echo. Size: %$d1-4%%$d1-5%
echo. Interface: %$d1-3%
::# compare to the interface type of the disk.
::# if not same, the return value is non-zero.
if /i "%$p2_1%" == "%$d1-3%" set $r1_1=0
::# script exit.
:SA1-3
::# Return an error code to the calling process.
exit /b %$r1_1%
goto :eof
::#
::# --function description--
::# Test whether an string can be evaluated as a number.
::#
::# Input Parameters:
::# P1: a string for argument analysis.
::#
::# Note: each parameters must be included in double quotes("").
::#
::# Output:
::# ERRORLEVEL
::# if the function executed is successfully, the errorlevel is
::# zero. Otherwise, the errorlevel is non-zero.
::#
::# Examples:
::# call :f1-1 "input"
::#
::#
::# --function begin--
::#
:f1-1
::#
set $r2_1=1
set $c2_1=%~1
set $c2_2=0123456789
::#
::# if the parameter of input is invalid.
::# Now, we'll returned a error code.
if not defined $c2_1 goto :f1-2
if "%$c2_1%" == "" goto :f1-2
::#
::# check the number is in range 0 to 9.
call set $c2_2=%%$c2_2:%$c2_1%=%%
if not "%$c2_2%" == "0123456789" set $r2_1=0
::#
:f1-2
::# release the local variables.
set $c2_2=
set $c2_1=
::#
::# function is exit normal, the returned code is zero.
::# Otherwise, the returned code is 1.
set $r2_1=&exit /b %$r2_1%
::#
::# --function end--
::#
::# --function description--
::# trim a string leading and trailing spaces or double quotes("").
::#
::# Input Parameters:
::# P1: a string that specifies the name of output variable.
::# P2: a string for argument analysis.
::#
::# Note: each parameters must be included in double quotes("").
::#
::# Output:
::# ERRORLEVEL
::# if the function executed is successfully, the errorlevel is
::# zero. Otherwise, the errorlevel is non-zero.
::#
::# Examples:
::# call :f2-1 "output", "input"
::#
::#
::# --function begin--
::#
:f2-1
::#
set $r3_1=1
set $c3_1=%*
set $c3_2=
set $c3_3=0
set $q3_1=no
set $t3_1=yes
::#
::# we need to remove the command line first parameter.
call set $c3_1=%%$c3_1:%1,=%%
::#
::# if the string is not available, so we will not do anything.
if not defined $c3_1 goto :f2-5
::#
:f2-2
call set $c3_2=%%$c3_1:~%$c3_3%,1%%
::#
::# if find a space character, We will ignore it until find a non-space character.
set /a $c3_3+=0x01
if "%$c3_2%%$c3_2%" == " " (
goto :f2-2)
::#
::# if find a double quote, We think it is an start symbol of the argument.
if "%$c3_2%%$c3_2%" == """" (
set /a $c3_3+=0x01
set $q3_1=yes)
::#
::# if find a slash, We think it is an invalid argument.
if "%$c3_2%%$c3_2%" == "//" (
if "%$q3_1%" == "no" (
goto :f2-5))
::#
set /a $c3_3-=0x01
::#
::# if the effective length of the argument is 0.
::# we'll stop the string analysis.
call set $c3_2=%%$c3_1:~%$c3_3%,1%%
if "%$c3_2%%$c3_2%" == "" (
goto :f2-5)
::#
::# truncate the string from the start symbol, and then start
::# from first characters to search the end symbol in this string
call set $c3_1=%%$c3_1:~%$c3_3%%%
set $c3_3=0
::#
:f2-3
call set $c3_2=%%$c3_1:~%$c3_3%,1%%
set /a $c3_3+=0x01
::#
::# here is to avoid unterminated string causes an endless loop.
::# exit loop if detected a invalid character in the string.
if "%$c3_2%%$c3_2%" == "" (
goto :f2-4)
::#
::# if find a space character, and the leading of the string is not a double quote.
::# we think this is the end of a parameter.
if "%$c3_2%%$c3_2%" == " " (
if "%$q3_1%" == "no" (
goto :f2-4))
::#
::# if find a slash, and the leading of the string is not a double quote.
::# we think that this slash is the leading of the next switch.
::# so stop the string analysis.
if "%$c3_2%%$c3_2%" == "//" (
if "%$q3_1%" == "no" (
goto :f2-4))
::# if find a double quote, and the leading of the string aslo is a double quote.
::# now we can think this is a qualified string.
if "%$c3_2%%$c3_2%" == """" (
if "%$q3_1%" == "yes" (
goto :f2-4))
goto :f2-3
:f2-4
if %$c3_3% EQU 1 goto :f2-5
set /a $c3_3-=0x01
call set %~1=%%$c3_1:~0,%$c3_3%%%
set $r3_1=0
:f2-5
::# release the local variables.
set $c3_3=
set $t3_1=
set $q3_1=
set $c3_1=
set $c3_2=
::# function is exit normal, the returned code is zero.
::# Otherwise, the returned code is 1.
set $r3_1=&exit /b %$r3_1%
::# --function end--
::#
::# --function description--
::# parse string for disk size information.
::# the WMIC output format string (e.g 250056737280 = 250GB
::# 1998743040 = 2GB)
::# We want to get the integer number for the disk size.
::#
::# Input Parameters:
::# P1: the name of output variable for [size].
::# P2: the name of output variable for [unit].
::# P3: input string.
::#
::# Note: each parameters must be included in double quotes("").
::#
::# Output:
::# ERRORLEVEL
::# if the function executed is successfully, the errorlevel is
::# zero. Otherwise, the errorlevel is non-zero.
::#
::# Examples:
::# call :f3-1 "output size", "output units", "input"
::#
::#
::# --function begin--
::#
:f3-1
::#
set $r4_1=1
set $c4_1=
set $c4_2=%~3
set $c4_3=GB
set $n4_1=0
set $n4_2=0
set $s4_1=0
set $s4_2=
set $s4_3=0
::#
::# If the string is not available, so we will not do anything.
if not defined $c4_2 goto :f3-5
::#
::# If the string is not available, so we will not do anything.
if "%$c4_2%" == "" goto :f3-5
::#
::# We need to remove the double quotes in the string.
call set $c4_2=%%$c4_2:"=%%
::# We need to remove the space characters in the string.
if defined $c4_2 call set $c4_2=%%$c4_2: =%%
:f3-2
::# get the first char.
call set $c4_1=%%$c4_2:~%$n4_2%,1%%
::# here is to avoid unterminated string causes an endless loop.
::# exit loop if detected a invalid character in the string.
if not defined $c4_1 goto :f3-3
if "%$c4_1%" == "" goto :f3-3
::# check the number is in range 0 to 9.
::# if find out a non-numeric character,
::# we will ignore it until find a numeric character.
set /a $n4_2+=0x01
call :f1-1 "%$c4_1%" || (
goto :f3-2)
set $s4_2=%$s4_2%%$c4_1%
goto :f3-2
:f3-3
::# We need to remove the first space characters.
call set $s4_2=%%$s4_2: =%%
::# If the string is not available, so we will not do anything.
if "%$s4_2%" == " " goto :f3-5
set $c4_2=%$s4_2%
:f3-4
::# calculating the length for keyword string.
call :f5-1 "$s4_3", "%$s4_2%"
if %$s4_3% GTR 3 (
set $s4_2=!$s4_2:~0,-3!
set /a $s4_1+=0x01
goto :f3-4)
set $n4_1=%$s4_2%
call :f5-1 "$s4_3", "%$n4_1%"
call set $s4_2=%%$c4_2:~%$s4_3%,1%%
call :f1-1 "%$s4_2%" && (
if %$s4_2% GTR 5 set /a $n4_1+=0x01)
::# units of disk size.
set $s4_2= KMGTPE
call set $s4_2=%%$s4_2:~%$s4_1%,1%%
set $c4_3=%$s4_2%B
set $r4_1=0
:f3-5
if not "%~1" == "" set %~1=%$n4_1%
if not "%~2" == "" set %~2=%$c4_3%
::# release the local variables.
set $n4_2=
set $s4_1=
set $s4_3=
set $c4_3=
set $n4_1=
set $c4_1=
set $s4_2=
set $c4_2=
::# if function exit normal, returned code is zero.
::# Otherwise, the returned code is 1.
set $r4_1=&exit /b %$r4_1%
::# --function end--
::# --function description--
::# parse a disk index from a string.
::# the reg format string (IDE\DiskHitachi_HTS132112K3SA00_BB2OC31P\1&&0&0.0.0
::# Channel 5, Target 0...)
::# We want to get the characters "5". and convert it to a numerical.
::#
::# Input Parameters:
::# P1: a string that specifies the name of output variable.
::# P2: a string that specifies the search keyword.
::# P3: a string for argument analysis.
::#
::# Note: each parameters must be included in double quotes("").
::#
::# Output:
::# ERRORLEVEL
::# if the function executed is successfully, the errorlevel is
::# zero. Otherwise, the errorlevel is non-zero.
::#
::# Examples:
::# call :f4-1 "output", "keyword", "input"
::#
::#
::# --function begin--
::#
:f4-1
::#
set $r5_1=1
set $e5_1=
set $t5_1=%*
set $k5_1=%~2
set $n5_1=0
set $n5_3=0
::# We need to remove the command line first and the second parameter.
call set $t5_1=%%$t5_1:%1,=%%
call set $t5_1=%%$t5_1:%2,=%%
::# If the string is not available, so we will not do anything.
if not defined $t5_1 goto :f4-3
::# calculating the length for keyword string.
call :f5-1 "$n5_1", "%$k5_1%"
::# If the keyword is not available, so we will not do anything.
if %$n5_1% EQU 0 goto :f4-3
::# Removed some of the special string.
call set $t5_1=%%$t5_1:"=%%
call set $t5_1=%%$t5_1:\=%%
:f4-2
call set $e5_1=%%$t5_1:~%$n5_3%,%$n5_1%%%
::# here is to avoid unterminated string causes an endless loop.
::# exit loop if detected a invalid character in the string.
if not defined $e5_1 goto :f4-3
if "%$e5_1%" == "" goto :f4-3
::# If find a non-anchor string,
::# We will ignore it until find a anchor string.
if not "%$e5_1%" == "%~2" (
set /a $n5_3+=0x01
goto :f4-2)
::# skip the string to offset $n5_1 character.
set /a $n5_3+=$n5_1
call set $e5_1=%%$t5_1:~%$n5_3%,1%%
::# check the number is in range 0 to 9.
call :f1-1 "%$e5_1%" && (
call set %~1=%$e5_1%
::# function is exit normal, the returned code is zero.
set $r5_1=0
goto :f4-3)
:f4-3
::# release the local variables.
set $n5_3=
set $n5_1=
set $e5_1=
set $t5_1=
::# if find a valid numeric value,
::# this function will exit normal, here returned code is zero.
::# Otherwise, the returned code is 1.
set $r5_1=&exit /b %$r5_1%
::# --function end--
::#
::# --function description--
::# to determine the length of a string.
::#
::# Input Parameters:
::# P1: the name of output variable.
::# P2: input string.
::#
::# Note: each parameters must be included in double quotes("").
::#
::# Output:
::# ERRORLEVEL
::# if the function executed is successfully, the errorlevel is
::# zero. Otherwise, the errorlevel is non-zero.
::#
::# Examples:
::# call :f5-1 "output size", "input"
::#
::#
::# --function begin--
::#
:f5-1
::#
set $r6_1=1
set $t6_1=%~2
set $n6_1=0
::#
::# If the string is not available, so we will not do anything.
if not defined $t6_1 goto :f5-4
::# calculating the length for a string.
:f5-2
if "%$t6_1%" == "" goto :f5-3
set $r6_1=0
set $t6_1=%$t6_1:~0,-1%
set /a $n6_1+=0x01
goto :f5-2
:f5-3
:f5-4
set %~1=%$n6_1%
::# release the local variables.
set $t6_1=
set $n6_1=
::# if function exit normal, returned code is zero.
::# Otherwise, the returned code is 1.
set $r6_1=&exit /b %$r6_1%
::# --function end--
::# --function description--
::#
::# Input Parameters:
::# N/A.
::#
::# Output:
::# ERRORLEVEL
::# if the function executed is successfully, the errorlevel is
::# zero. Otherwise, the errorlevel is non-zero.
::#
::# Examples:
::# call :f6-1
::# --function begin--
:f6-1
::#
echo.
echo.driveinfo.cmd ^(Version: V1.0.0^)
echo.
echo.Usage: driveinfo.cmd /P:[filepath] [/T:[IDE/ATA/USB/SATA]] [/H] [/?]
echo.
echo. Options:
echo. /P: path is a file or directory path.
echo. /T: type specify the bus type of HDD, (e.g IDE/ATA/USB/SATA)
echo. /H help show help information.
echo. /? help same as /H.
echo.
::# function is exit normal, the returned code is zero.
::# this function returned succeed alway.
exit /b 0
::# --function end--