avery_larry
I did this:
Code: Select all
setlocal enabledelayedexpansion
for %%a in (f g h i j k l m n o p q r s t u v w x y z) do (
if not exist %%a:\ (
if 1!tmpsource!==1 (
set tmpsource=%%a:
) else (
if 1!tmpdest!==1 set tmpdest=%%a:
)
)
)
Now obviously I can get rid of the "l" in the for list but I'm trying for something that can be run on different machines where I don't know the drive letters . . .
----------------------------
#2 27 Jun 2008 11:18
Simon Sheppard
If you do
Code: Select all
NET USE * \\server\your_share
A better option is
Code: Select all
Pushd \\server\your_share
When you are finished with it, a simple POPD will remove the temporary map and put your current directory back where it started.
----------------------------
#3 01 Jul 2008 17:52
avery_larry
Well, nice idea--but I'm not using net use.
First I'm using vmware server and mounting a virtual disk. Then I'm using the subst command for the 2nd option. I have other scripts that would use it for netware drive mapping.
I suppose I could use a net use * command and figure out what drive it uses, then delete the mapping and use the drive. Seems a bit excessive, though. There should be some way to list local drives . . .
Ted
----------------------------
#4 03 Jul 2008 12:13
bluesxman
Oh but there is a way!
Code: Select all
FSUTIL FSINFO DRIVES
:EDIT:
Alternatively, you could probably try accessing each drive letter in turn, looking for the error "The system cannot find the drive specified." as that should indicate an available drive letter. An empty CD/DVD drive should give "The device is not ready."; any other in-use letter should return no error at all.
Last edited by bluesxman (03 Jul 2008 12:23)
cmd | *sh | ruby | chef
----------------------------
#5 03 Jul 2008 21:12
avery_larry
Nice. So it could look like this:
Code: Select all
setlocal enabledelayedexpansion
FSUTIL FSINFO DRIVES > }{.tmp
for %%a in (f g h i j k l m n o p q r s t u v w x y z) do (
find /i "%%a:\" }{.tmp
if errorlevel 1 (
if 1!tmpsource!==1 (
set tmpsource=%%a
) else (
if 1!tmpdest!==1 set tmpdest=%%a
)
)
)
Thanks!
Last edited by avery_larry (21 Jul 2008 19:14)
----------------------------
#6 24 Jul 2008 21:38
avery_larry
I've come up with this:
Code: Select all
@setlocal enabledelayedexpansion
@echo off
::This file will echo a free drive letter. It will also set a variable
::to that drive letter if it is passed the variable name like this:
::freedrv variablename
for /f "tokens=*" %%a in ('FSUTIL FSINFO DRIVES') do set freedrv_drives=%%a
for %%a in (z y x w v u t s r q p o n m l k j i h g f) do (
echo %freedrv_drives%|find /i "%%a:\" >nul 2>nul
if errorlevel 1 set freedrv_drive=%%a
)
:end
endlocal && echo %freedrv_drive%&&if not 1%1==1 set %1=%freedrv_drive%
:eof
Code: Select all
if not 1%1==1 (
echo %freedrv_drives%|find /i "%1:\" >nul 2>nul
if errorlevel 1 exit&&set freedrv_drive=%1
goto eof
)
cmd /q /d /c "for %%a in (1 2 3) do call %0 %%a"
:eof
----------------------------
#7 24 Jul 2008 22:02
avery_larry
Actually, this doesn't work:
Code: Select all
for /f "tokens=*" %%a in ('FSUTIL FSINFO DRIVES') do set freedrv_drives=%%a
Any idea why? Seems like the output maybe uses LF?
----------------------------
#8 25 Jul 2008 09:28
bluesxman
I refer you back to the post I referred you to in my original post (does that make sense?) ... Look here.
cmd | *sh | ruby | chef
----------------------------
#9 25 Jul 2008 18:38
Simon Sheppard
An alternative method to get drive information is PSINFO -d but that is noticeably slower than FSUTIL
----------------------------
#10 29 Jul 2008 17:18
avery_larry
Sorry -- didn't read very well. Thank you all very much.bluesxman wrote:
I refer you back to the post I referred you to in my original post (does that make sense?) ... Look here.
----------------------------
#11 29 Jul 2008 17:33
avery_larry
In the code from the other thread:
Code: Select all
@echo off
setlocal enabledelayedexpansion
set drives=
for /f "usebackq tokens=1*" %%a in (`FSUTIL FSINFO DRIVES ^| find ":"`) do (
if /i "%%a" NEQ "Drives:" (
set "drives=!drives! %%a"
echo:%%a
) ELSE (
set "drives=!drives! %%b"
echo:%%b
)
)
set drives=%drives:~1%
echo:"%drives%"
) ELSE (
set "drives=!drives! %%b"
echo:%%b
Did I miss something or is it just extra code? wink
----------------------------
#12 29 Jul 2008 18:25
avery_larry
After much testing, I've come up with the following:
Code: Select all
@setlocal enabledelayedexpansion
@echo off
::This file will echo a free drive letter. It will also set a variable
::to that drive letter if it is passed the variable name like this:
::freedrv variablename
set freedrv_drives=
for /f "usebackq tokens=1*" %%a in (`FSUTIL FSINFO DRIVES ^| find ":"`) do (
if /i "%%a" NEQ "Drives:" set freedrv_drives=!freedrv_drives! %%a
)
call :process
goto end
:process
for %%a in (z y x w v u t s r q p o n m l k j i h g f) do (
echo %freedrv_drives% | find /i "%%a:\" >nul 2>nul
if errorlevel 1 (
set freedrv_drive=%%a
exit /b
)
)
goto eof
:end
endlocal && echo %freedrv_drive%&&if not 1%1==1 set %1=%freedrv_drive%
:eof
----------------------------
#13 30 Jul 2008 10:14
bluesxman
Au contraire, the "ELSE" command will execute for the very first drive in the list. Trust me, I'm a professional.avery_larry wrote:
I don't see the else statement ever running:
OK I'll explain.
If you run the fsutil fsinfo drives | find ":" command at the CMD prompt you'll get a response in this format:
Code: Select all
Drives: C:\
D:\
E:\
F:\
G:\
H:\
I:\
K:\
X:\
Y:\
It's not going to cause a big problem with your code, because the first in-use letter is very likely to be "A" or "C", and you aren't entertaining the possibility of a free letter below "F".
cmd | *sh | ruby | chef
----------------------------
#14 30 Jul 2008 22:54
avery_larry
On the computer I was using (Win 2003 server), the output is as follows:bluesxman wrote:
If you run the fsutil fsinfo drives | find ":" command at the CMD prompt you'll get a response in this format:
Drives: C:\
D:\
E:\
F:\
G:\
H:\
I:\
K:\
X:\
Y:\
Code: Select all
Drives:
C:\
D:\
E:\
F:\
G:\
H:\
I:\
K:\
X:\
Y:\
----------------------------
#15 31 Jul 2008 10:00
bluesxman
I really should check on different Windows versions before getting on my high horse smile
cmd | *sh | ruby | chef
----------------------------
#16 05 Sep 2008 20:11
avery_larry
This may be a bit more elegant: (tested only on WinXP)
Code: Select all
@setlocal enabledelayedexpansion
@echo off
::This file will echo a free drive letter. It will also set a variable
::to that drive letter if it is passed the variable name like this:
::freedrv variablename
for /f "usebackq tokens=1*" %%a in (`FSUTIL FSINFO DRIVES ^| find ":"`) do (
if /i "%%a" NEQ "Drives:" (
set freedrv_drives=!freedrv_drives! %%a
) else (
set freedrv_drives=%%b
)
)
for %%a in (z y x w v u t s r q p o n m l k j i h g f e d c b a) do (
echo %freedrv_drives% | find /i "%%a:\" >nul 2>nul
if errorlevel 1 (
endlocal
echo %%a
if not 1%1==1 set %1=%%a
exit /b
)
)
----------------------------
#17 19 Oct 2012 22:27
QuickLearnin00b
How about just:
Code: Select all
for %%a in (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 %%a:\ (echo %%a drive exists) ELSE (set MountedDriveLetter=%%a && GOTO break)
)
:break
#18 22 Oct 2012 14:43
bluesxman
Because that will erroneously report a CD-ROM without a CD loaded as being available.
cmd | *sh | ruby | chef
----------------------------
#19 22 Oct 2012 18:49
dbenham
I believe WMIC is faster, and it does not require admin privs.
Code: Select all
@echo off
setlocal enableDelayedExpansion
set "drives=ABCDEFGHIJKLMNOPQRSTUVWXYZ"
for /f "delims=:" %%A in ('wmic logicaldisk get caption') do set "drives=!drives:%%A=!"
echo all unused letters = %drives%
echo next unused letter = %drives:~0,1%
echo last unused letter = %drives:~-1%
Dave Benham
----------------------------
#20 05 Sep 2013 20:06
npocmaka
one more way (requires admin privileges ):
fltMc volumes
edit:
shows only virtual cdroms. So cannot be used to find free letter.
Last edited by npocmaka (05 Sep 2013 21:14)
----------------------------
#21 06 Sep 2013 06:23
carlos
Hello. I remember write that function:
Code: Select all
:volume
For %%# in (B Z Y X W V U T S R Q
P O N M L K J I H G F E D C A
) Do (Vol %%#: || Net Use %%#:) >Nul 2>&1 || (
Set "volume=%%#:" &Goto :Eof)
Echo Error. None volume available.
----------------------------
#22 21 May 2017 12:00
Andrew.au
Using internal commands only, get the next available drive, skipping optical drives:
Code: Select all
vol Z: Y: X: W: V: U: T: S: R: Q: P: O: N: M: L: K: J: I: H: G: F: E: D: C: 1>nul 2>%temp%\volErr.txt
for /F "tokens=5 delims=. " %%A in (%temp%\volErr.txt) do @set NAD=%%A
@echo.
@echo Next available drive is; %NAD%