Finding which drives are connected to computer - batch-file

I have a small side project I've been working on and i want to add an option to scan the computer and find which drives are connected and what they are(USB, Hard drive, Disc drive, SSD, etc.)
this is what i have so far.
echo off
:start
color 0a
cls
title Search
echo To search enter the drive and term you wish to search below.
echo ---------------------------------------------------------------------------
set inputdrive=
set /p inputdrive=Drive:
set input=
set /p input=Search:
dir %inputdrive%:\%input% /s /b
pause
echo search again?
set inputsearch=
set /p inputsearch=(Y/N)
if %inputsearch%==Y goto start
if %inputsearch%==N exit
I plan on adding an option to scan for connected drives at the beginning of the script.

You can use WMIC to get the info without the need for administrator rights.
Here is code that gives a nice listing of all available drives, including removable media drives that do not have any media installed:
#echo off
setlocal
set ^"driveTypes=^
0Unknown :^
1No Root Directory:^
2Removable Media :^
3Local Disk :^
4Network Drive :^
5CD/DVD :^
6RAM Disk :^"
echo Available Drives:
echo(
echo ID Drive Type Volume Name
echo -- ----------------- -----------
for /f "skip=1 tokens=1-3" %%A in (
'"wmic logicalDisk get DeviceID, DriveType, VolumeName"'
) do if "%%B" neq "" (
setlocal enableDelayedExpansion
for /f "delims=:" %%D in ("!driveTypes:*%%B=!") do (
endlocal
echo %%A %%D %%C
)
)
Just a bit more code will restrict the list to only drives that are available with media:
#echo off
setlocal
set ^"driveTypes=^
0Unknown :^
1No Root Directory:^
2Removable Media :^
3Local Disk :^
4Network Drive :^
5CD/DVD :^
6RAM Disk :^"
echo Available Drives:
echo(
echo ID Drive Type Volume Name
echo -- ----------------- -----------
for /f "skip=1 tokens=1-3" %%A in (
'"wmic logicalDisk get DeviceID, DriveType, VolumeName"'
) do if "%%B" neq "" dir %%A >nul 2>nul && (
setlocal enableDelayedExpansion
for /f "delims=:" %%D in ("!driveTypes:*%%B=!") do (
endlocal
echo %%A %%D %%C
)
)

fsutil fsinfo drives
fsutil fsinfo drivetype c:
But you need to have administrator rights to use it

Related

Batch Scripting Backing up files in USB

Iv got my code to show a list of USb devices connected to my laptop and i can select the USB as well but when i try to back up a folder into the USB what i get instead is a folder named f in the folder i was trying to save. This is the code i have for selectong a USB device
for /f "delims=" %%a in ('wmic logicaldisk where drivetype^=2 get deviceid ^| find ":"') do set "$List=!$List! %%a"
:USB
echo Avaiable Drive ==^> !$List!
set /p "$Drive=Enter the letter of the Backup drive : "
echo !$List! | find /i "%$Drive::=%:" && Echo drive OK || Echo drive do not exist && goto:USB
set backupcmd=robocopy
and this is the code that backup the folder
%backupcmd% "%cd%" "%$Drive%"
Give this one a go:
#echo off
setlocal enabledelayedexpansion
set num=0
for /f %%a in ('wmic logicaldisk where drivetype^=2 get drivetype^, deviceid ^| find ":"') do (
set /a num+=1
set cnt=!cnt!!num!
echo (!num!^) %%a
set "d!num!=%%a"
)
choice /c !cnt! /M "select a number to choose a drive: "
echo You've chosen drive !d%errorlevel%! you can do everything with it from here..
You will notice that I set delayedexpansion here because of the setting and using of variables inside of the parenthesised code block.
Choice is a good option here as it does not allow typing the wrong values.

Batch conditional FOR loop nested IF

I'm trying to write a script that parses a text file to identify removable drives by Label. The goal is to create a copy script based on the found drives.
I'm able to parse the file but I can't seem to get the second pair of IF conditions to be true.
I may be misunderstanding how variables are evaluated in each loop of the FOR.
Thoughts appreciated.
EDIT: Expanding on the original request for clarity(it was late when I asked) The expanded goal is to identify one or many target drives to copy data from an SD card. Since the drives letter allocations vary from PC to PC and depend on which is plugged in first my idea was to use the labels as somewhat identifiable values and create a simple copy string along the lines of
XCOPY SourceDrive\*.jpg DestinationDrive1\<GetDate>\
XCOPY SourceDrive\*.jpg DestinationDrive2\<GetDate>\
End Edit
#echo off
cls
title "Detecting device drive letters..."
setlocal enabledelayedexpansion
set DestinationDrive1Found=
set DestinationDrive2Found=
set SourceDriveFound=
set SourceDrive=
set DestinationDrive1=
set DestinationDrive2=
echo Detecting device drive letters...
echo list volume > %systemdrive%\ListDrives.tmp
diskpart /s %systemdrive%\ListDrives.tmp > %systemdrive%\CurrentDrives.tmp
echo Checking drive IDs
FOR /F "skip=7 tokens=2-4" %%a IN (%systemdrive%\CurrentDrives.tmp) DO (
set "matchvar=%%c"
set "comparevar=!matchvar:DRIVE=!"
IF /I NOT "!comparevar!" == "%%c" IF "!DestinationDrive1Found!" NEQ 1 (
echo Drive %%b was found to be %%c and will be DESTINATION1
set DestinationDrive1Found=1
set DestinationDrive1=%%b )
IF /I NOT "!comparevar!" == "%%c" IF "!DestinationDrive1Found!" EQU 1 ( echo Drive %%b was found to be %%c and will be DESTINATION2
set DestinationDrive2Found=1
set DestinationDrive2=%%b )
)
File I'm parsing
Microsoft DiskPart version 10.0.10586
Copyright (C) 1999-2013 Microsoft Corporation.
On computer: NEWGLOOMWIN10
Volume ### Ltr Label Fs Type Size Status Info
---------- --- ----------- ----- ---------- ------- --------- --------
Volume 0 D DVD-ROM 0 B No Media
Volume 1 E Macintosh H HFS Partition 231 GB Healthy
Volume 2 C BOOTCAMP NTFS Partition 721 GB Healthy System
Volume 3 F TEAMXCAMRAX FAT Removable 1937 MB Healthy
Volume 4 G TEAMXDRIVEX NTFS Partition 465 GB Healthy
Volume 5 H TEAMYDRIVEY NTFS Partition 931 GB Healthy
Thanks to all who responded. Had #Mofi provided an answer I would have marked that response as the answer. In the end the removal of a four quote marks and the addition of an ELSE got me the answer I was looking for.
The script below gives me exactly what I'm after.
#echo off
cls
title "Detecting device drive letters..."
setlocal enabledelayedexpansion
set DestinationDrive1Found=
set DestinationDrive2Found=
set SourceDriveFound=
set SourceDrive=
set DestinationDrive1=
set DestinationDrive2=
echo Detecting device drive letters...
echo list volume > %systemdrive%\ListDrives.tmp
diskpart /s %systemdrive%\ListDrives.tmp > %systemdrive%\CurrentDrives.tmp
echo Checking drive IDs
FOR /F "skip=7 tokens=2-4" %%a IN (%systemdrive%\CurrentDrives.tmp) DO (
set "matchvar=%%c"
set "comparevar=!matchvar:CAMRA=!"
IF /I NOT "!comparevar!" == "%%c" (#echo Drive %%b was found to be %%c and will be SOURCE
set SourceDriveFound=1
set SourceDrive=%%b)
)
echo Checking drive IDs
FOR /F "skip=7 tokens=2-4" %%a IN (%systemdrive%\CurrentDrives.tmp) DO (
set "matchvar=%%c"
set "comparevar=!matchvar:DRIVE=!"
IF /I NOT "!comparevar!" == "%%c" IF !DestinationDrive1Found! NEQ 1 (
echo Drive %%b was found to be %%c and will be DESTINATION1
set DestinationDrive1Found=1
set DestinationDrive1=%%b
) ELSE (
IF /I NOT "!comparevar!" == "%%c" IF !DestinationDrive1Found! EQU 1 ( echo Drive %%b was found to be %%c and will be DESTINATION2
set DestinationDrive2Found=1
set DestinationDrive2=%%b ))
)
If you just want to set some variables to the drives allocated to any removable drive with the string DRIVE in it's 'label' then the following may provide you with an alternative not requiring elevation.
#Echo Off
For /F "UseBackQ Skip=1 Delims=" %%A In (`WMIC LogicalDisk Where^
"DriveType='2' And VolumeName Like '%%DRIVE%%'" Get Name`
) Do For /F %%B In ("%%A") Do Set/A "i+=1"&Call Set "_drv%%i%%=%%B"
Set _drv
Timeout -1
[Edits] - an example correctly stipulating a fixed drive
#Echo Off
For /F "UseBackQ Skip=1 Delims=" %%A In (`WMIC LogicalDisk Where^
"DriveType='3' And VolumeName Like '%%DRIVE%%'" Get Name`
) Do For /F %%B In ("%%A") Do Set/A "i+=1"&Call Set "_drv%%i%%=%%B"
Set _drv
Timeout -1
An example without stipulating the type of drive, (recommended based on comments).
#Echo Off
For /F "UseBackQ Skip=1 Delims=" %%A In (
`WMIC LogicalDisk Where "VolumeName Like '%%DRIVE%%'" Get Name`
) Do For /F %%B In ("%%A") Do Set/A "i+=1"&Call Set "_drv%%i%%=%%B"
Set _drv
Timeout -1

how to end loop in batch file

I have batch script that does check:
create log file with Date and Time format
oracle listener check
oracle db status check
disk space check
#echo off
set ORACLE_SID=equis01
REM set result_file = %Date:~4,2%.%Date:~7,2%.%Date:~10,4%
set HH=%TIME: =0%
set HH=%HH:~0,2%
set MI=%TIME:~3,2%
set SS=%TIME:~6,2%
REM for /F "tokens=2-4 delims=/ " %%i in ('date /t') do set result_file="%%j"."%%i"."%%k"_%HH%.%MI%.%SS%_"DBXXX".log
if exist %result_file% (
del %result_file%
)
>%result_file% (
echo Oracle Listener Status:
echo ========================================
echo.
lsnrctl status
echo.
echo.
echo.
echo Oracle Database Status:
echo ========================================
echo.
(
echo #monitoring.sql
) | sqlplus /
)
echo.
echo.
echo.
echo Disk Space:
echo ========================================
for /f "skip=1 usebackq delims==" %%i in (`wmic logicaldisk where "mediatype='12'" get caption`) do (
call :doit %%i >> "%result_file%"
)
goto :eof
:doit
set driveletter=%1
if {%driveletter%}=={} goto :EOF
for /f "usebackq delims== tokens=2" %%x in (`wmic logicaldisk where "DeviceID='%driveletter%'" get FreeSpace /format:value`) do set FreeSpace=%%x
for /f "usebackq delims== tokens=2" %%x in (`wmic logicaldisk where "DeviceID='%driveletter%'" get Size /format:value`) do set Size=%%x
set FreeMB=%FreeSpace:~0,-10%
set SizeMB=%Size:~0,-10%
set /a Percentage=100 * FreeMB / SizeMB
echo %driveletter% %FreeMB% GB out of %SizeMB% GB Total - %Percentage%%% free
rem echo exit
for %%a in (*.log*) do "C:\Program Files\7-Zip\7z.exe" a -tzip "%result_file%" "%%a"
Description of problem:
after running the code - it must archive the log file.
but the message says:
C: 25 GB out of 42 GB Total - 59% free
System ERROR:
The process cannot access the file because it is being used by another process.
ERROR: 11.10.2016_17.47.31_DBXXX.log
Can not open the file as archive
D: 88 GB out of 107 GB Total - 82% free
System ERROR:
The process cannot access the file because it is being used by another process.
ERROR: 11.10.2016_17.47.31_DBXXX.log
Can not open the file as archive
E: 415 GB out of 436 GB Total - 95% free
System ERROR:
The process cannot access the file because it is being used by another process.
ERROR: 11.10.2016_17.47.31_DBXXX.log
Can not open the file as archive
How to solve the problem?
For the WMICpart you can simplify your code like this :
#echo off
setlocal enabledelayedexpansion
for /f %%i in ('wmic logicaldisk where "mediatype=12" get caption ^| findstr ":"') do (
for /f %%x in ('wmic logicaldisk where "DeviceID='%%i'" get Size^,FreeSpace ^/format:value ^| findstr [0-9]') do set %%x
call:next %%i !Freespace:~0,-10! !Size:~0,-10!
)
exit/b
:next
set /a percentage=(%2 * 100) / %3
echo %1 - %2 Gb of %3 Gb [!Percentage!^% Free]
Then just add the other element, It will be easier to debug.

diskpart select by disk label

I need to select a disk in WinPE using DISKPART by label. I found this but I think it's outdated:
#Echo %dbg%Off
::
:: Find External drive and set it active
:: Lists Disk Information using Diskpart
::
SetLocal EnableDelayedExpansion
:: Type the frst 11 characters of the label of the drive here.
Set _FindLabel=Recovery
Call :_InitVars "%_FindLabel%"
"%SystemRoot%\system32\FSUTIL.exe">Nul 2>&1||Goto _NotAdmin
Echo.
Echo.Please wait, gathering info on the installed drives
Echo.
>"%_Dscr1%" Echo.List disk
For /F "Tokens=2" %%I In ('Diskpart /S "%_Dscr1%"^|Findstr /I /R /C:"Disk [0-9]"') Do (
(Echo.Select Disk %%I
Echo.Detail Disk)>>"%_OFile1%"
)
For /F "Tokens=1,2,3*" %%I In ('Diskpart /S "%_OFile1%"^|Findstr /I /R /C:"Disk [0-9]" /C:"Volume [0-9]"') Do (
If /I %%I==Disk (
Set _Tmp=%%J:
) Else (
Set _Label=%%L
Set _Label=!_Label:~,11!
>>"%_OFile2%" Echo.!_Tmp!%%J:!_Label!
))
If Exist "%_OFile1%" Del "%_OFile1%"
For /F "Usebackq Tokens=1-3 Delims=:" %%I In ("%_OFile2%") Do (
Set _Label=%%K
Set _Label=!_Label:~,11!
If "!_Label!"=="%_FindLabel%" (Set _Disk=%%I) & (Set _Label=%%K) & Goto _FDisk
>>"%_OFile1%" Echo.Volume %%J on Disk %%I has the Label %%K
)
Echo.
Echo.There is no drive connected that has the label of "%_FindLabel%"
Echo.These are the currently connected volumes:
Type "%_OFile1%"
:_Exit
Echo.
Pause
Goto _Cleanup
:_FDisk
(Echo.Select disk %_Disk%
Echo.Select Partition 1
Echo.Active)>"%_Dscr1%"
Diskpart /S "%_Dscr1%"
:_Cleanup
For %%I In ("%_Dscr1%" "%_OFile1%" "%_OFile2%") Do Del %%I>Nul 2>&1
Goto :EOF
::::::::::::::::::::::::::::::::::::::::::::::::::::::
:: Subroutines
::::::::::::::::::::::::::::::::::::::::::::::::::::::
:_NotAdmin
Ver|Findstr /I /C:"Version 5">Nul
If %Errorlevel%==0 (Set _Tmp1=5) & (Set _Tmp=a Computer Administrator account)
Ver|Findstr /I /C:"Version 6">Nul
If %Errorlevel%==0 (Set _Tmp1=6) & (Set _Tmp=an Elevated Command Prompt)
Echo.
Echo.This program must be run from %_Tmp%.
If %_Tmp1%==6 Echo.Please Right click the file, then click Run as Administrator
Echo.Exiting program
Goto _Exit
:_InitVars
For /F "Tokens=1 Delims==" %%I In ('Set _ 2^>Nul') Do Set %%I=
Set _Dscr1=%temp%\dpscr1.txt
Set _OFile1=%temp%\_OFile1.txt
Set _OFile2=%temp%\_OFile2.txt
Set _FindLabel=%~1
Set _FindLabel=%_FindLabel:~,20%
Call :_Cleanup
When I run it, it returns:
Please wait, gathering info on the installed drives
There is no drive connected that has the label of "Recovery"
These are the currently connected volumes:
Volume 1 on Disk 0 has the Label NTFS Part
Volume 2 on Disk 0 has the Label NTFS Part
Volume 3 on Disk 1 has the Label WINPE
It's showing the Fs (filesystem), not the label.
Diskpart output (list volume)
Volume ### Ltr Label Fs Type Size Status Info
---------- --- ----------- ----- ---------- ------- --------- --------
Volume 0 D USBBOOT UDF DVD-ROM 329 MB Healthy
Volume 1 Windows NTFS Partition 40 GB Healthy
Volume 2 Recovery NTFS Partition 19 GB Healthy
Volume 3 Z WINPE FAT32 Removable 7632 MB Healthy
Not sure how to modify this to get it to select the Label column.
As there is missing valid drive letter in some lines of the Diskpart output (list volume, column ltr), then tokens in line #19
For /F "Tokens=1,2,3*" %%I In ('Diskpart /S "%_OFile1%"^|Findstr /I /R /C:"Disk [0-9]" /C:"Volume [0-9]"') Do (
display as follows (and we have our culprit now):
%%I %%J %%K %%L
Volume 0 D USBBOOT UDF DVD-ROM 329 MB ...
Volume 1 Windows NTFS Partition 40 GB Healthy
Volume 2 Recovery NTFS Partition 19 GB Healthy
Volume 3 Z WINPE FAT32 Removable 7632 MB ...
Therefore you could use next snippet code (instead of lines 19..26) in your script:
For /F "Tokens=1*" %%I In ('Diskpart /S "%_OFile1%"^|Findstr /I /R /C:"Disk [0-9]" /C:"Volume [0-9]"') Do (
If /I %%I==Disk (
Set _Tmp=%%J:
) Else (
Set _Label=%%J
Set _Label=!_Label:~10,11!
>>"%_OFile2%" Echo.!_Tmp!%%J:!_Label!
))
Care this change interferes _Tmp variable!

Detect USB and copy *.* to USB drive using batch script

I am trying to write a batch script to detect a USB drive and, if it is plugged in,
for example copy c:\test\big.txt to the USB drive, and looping to detect another flash drive.
#echo off
for %%d in (D: E: F: G: H: I: etc...) do (
if exist %%d\nul (
echo USB at drive %%d connected
)
)
EDIT: Below is the right way to do that:
#echo off
for /F "tokens=1*" %%a in ('fsutil fsinfo drives') do (
for %%c in (%%b) do (
for /F "tokens=3" %%d in ('fsutil fsinfo drivetype %%c') do (
if %%d equ Removable (
echo Drive %%c is Removable (USB^)
)
)
)
)
I know this is old but....
#echo off
for /F "usebackq tokens=1,2,3,4 " %%i in (`wmic logicaldisk get caption^,description^,drivetype 2^>NUL`) do (
if %%l equ 2 (
copy c:\test\big.txt %%i
)
)
This is assuming of course both drives are inserted.
The above code had a flaw which has been attended to in the following code
The code works in XP and gives you the USB drive letters, if no usb device
is connected , it tells you so !
:: SUCCESS # 2:39 AM ON 12 OCT 2013 !!!
:: IMPROVED BY BOBBY GOREJA
#echo off
set usbdrv=
set usb=No
:: Above two lines on 12 Oct 2013
fsutil fsinfo drives >de
type de | find "Drives:" /v >dlist
for /F "tokens=1" %%c in ('type dlist') do (
for /F "tokens=3" %%d in ('fsutil fsinfo drivetype %%c') do (
rem echo Token is %%d
if %%d equ Removable (
echo Drive %%c is Removable (USB^)
set usbletter=%%c
set usb=Yes
echo USB drive letter is %usbletter%
rem set usbdrv = %%c <<< this does NOT work!
rem echo USB1 drive letter is %usbdrv%
)
)
)
del de
del dlist
echo REPEAT:Device at %usbletter%
if "%usb%"=="No" echo No USB Device Connected .
set usb=
#Aacini I don't have a good setup to this case today, so I instead tried finding my USB webcam. I used devmgmt.msc and devcon listclasses to figure out the membership a connected USB camera would have. After a few tests, I arrived at devcon find =Image USB\*. I figured it would be simple enough to do the same for a USB mass storage device, so I tried devcon find =Volume (per listclasses). Unfortunately, this dumps out a GUID which you would then have to map to a drive letter. A cursory glance at this overflow suggests you can do so from the registry using reg query, but it seems at this point that fsutil would be simplest for your case.

Resources