-1

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
Jacky
  • 3
  • 3
  • Works fine for me. Is `%st%` properly defined in your script? – Stephan Apr 01 '23 at 10:39
  • 2
    It's a batch file, you need to escape your percent wildcards! ```'%%st%%'```. – Compo Apr 01 '23 at 11:12
  • 1
    If you explain what exactly you need the drive index for, and show us the output from ```WMIC.exe DiskDrive Get /Format:CSV``` we may be able to assist you further. – Compo Apr 01 '23 at 11:24
  • 3
    Does this answer your question? [Set Variable to value of command](https://stackoverflow.com/questions/38742917/set-variable-to-value-of-command) Specifically, since `wmic` uses UTF-16 line endings, you either need to pipe the results to `findstr` or run it through a second `for` loop. – SomethingDark Apr 01 '23 at 12:39
  • That's what I figured. Is it properly defined in the script? Does the script work when you use the string directly (without using a variable)? – Stephan Apr 01 '23 at 15:17
  • @Compo escape percent wildcards '%%st%%' not work for me – Jacky Apr 01 '23 at 15:21
  • @Stephan when i set st='ST1000DM010-2EP102' it works indeed, but I want to use fuzzy matching to match the model of hdd – Jacky Apr 01 '23 at 15:44
  • You can tell me that if you like @Jacky, but you are most certainly wrong. I can guarantee the the fix for your working Command Prompt version in a batch file, is what I told you! However, as we now know the string you were trying to match, I would say you definitely wanted to use ```@%SystemRoot%\System32\wbem\WMIC.exe DiskDrive Where "Model Like 'ST%%' And Size > 300000000000" Get Index, Model```, because you are only needing to wildcard the trailing characters, leading ones don't exist. – Compo Apr 01 '23 at 15:52
  • However, as you've completely changed your code, to run that within a `For /F` loop, it would look like this ```In ('%SystemRoot%\System32\wbem\WMIC.exe DiskDrive Where "Model Like 'ST%%' And Size > 300000000000" Get Index^, Model 2^>NUL') Do```. – Compo Apr 01 '23 at 15:58
  • @Compo it really works! The difference between command prompt and batch file does confuse me a lot, thank you very much for your patience in explaining – Jacky Apr 01 '23 at 16:05
  • when you `set st='ST1000DM010-2EP102'`, what do you think `'%st%'` expands to? (Tip: `''ST1000DM010-2EP102''`) – Stephan Apr 01 '23 at 16:16
  • @Stephan, Compo is right, i just want to wildcard the substring in the model – Jacky Apr 01 '23 at 16:20
  • I reopened this question, because it was closed as a duplicate of a problem which was nothing to do with the reported issue. The issue, which was subsequently confirmed by the OP, was about the escaping of literal percent characters. Their use of `%st%` was not a variable for expansion, it was a wmi 'like" operator pattern. Isolating a substring of a commands output was only a secondary problem, which only became known after the OP later edited their question. – Compo Apr 02 '23 at 11:29

1 Answers1

0

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.

Compo
  • 36,585
  • 5
  • 27
  • 39