Jump to content

Batch script list drives.


Recommended Posts

The following script works as expected but I'd like an explanation of why the command CMD /C is necessary for it to run if the drive list contains drive a.

This works:

@echo off
cls
setlocal

for %%1 in (a b c d e f g h i j k l m n o p q r s t u v w x y z) do (
cmd /c if exist %%1:\ (
fsutil fsinfo drivetype %%1:
)
)

This hangs with a "no disk in drive" error message.

@echo off
cls
setlocal

for %%1 in (a b c d e f g h i j k l m n o p q r s t u v w x y z) do (
if exist %%1:\ (
fsutil fsinfo drivetype %%1:
)
)

Link to comment
Share on other sites


I added some "ELSE" logic, give it a try.

@echo off
cls
setlocal

for %i in (a b c d e f g h i j k l m n o p q r s t u v w x y z) do (if exist %i:\ (fsutil fsinfo drivetype %i: )ELSE (fsutil fsinfo drivetype %i:))

The CMD /C tells your script to give up when your if exist statement fails, which does not happen in your second script because it does not have a 'ELSE' block.

/C Carries out My_Command and then terminates

More Details Here and Here

Edited by MrJinje
Link to comment
Share on other sites

Try reversing the logic of it.

Fsutil does NOT throw an error if a drive is not accessible, BUT it will report an error message.

In my Italian XP this error is "Directory principale non esistente"

Thus this works:

@ECHO OFF

for %%1 in (a b c d e f g h i j k l m n o p q r s t u v w x y z) do (
fsutil fsinfo drivetype %%1: |FIND /V "Directory")

jaclaz

Link to comment
Share on other sites

You can use DISKPART too, I feel it's a better tool for this type of thing:

C:\> ECHO LIST VOL | DISKPART | FIND "NTFS"
Volume 1 C System NTFS Partition 20 GB Healthy System

Replace NTFS with CDFS to find the CDROM's. You'll have to do some parsing of the results, but this is cleaner and quicker than most methods.

Edited by Noise
Link to comment
Share on other sites

You could also get this incredibly easily with Win32_LogicalDisk from WMI and some vbscript:

RunMeWithCscript()

strComputer = "."
Set objWMIService = GetObject("winmgmts:\\" & strComputer & "\root\CIMV2")
Set colDiskItems = objWMIService.ExecQuery( _
"SELECT * FROM Win32_LogicalDisk",,48)

For Each objDiskItem in colDiskItems
If objDiskItem.DriveType = 3 Then
Wscript.Echo " Volume: " & objDiskItem.Caption
Wscript.Echo " Drive Type: " & objDiskItem.Description
Wscript.Echo " Compressed: " & objDiskItem.Compressed
Wscript.Echo " File System: " & objDiskItem.FileSystem
Wscript.Echo " Volume Size: " & FormatNumber(objDiskItem.Size/1024^3, 2) & " GB"
Wscript.Echo " Free Space: " & FormatNumber(objDiskItem.FreeSpace/1024^3, 2) & " GB"
Wscript.Echo " VolumeDirty: " & objDiskItem.VolumeDirty
Wscript.Echo " VolumeSerialNumber: " & objDiskItem.VolumeSerialNumber
Wscript.Echo ""
End If

If objDiskItem.DriveType = 5 Then
Wscript.Echo " Volume: " & objDiskItem.Caption
Wscript.Echo " Drive Type: " & objDiskItem.Description
If Not objDiskItem.FileSystem = "" Then
Wscript.Echo " File System: " & objDiskItem.FileSystem
Wscript.Echo " Volume Size: " & FormatNumber(objDiskItem.Size/1024^3, 2) & " GB"
Wscript.Echo " Free Space: " & FormatNumber(objDiskItem.FreeSpace/1024^3, 2) & " GB"
End If
Wscript.Echo ""
End If

If objDiskItem.DriveType = 2 Then
Wscript.Echo " Volume: " & objDiskItem.Caption
Wscript.Echo " Drive Type: " & objDiskItem.Description
If Not objDiskItem.FileSystem = "" Then
Wscript.Echo " File System: " & objDiskItem.FileSystem
Wscript.Echo " Volume Size: " & FormatNumber(objDiskItem.Size/1024^3, 2) & " GB"
Wscript.Echo " Free Space: " & FormatNumber(objDiskItem.FreeSpace/1024^3, 2) & " GB"
End If
Wscript.Echo ""
End If
Next


'//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
'// Subroutine: RunMeWithCScript()
'//
'// Purpose: Forces the currently running script to use Cscript.exe as the Script
'// engine. If the script is already running with cscript.exe the sub exits
'// and continues the script.
'//
'// Sub Attempts to call the script with its original arguments. Arguments
'// that contain a space will be wrapped in double quotes when the script
'// calls itself again. To verify your command string you can echo out the
'// scriptCommand variable.
'//
'// Usage: Add a call to this sub (RunMeWithCscript) to the beggining of your script
'// to ensure that cscript.exe is used as the script engine.
'//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Public Sub RunMeWithCScript()

