I've been trying to put together a robocopy CMD script to be able to ask the user for a path (copy paste or just entering it manually) but I seem to be stumped...
Here's the current code I have;
#ECHO OFF
SETLOCAL
:Input
SET /P "source=Please enter or paste the location you want backed up and press ^<Enter^>."
IF "%source%"=="" GOTO Error
GOTO :DoTask
:Error
ECHO You did not specify a location to be backed up! Please try again. & goto :Input
::SET source="":: Obsolete for now, since user input is possible.
:DoTask
REM SET YEAR
set YEAR=%date:~6,4%
REM SET MONTH
set MONTH=%date:~3,2%
if %MONTH% LSS 10 set MONTH=%MONTH:~1,2%
if %MONTH% LSS 10 set MONTH=0%MONTH%
REM SET DAY
set DAY=%date:~0,2%
if %DAY% LSS 10 set DAY=%DAY:~1,2%
if %DAY% LSS 10 set DAY=0%DAY%
REM SET HOUR
set HOUR=%time:~0,2%
if %HOUR% LSS 10 set HOUR=%HOUR:~1,2%
if %HOUR% LSS 10 set HOUR=0%HOUR%
REM SET MINUTE
set MINUTE=%time:~3,2%
if %MINUTE% LSS 10 set MINUTE=%MINUTE:~1,2%
if %MINUTE% LSS 10 set MINUTE=0%MINUTE%
REM SET SECOND
set SECOND=%time:~6,2%
if %SECOND% LSS 10 set SECOND=%SECOND:~1,2%
if %SECOND% LSS 10 set SECOND=0%SECOND%
SET destination="Backups"\%date%
SET logdir="Backups\Logs"\%date%
SET log="Backups\Logs"\%date%\%HOUR%_%MINUTE%_%SECOND%.log
mkdir "%logdir%" 2>NUL
SET copyoptions=/COPYALL /E /ZB /SEC /MIR
:: /COPYALL :: COPY ALL file info.
:: /E :: Copy Subfolders, including Empty Subfolders.
:: /ZB :: Use restartable mode; if access denied use Backup mode.
:: /SEC :: Copy files with SECurity.
:: /MIR :: MIRror a directory tree.
SET logoptions=/R:0 /W:0 /LOG:%log% /TS /NP /V /ETA /TIMFIX /SECFIX /TEE
:: /R:n:: Number of Retries.
:: /W:n:: Wait time between retries.
:: /LOG:: Output log file.
:: /TS :: Include Source file Time Stamps in the output.
:: /NP :: No Progress - don’t display % copied.
:: /V :: Produce Verbose output log, showing skipped files.
:: /ETA:: Show Estimated Time of Arrival of copied files.
:: /TIMFIX :: FIX file TIMes on all files, even skipped files.
:: /SECFIX :: FIX file SECurity on all files, even skipped files.
:: /TEE:: Output to console window, as well as the log file.
:: /NFL:: No file logging.
:: /NDL:: No dir logging.
ROBOCOPY %source% %destination% %copyoptions% %logoptions%
:End
If this is too long, please feel free to edit this post and just link to it: http://pastebin.com/Np8wBF5b
So basically my issue with the above is as follows;
If I try to enter the path:
C:\Users\Public\Pictures\Sample Pictures
I get the error:
ERROR: Invalid Parameter #3 : "Backups\2013/10/22"
Source: C:\Users\Public\Pictures\Sample\
Destination: G:\Pictures
Notice how the destination in the first line of the error has forward slashes instead of backslashes? But what I find break it is the space between "Sample" and "Pictures".
For if I use a single word, it works perfectly, but brings me to my second problem;
Source: C:\Users\User\Pictures\BlackBerry\
Destination: G:\Backups\2013\10\22\
The source is correct, however in the destination folder it doesn't recreate the "Blackberry" folder, only the contents therein, and that is my issue...
For the user gets to choose multiple destinations to XCOPY, yet all that will happen is all the files get bunched together, with no folder structure etc...
My head is blown with trying to figure this all out, so I am REALLY hoping so kind soul will be able to help me out with this! :)
Enclose %source% in quotes, either there or where it is set.
Robocopy "%source%" ...
Edit: extra code after further the comments
Change this line as shown below: SET destination="Backups"\%date%
for %%a in ("%source%") do SET destination="Backups\%date%\%%~nxa"
The first four lines of this code will give you reliable YY DD MM YYYY HH Min Sec variables in XP Pro and higher. Run the batch file below to see the variables, and you can modify them too.
#echo off
for /f "tokens=2 delims==" %%a in ('wmic OS Get localdatetime /value') do set "dt=%%a"
set "YY=%dt:~2,2%" & set "YYYY=%dt:~0,4%" & set "MM=%dt:~4,2%" & set "DD=%dt:~6,2%"
set "HH=%dt:~8,2%" & set "Min=%dt:~10,2%" & set "Sec=%dt:~12,2%"
set "datestamp=%YYYY%%MM%%DD%" & set "timestamp=%HH%%Min%%Sec%"
set "fullstamp=%YYYY%-%MM%-%DD%_%HH%-%Min%-%Sec%"
echo datestamp: "%datestamp%"
echo timestamp: "%timestamp%"
echo fullstamp: "%fullstamp%"
pause
Related
I'm trying to build a script for one of our remote media players and am trying to get it to update once a file shows up in the dropbox. I need it to check the first 5 of the title against MM-DD and if they match then play the video in question. Playing the video is no issue, neither are the archives. My issue right now is that when I try to make a for loop for the files in the location I'm getting the syntax of the command is incorrect or "x" was not expected at this time. also, my date is being formatted like this: 05 -02, and I dont know why.
:::::::::::::::::::::::::::::::::::::::::::::: Get Date :::::::::::::::::::::::::::::::::::::::::::::::::::::::
:: Use WMIC to retrieve date and time
FOR /F "skip=1 tokens=1-6" %%G IN ('WMIC Path Win32_LocalTime Get Day^,Hour^,Minute^,Month^,Second^,Year /Format:table') DO (
IF "%%~L"=="" goto s_done
Set _mm=00%%J
Set _dd=00%%G
)
:s_done
:: Pad digits with leading zeros
Set _mm=%_mm:~-2%
Set _dd=%_dd:~-2%
::Finalize Date
Set date=%_mm%-%_dd%
echo %date%
::::::::::::::::::::::::::: Check the downloads folder for completed video files :::::::::::::::::::::::::::::::
:: Loop through all files
:loop
for %%a IN ("dir \Dropbox\Trailer") DO (
::IF the name is not blank, get the first 5 characters of the video name
set first5=%a:~0,5%
::Compare those characters to the date
IF "%first5%" == "%date%" (
taskkill /im wmplayer.exe /t
::::::::::::::: Archive all previous Videos :::::::::::::
for /r %%i in ("dir \Dropbox\Trailer") do (
xcopy /s (%%i) "dir \Archived_Shows\"
)
ping localhost
"C:\Program Files\Windows Media Player\wmplayer.exe" "C:\Dropbox\Trailer\%%a" /fullscreen
:::::::::::::::::::::::::::::::: Exit if new video is running ::::::::::::::::::::::::::::::::::::::
exit
)
)
goto :loop
I'm not sure exactly what your script is supposed to be doing but here is an example based on my understanding.
#Echo Off
CD "Dropbox\Trailer" 2>Nul || Exit /B
For /F "Tokens=1-2" %%A In (
'WMIC Path Win32_LocalTime Get Day^,Month^|FindStr [1-9]'
) Do Set /A _dd=10%%A,_MM=10%%B
Set "DString=%_MM:~-2%-%_dd:~-2%"
:Loop
If Not Exist "%DString%*" (
Timeout 300 /NoBreak
GoTo Loop
)
TaskKill /IM WMPlayer.exe /T 2>Nul
Timeout 10 /NoBreak >Nul
XCopy "." "%~dp0Archived_Shows" /S /D /I
For %%A In ("%DString%*") Do (
"%ProgramFiles%\Windows Media Player\wmplayer.exe" "%%A" /FullScreen
)
GoTo Loop
If no matching file is found it currently checks for new ones every 300 seconds, (5 minutes). If a matching file is found, the loop only resumes once you close WMPlayer. You can change that timespan on line 11 as per your preference.
You are setting the variable %date%, which is a system dynamic variable. Attempting to modify the contents is an unrecommended act, so instead, use another name.
Also, I have simplified the get-and-trim MM-DD part, and it works properly for me.
for /F "skip=1 tokens=1-6" %%G IN ('WMIC Path Win32_LocalTime Get Day^,Hour^,Minute^,Month^,Second^,Year /Format:table') DO (
IF "%%~L"=="" goto s_done
Set _mm=00%%~J
Set _dd=00%%~G
)
:s_done
::Finalize Date
Set titleDate=%_mm:~-2%-%_dd:~-2%
echo %titleDate%
pause
I'm trying to find an easy way of deploying only changed files to the webserver for deployment purpose. In times past I've used MSBuild, which could be told to only copy files that were newer than the ones on the target, but I'm in a hurry and don't want to try to figure out the newer version of MSBuild.
Can I use ROBOCOPY for this? There is a list of options for exclusion, which is:
/XC :: eXclude Changed files.
/XN :: eXclude Newer files.
/XO :: eXclude Older files.
/XX :: eXclude eXtra files and directories.
/XL :: eXclude Lonely files and directories.
What exactly does it mean to exclude? Exclude copying, or exclude overwriting? For example, if I wrote:
ROBOCOPY C:\SourceFolder\ABC.dll D:\DestinationFolder /XO
would this copy only newer files, not files of the same age?
Or is there a better tool to do this?
To answer all your questions:
Can I use ROBOCOPY for this?
Yes, RC should fit your requirements (simplicity, only copy what needed)
What exactly does it mean to exclude?
It will exclude copying - RC calls it skipping
Would the /XO option copy only newer files, not files of the same age?
Yes, RC will only copy newer files. Files of the same age will be skipped.
(the correct command would be robocopy C:\SourceFolder D:\DestinationFolder ABC.dll /XO)
Maybe in your case using the /MIR option could be useful. In general RC is rather targeted at directories and directory trees than single files.
You can use robocopy to copy files with an archive flag and reset the attribute. Use /M command line, this is my backup script with few extra tricks.
This script needs NirCmd tool to keep mouse moving so that my machine won't fall into sleep. Script is using a lockfile to tell when backup script is completed and mousemove.bat script is closed. You may leave this part out.
Another is 7-Zip tool for splitting virtualbox files smaller than 4GB files, my destination folder is still FAT32 so this is mandatory. I should use NTFS disk but haven't converted backup disks yet.
backup-robocopy.bat
#REM https://technet.microsoft.com/en-us/library/cc733145.aspx
#REM http://www.skonet.com/articles_archive/robocopy_job_template.aspx
set basedir=%~dp0
del /Q %basedir%backup-robocopy-log.txt
set dt=%date%_%time:~0,8%
echo "%dt% robocopy started" > %basedir%backup-robocopy-lock.txt
start "Keep system awake" /MIN /LOW cmd.exe /C %basedir%backup-robocopy-movemouse.bat
set dest=E:\backup
call :BACKUP "Program Files\MariaDB 5.5\data"
call :BACKUP "projects"
call :BACKUP "Users\Myname"
:SPLIT
#REM Split +4GB file to multiple files to support FAT32 destination disk,
#REM splitted files must be stored outside of the robocopy destination folder.
set srcfile=C:\Users\Myname\VirtualBox VMs\Ubuntu\Ubuntu.vdi
set dstfile=%dest%\Users\Myname\VirtualBox VMs\Ubuntu\Ubuntu.vdi
set dstfile2=%dest%\non-robocopy\Users\Myname\VirtualBox VMs\Ubuntu\Ubuntu.vdi
IF NOT EXIST "%dstfile%" (
IF NOT EXIST "%dstfile2%.7z.001" attrib +A "%srcfile%"
dir /b /aa "%srcfile%" && (
del /Q "%dstfile2%.7z.*"
c:\apps\commands\7za.exe -mx0 -v4000m u "%dstfile2%.7z" "%srcfile%"
attrib -A "%srcfile%"
#set dt=%date%_%time:~0,8%
#echo %dt% Splitted %srcfile% >> %basedir%backup-robocopy-log.txt
)
)
del /Q %basedir%backup-robocopy-lock.txt
GOTO :END
:BACKUP
TITLE Backup %~1
robocopy.exe "c:\%~1" "%dest%\%~1" /JOB:%basedir%backup-robocopy-job.rcj
GOTO :EOF
:END
#set dt=%date%_%time:~0,8%
#echo %dt% robocopy completed >> %basedir%backup-robocopy-log.txt
#echo %dt% robocopy completed
#pause
backup-robocopy-job.rcj
:: Robocopy Job Parameters
:: robocopy.exe "c:\projects" "E:\backup\projects" /JOB:backup-robocopy-job.rcj
:: Source Directory (this is given in command line)
::/SD:c:\examplefolder
:: Destination Directory (this is given in command line)
::/DD:E:\backup\examplefolder
:: Include files matching these names
/IF
*.*
/M :: copy only files with the Archive attribute and reset it.
/XJD :: eXclude Junction points for Directories.
:: Exclude Directories
/XD
C:\projects\bak
C:\projects\old
C:\project\tomcat\logs
C:\project\tomcat\work
C:\Users\Myname\.eclipse
C:\Users\Myname\.m2
C:\Users\Myname\.thumbnails
C:\Users\Myname\AppData
C:\Users\Myname\Favorites
C:\Users\Myname\Links
C:\Users\Myname\Saved Games
C:\Users\Myname\Searches
:: Exclude files matching these names
/XF
C:\Users\Myname\ntuser.dat
*.~bpl
:: Exclude files with any of the given Attributes set
:: S=System, H=Hidden
/XA:SH
:: Copy options
/S :: copy Subdirectories, but not empty ones.
/E :: copy subdirectories, including Empty ones.
/COPY:DAT :: what to COPY for files (default is /COPY:DAT).
/DCOPY:T :: COPY Directory Timestamps.
/PURGE :: delete dest files/dirs that no longer exist in source.
:: Retry Options
/R:0 :: number of Retries on failed copies: default 1 million.
/W:1 :: Wait time between retries: default is 30 seconds.
:: Logging Options (LOG+ append)
/NDL :: No Directory List - don't log directory names.
/NP :: No Progress - don't display percentage copied.
/TEE :: output to console window, as well as the log file.
/LOG+:c:\apps\commands\backup-robocopy-log.txt :: append to logfile
backup-robocopy-movemouse.bat
#echo off
#REM Move mouse to prevent maching from sleeping
#rem while running a backup script
echo Keep system awake while robocopy is running,
echo this script moves a mouse once in a while.
set basedir=%~dp0
set IDX=0
:LOOP
IF NOT EXIST "%basedir%backup-robocopy-lock.txt" GOTO :EOF
SET /A IDX=%IDX% + 1
IF "%IDX%"=="240" (
SET IDX=0
echo Move mouse to keep system awake
c:\apps\commands\nircmdc.exe sendmouse move 5 5
c:\apps\commands\nircmdc.exe sendmouse move -5 -5
)
c:\apps\commands\nircmdc.exe wait 1000
GOTO :LOOP
Looks like /e option is what you need, it'll skip same files/directories.
robocopy c:\data c:\backup /e
If you run the command twice, you'll see the second round is much faster since it skips a lot of things.
I know there are questions here like this before but in my case there are special conditions in specifying the files to be excluded in the "delete" operation.
Filename examples:
A_001.xml
A_002.xml
B_001.xml
B_002.xml
B_003.xml
C_009.xml
D_002.xml
The files above are in one directory and I need to delete all files but retain one copy of each file with the highest counter in filename which are A_002.xm, B_003.xml, C_009.xml and D_002.xml.
Is this possible? I'm new in batch file creation so please help me.. I already know how to delete files and even exclude a specific file extension but I don't know what to do in this scenario.
#ECHO OFF
SETLOCAL enabledelayedexpansion
::
:: establish target directory
:: initialise PREFIX to a name that's invalid in a filename
::
SET target=.
SET prefix=:
FOR /f "tokens=1*delims=_" %%i IN (
'dir /b/a-d/o-n "%target%\*_*.xml'
) DO (
IF !prefix!==%%i ECHO DEL "%target%\%%i_%%j"
SET prefix=%%i
)
This solution relies on the presence of "_" in the names of the *xml files in the target directory. I tested it on some dummy files in my batch-development directory, hence I used . for the current directory
The DIR command produces a list of the files in the target directory that match the pattern *_*.xml The/b switch means filename only, /a-d means no directory names, even if they match and /o-n means in the reverse order of name Therefore, the names will appear with the highest numeric value of the part after _ first.
The FOR reads this output and assigns the prefix to %%i and the remainder of the filename to %%j Since prefix is initialised to an invalid-in-filenames character, it cannot possibly match %%i for the first file encountered, so the DEL will not be executed. The last-encountered prefix will then be stored. Only if the next filename has a matching prefix will the DEL be executed
Note that I've inserted the ECHO keyword before the DEL. This is a safety device in case of error. The PROPOSED DEL operation will be reported to the screen, not EXECUTED. Once you're satisfied that the batch is correct, remove the ECHO and the delete operation will proceed.
Point to be observed:
Some editors are quite cavalier about stripping or retaining trailing
spaces. Normally, this is harmless but trailing spaces on a SET
command in batch can cause chaos.
#echo off
SETLOCAL ENABLEDELAYEDEXPANSION
set newprefix=_
for /F %%a in ('dir /on /b /a-d *.xml') do (
for /F "delims=_" %%i in ("%%a") do (
IF NOT *%%i*==*!newprefix!* (
for /F %%q in ('dir /on /b /a-d %%i*.xml') do set lastitem=%%q
attrib +r !lastitem! > NUL
del /s /q %%i*.xml 1>NUL 2>NUL
attrib -r !lastitem! > NUL
set newprefix=%%i
)
)
)
For each prefix of xml file, lists all the files with the prefix in question to get the last one in the list. Then mark the last one read only. Delete all with given pattern except read only. Reset read only flag and do over for next prefix.
I can't seem to understand how batch files add yyyy/mo/dd/hh/mm/ss to the beginning of filenames. (Using Windows 7) Accuracy to the second is important.
It doesn't actually have to be a batch file, it just has to be a small program which can be executed by Directory Monitor whenever I add files to a folder: http://brutaldev.com/page/Directory-Monitor.aspx
I only imagine that a batch file would be the simplest and most efficient approach, but any other suggestions are welcome.
I work with many sequentially numbered files with overlapping filenames and I need a quick way to rename them whenever I add them to a folder such that there will never be any file with the same name yet they will still remain in sequential order. This is how I thought of adding the current date and time to the beginning of the filename and why seconds are important, since I can easily add multiple sets to a folder in under a minute but certainly not under a second. It would be ideal if the batch file could ignore file extensions and simply add the current date/time to the beginning of any file added to the folder.
The first four lines of this code will give you reliable YY DD MM YYYY HH Min Sec variables in XP Pro and higher.
#echo off
for /f "tokens=2 delims==" %%a in ('wmic OS Get localdatetime /value') do set "dt=%%a"
set "YY=%dt:~2,2%" & set "YYYY=%dt:~0,4%" & set "MM=%dt:~4,2%" & set "DD=%dt:~6,2%"
set "HH=%dt:~8,2%" & set "Min=%dt:~10,2%" & set "Sec=%dt:~12,2%"
set "datestamp=%YYYY%%MM%%DD%" & set "timestamp=%HH%%Min%%Sec%" & set "fullstamp=%YYYY%-%MM%-%DD%_%HH%-%Min%-%Sec%"
echo datestamp: "%datestamp%"
echo timestamp: "%timestamp%"
echo fullstamp: "%fullstamp%"
:: this line will rename the files in the current folder which haven't already
:: been renamed by checking for the fullstamp format at the start of the line
:: but it will skip this batch file
for /f "delims=" %%a in ('dir /b /a-d ^|findstr /v "^[0-9]*-[0-9]*-[0-9]*_[0-9]*-[0-9]*-[0-9]*" ') do if /i not "%%a"=="%~nx0" ren "%%a" "%fullstamp% - %%a"
pause
#ECHO off
SETLOCAL
IF [%1] NEQ [] goto s_start
:: Author - Simon Sheppard, July 2003
:: Tested for Windows NT, 2K, XP
ECHO STAMPME.cmd
ECHO REName a file with the DATE/Time
ECHO.
ECHO SYNTAX
ECHO STAMPME TestFile.txt
ECHO.
ECHO STAMPME "Test File.txt"
ECHO.
ECHO STAMPME "c:\docs\Test File.txt"
ECHO.
ECHO In a batch file use CALL STAMPME ...
:: To change the filename format just change around the last line below
GOTO :eof
:s_start
SET _file=%~n1%
SET _pathname=%~f1%
SET _ext=%~x1%
::Get the date
:: note ISO 8601 date format would require 4 digit YYYY Year)
FOR /f "tokens=6-8 delims=/ " %%G IN ('NET TIME \\%computername%') DO (
SET _mm=%%G
SET _dd=%%H
SET _yy=%%I
)
:: Get the time
FOR /f "tokens=2-4 delims=:." %%G IN ('cmd /c "time<nul"') DO (
SET _hr=%%G
SET _min=%%H
SET _sec=%%I
GOTO :done
)
:done
ECHO Today is Year: [%_yy%] Month: [%_mm%] Day: [%_dd%]
ECHO The time is: [%_hr%]:[%_min%]:[%_sec%]
REN "%_pathname%" "%_hr%-%_min%-%_sec%#%_file%%_ext%"
This seems to work for me
I'd prefer solutions, that are not dependent to local settings (wmic gives always the same format):
#echo off
setlocal EnableDelayedExpansion
for %%a in (a.*) do (
for /f %%i in ( 'wmic os get localdatetime /value ^|find "Local"' ) do set %%i
set ldt=!LocalDateTime:~0,4!-!LocalDateTime:~4,2!-!LocalDateTime:~6,2!-!LocalDateTime:~8,2!-!LocalDateTime:~10,2!-!LocalDateTime:~12,2!-!LocalDateTime:~15,3!
echo seconds ### ren %%a !LocalDateTime:~0,14!%%a
echo milliseconds ### ren %%a !LocalDateTime:~0,18!%%a
echo with separator ### ren %%a !ldt!-%%a
)
I'm launching WinPE 2 from a bootable UFD, and I need to detect the drive letter in order to tell ImageX where to find the WIM. However, depending on the machine I'm imaging, there are different mounted drives.
I need a way to consistently mount the UFD at, say, P: or something. Is there a way to detect the letter of the drive from which the machine was booted, or another way to pass the location of my WIM file to a variable accessible from startnet.cmd?
Here's someone else with the same issue over at TechNet.
http://social.technet.microsoft.com/Forums/en-US/itprovistadeployment/thread/3e8bb8db-a1c6-40be-b4b0-58093f4833be?prof=required#
This VBScript will show a message for each removable drive (letter:description), could be easily modified to search for a particular drive and return the letter.
strComputer = "."
Set objWMIService = GetObject("winmgmts:\\" & strComputer & "\root\cimv2")
Set colDisks = objWMIService.ExecQuery("Select * from Win32_LogicalDisk where MediaType = 11")
For Each objDisk in colDisks
Wscript.Echo objDisk.DeviceID & objDisk.Description
Next
Don't know if that helps at all.
It's a less generic solution than the others mentioned here, but there appears to be a specific way to determine which underlying volume a "RAM-drive-booted" Windows PE OS was booted from. From the documentation on Windows PE in the Windows Automated Installation Kit:
If you are not booting Windows
Deployment Services, the best way to
determine where Windows PE booted from
is to first check for
PEBootRamdiskSourceDrive registry key.
If it is not present, scan the drives
of the correct PEBootType and look for
some kind of tag file that identifies
the boot drive.
(The registry value in question sits under HKLM\SYSTEM\CurrentControlSet\Control.)
Here's a non-optimal solution. In this case, the UFD has to have a specific name, which is passed to the script which searches every possible drive letter for a match. It's probably not practical to rely on the flash drives all having the same name.
Still hoping someone pops by with a better answer!
setlocal
:: Initial variables
set TMPFILE=%~dp0getdrive.tmp
set driveletters=abcdefghijklmnopqrstuvwxyz
set MatchLabel_res=
for /L %%g in (2,1,25) do call :MatchLabel %%g %*
if not "%MatchLabel_res%"=="" echo %MatchLabel_res%
goto :END
:: Function to match a label with a drive letter.
::
:: The first parameter is an integer from 1..26 that needs to be
:: converted in a letter. It is easier looping on a number
:: than looping on letters.
::
:: The second parameter is the volume name passed-on to the script
:MatchLabel
:: result already found, just do nothing
:: (necessary because there is no break for for loops)
if not "%MatchLabel_res%"=="" goto :eof
:: get the proper drive letter
call set dl=%%driveletters:~%1,1%%
:: strip-off the " in the volume name to be able to add them again further
set volname=%2
set volname=%volname:"=%
:: get the volume information on that disk
vol %dl%: > "%TMPFILE%" 2>&1
:: Drive/Volume does not exist, just quit
if not "%ERRORLEVEL%"=="0" goto :eof
set found=0
for /F "usebackq tokens=3 delims=:" %%g in (`find /C /I "%volname%" "%TMPFILE%"`) do set found=%%g
:: trick to stip any whitespaces
set /A found=%found% + 0
if not "%found%"=="0" set MatchLabel_res=%dl%:
goto :eof
:END
if exist "%TMPFILE%" del "%TMPFILE%"
endlocal
To elaborate reuben's answer in more detail, here is my batch file:
wpeutil UpdateBootInfo
for /f "usebackq skip=1 tokens=3 delims= " %%l in ( `reg query HKLM\System\CurrentControlSet\Control /v PEBootRAMDiskSourceDrive` ) do set "PendrivePath=%%l"
set "PendriveLetter=%PendrivePath:~0,1%"
echo The boot pendrive's drive letter is %PendriveLetter%