Search code examples
batch-filewmic

wmic works well in cmd but not work in batch file


i try write something to get the hdd index in a batch script, the command below in comand prompt works well

wmic diskdrive where "model like '%st%' and size > 300000000000" get index,model

it returns

Index  Model
1      ST1000DM010-2EP102

but when i use it inside batch script, it return 'no instances available':

@echo off

for /f "usebackq skip=1" %%a in (`wmic diskdrive where "model like '%st%' and size > 300000000000" get index`) do echo %%a

pause

result of script

No Instance(s) Available.

by the way, if there is a better way to get the hdd index in batch script.


wmic diskdrive where "model like '%st%' and size > 300000000000" get /format:csv

@Compo, The result of the command is showed as follows

Node,Availability,BytesPerSector,Capabilities,CapabilityDescriptions,Caption,CompressionMethod,ConfigManagerErrorCode,ConfigManagerUserConfig,CreationClassName,DefaultBlockSize,Description,DeviceID,ErrorCleared,ErrorDescription,ErrorMethodology,FirmwareRevision,Index,InstallDate,InterfaceType,LastErrorCode,Manufacturer,MaxBlockSize,MaxMediaSize,MediaLoaded,MediaType,MinBlockSize,Model,Name,NeedsCleaning,NumberOfMediaSupported,Partitions,PNPDeviceID,PowerManagementCapabilities,PowerManagementSupported,SCSIBus,SCSILogicalUnit,SCSIPort,SCSITargetId,SectorsPerTrack,SerialNumber,Signature,Size,Status,StatusInfo,SystemCreationClassName,SystemName,TotalCylinders,TotalHeads,TotalSectors,TotalTracks,TracksPerCylinder
W0400966,,512,{3;4},{Random Access;Supports Writing},ST1000DM010-2EP102,,0,FALSE,Win32_DiskDrive,,Disk drive,\\.\PHYSICALDRIVE1,,,,CC46,1,,IDE,,(Standard disk drives),,,TRUE,Fixed hard disk media,,ST1000DM010-2EP102,\\.\PHYSICALDRIVE1,,,3,SCSI\DISK&VEN_ST1000DM&PROD_010-2EP102\4&BFDEFCD&0&000100,,,0,0,0,1,63,            ZN1PYMST,3140447416,1000202273280,OK,,Win32_ComputerSystem,W0400966,121601,255,1953520065,31008255,255

Solution

  • In your first submitted, and working Command Prompt example, you are using a WMI LIKE Operator, % which is signifies 0 or more string characters.

    A percent character % is a special character in a batch file, so any literal would need to be escaped. The escape character for a percent is another percent.

    Therefore in order to reproduce that Command Prompt code, in a batch file, you would use:

    wmic diskdrive where "model like '%%st%%' and size > 300000000000" get index,model
    

    However, the Model substring you are wanting to match actually begins with ST, it doesn't include the two characters st in any position. For that reason your code should have been using ST%% as your pattern.

    %SystemRoot%\System32\wbem\WMIC.exe DiskDrive Where "Model Like 'ST%%' And Size > 300000000000" Get Index, Model
    

    Subsequently, you edited your question to show us that you weren't really wanting to reproduce the Command Prompt code, but wanting to run it as a For parenthesized command. In order to do that in your batch file, you would have needed to escape the unquoted comma:

    … In ('%SystemRoot%\System32\wbem\WMIC.exe DiskDrive Where "Model Like 'ST%%' And Size > 300000000000" Get Index^, Model 2^>NUL') Do …
    

    You will note above, that should the WMIC command report No Instance(s) Available., I decided to send that output to the NUL device, (which subsequently passes nothing through to the Do portion of the loop).

    It became clear that you did not want to report the Model string at all, but isolate a specific substring of its output, i.e. just the Index number. For that, I would advise that you define a variable using the returned value.

    @Echo Off
    SetLocal EnableExtensions DisableDelayedExpansion
    
    Set "Index="
    For /F "Tokens=2 Delims==" %%G In ('%SystemRoot%\System32\wbem\WMIC.exe
     DiskDrive Where "Model Like 'ST%%' And Size > 300000000000" Get Index
     /Value 2^>NUL') Do For %%H In (%%G) Do Set "Index=%%H"
    If Not Defined Index GoTo :EOF
    
    Rem Your code continues below here.
    Echo Your Disk Index is %Index%
    Pause
    

    I have included a couple of lines below the Remark, for demonstration purposes only. Feel free to replace those as needed for your specific task.