Dim scriptEngine, engineFolder, Args, arg, scriptName, argString, scriptCommand

scriptEngine = Ucase(Mid(Wscript.FullName,InstrRev(Wscript.FullName,"\")+1))
engineFolder = Left(Wscript.FullName,InstrRev(Wscript.FullName,"\"))
argString = ""

If scriptEngine = "WSCRIPT.EXE" Then
Dim Shell : Set Shell = CreateObject("Wscript.Shell")
Set Args = Wscript.Arguments

For each arg in Args 'loop though argument array as a collection to rebuild argument string
If instr(arg," ") > 0 Then arg = """" & arg & """" 'if the argument contains a space wrap it in double quotes
argString = argString & " " & Arg
Next

'Create a persistent command prompt for the cscript output window and call the script with its original arguments
scriptCommand = "cmd.exe /k " & engineFolder & "cscript.exe """ & Wscript.ScriptFullName & """" & argString

Shell.Run scriptCommand,,False
Wscript.Quit
Else
Exit Sub 'Already Running with Cscript Exit this Subroutine
End If
End Sub

Link to comment
Share on other sites

Well, if order of columns is not a problem, a one-liner is possible at WMIC too:

wmic.exe path Win32_Logicaldisk Get description^, name

To change the order of the column is trickier that it might seem:

@ECHO OFF
SETLOCAL ENABLEDELAYEDEXPANSION
FOR /f "tokens=2,3 delims=," %%A IN ('wmic.exe path Win32_Logicaldisk Get name^, description /FORMAT:csv.xsl') DO (
SET Tempvar=%%A,%%B
FOR /F "tokens=1,2 delims=," %%C IN ('ECHO !TempVar!') DO ECHO %%D %%C
)

jaclaz

Link to comment
Share on other sites

Well, if order of columns is not a problem, a one-liner is possible at WMIC too:

wmic.exe path Win32_Logicaldisk Get description^, name

To change the order of the column is trickier that it might seem:

@ECHO OFF
SETLOCAL ENABLEDELAYEDEXPANSION
FOR /f "tokens=2,3 delims=," %%A IN ('wmic.exe path Win32_Logicaldisk Get name^, description /FORMAT:csv.xsl') DO (
SET Tempvar=%%A,%%B
FOR /F "tokens=1,2 delims=," %%C IN ('ECHO !TempVar!') DO ECHO %%D %%C
)

jaclaz

Or:
@FOR /F "TOKENS=* DELIMS=," %%# IN ('WMIC LOGICALDISK GET NAME^, DESCRIPTION^
/FORMAT:CSV^|FIND ":"') DO @FOR /F "TOKENS=2,3 DELIMS=," %%A IN ("%%#"
) DO @ECHO %%B %%A)

Link to comment
Share on other sites

Cluberti - Yes, the script runs without error when Cmd /k is used.

Thanks to all for your interest and responses.

V.

That would mean indeed it's because the check for A is failing in fsutil, and using /C or /K causes a new cmd.exe process to spawn to do the check, which will return to the original cmd.exe to continue the next step in the loop regardless of whether or not the previous operation failed or not. Using cmd without switches means it runs the check in the same cmd.exe process, and thus the fsutil command being stuck will block the rest of the drive letters from being parsed. I would suggest using the vbscript I posted above, the wmic command from jaclaz or Yzowl if you must do this in a .cmd file, or make sure you call this with cmd /c or /k.

Link to comment
Share on other sites

That would mean indeed it's because the check for A is failing in fsutil, and using /C or /K causes a new cmd.exe process to spawn to do the check, which will return to the original cmd.exe to continue the next step in the loop regardless of whether or not the previous operation failed or not. Using cmd without switches means it runs the check in the same cmd.exe process, and thus the fsutil command being stuck will block the rest of the drive letters from being parsed. I would suggest using the vbscript I posted above, the wmic command from jaclaz or Yzowl if you must do this in a .cmd file, or make sure you call this with cmd /c or /k.

Well, no, as said, it's not fsutil the problem, as it runs normally on non existing drives it's the "if exist" check.

jaclaz

Link to comment
Share on other sites

it's not fsutil the problem, as it runs normally on non existing drives it's the "if exist" check.

That is correct, if anyone looks at my post, the fix was to run FSUTIL during the else statement. :whistle:


for %i in (a b c d e f g h i j k l m n o p q r s t u v w x y z) do (if exist %i:\ (fsutil fsinfo drivetype %i: )ELSE (fsutil fsinfo drivetype %i:))

Edited by MrJinje
Link to comment
Share on other sites

That is correct, if anyone looks at my post, the fix was to run FSUTIL during the else statement. :whistle:

Well, if anyone looks at my post ;), the if exist is NOT needed at all, the usual form of IF/THEN/ELSE is:

IF <condition is true> THEN <do this> ELSE <do that>

something like:

IF <condition is true> THEN <do this> ELSE <do this>

seems to me a little pointless, and all in all replaceable by:

<do this>

:P

jaclaz

Edited by jaclaz
Link to comment
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...