When the script gets to the IF statement, it just ends. It doesn't go to the next line which is pause for debugging.
set yymm=%DATE:~12,2%%DATE:~4,2%
set DD=%DATE:~7,2%
robocopy "\\client system\Users\login name\Videos" "F:\Temporary\Videos\Process\New Batch\%yymm%%dd%\Netbook\Videos" /mir
set /p %user%=Did Netbook Videos complete? (y/n):
IF %user%=="y" (del "\\client system\Users\login name\Videos\"*.* /s/q) ELSE (echo Skipping)
I know that there is a /move switch for robocopy command. But it tells me that it doesn't have access to the destination folder. The batch program runs with administrative access and it is running in the profile that created the folder. So I wrote a workaround.
Why is this happening?
I recommend first to read following answers:
Debugging a batch file explains how to debug a batch file because of cmd.exe always outputs an error message on exiting execution of a batch file because of a syntax error as caused by your wrong code.
Why is no string output with 'echo %var%' after using 'set var = text' on command line?
The answer on this question explains how to define and use environment variables correct on Windows.
How to stop Windows command interpreter from quitting batch file execution on an incorrect user input?
The answer on this question explains in detail with examples the usage of set /P and choice whereby the latter is better for all user prompts on which the user must take one of the options the batch file offers during execution.
How does the Windows Command Interpreter (CMD.EXE) parse scripts?
The question is really self-explaining.
The batch file below assumes that the string substitutions done with value of dynamic environment variable DATE works with used user account because of date format depends on which region/country/locale is set for used user account.
set "yymm=%DATE:~12,2%%DATE:~4,2%"
set "DD=%DATE:~7,2%"
%SystemRoot%\System32\robocopy.exe "\\client system\Users\login name\Videos" "F:\Temporary\Videos\Process\New Batch\%yymm%%dd%\Netbook\Videos" /mir
%SystemRoot%\System32\choice.exe /N /M "Did Netbook Videos complete? (y/n): "
if errorlevel 2 (echo Skipping) else del /S /Q "\\client system\Users\login name\Videos\*"
I suggest also reading How to delete files/subfolders in a specific directory at command prompt in Windows? The command DEL as used here does not delete all files and leaves behind subdirectories which are most likely empty after deleting most or by chance all video files. But it would be good to avoid deletion of hidden system file desktop.ini in videos directory of a user account which is usually referenced with %USERPROFILE%\Videos.
For understanding the used commands and how they work, open a command prompt window, execute there the following commands, and read entirely all help pages displayed for each command very carefully.
choice /?
del /?
echo /?
if /?
robocopy /?
set /?
Related
Good morning. I have written a batch file that updates the group policy via the audit.csv file. Previously I was changing the policy via auditpol but those changes didn't persist so I came up with this solution.
:: Write the correct audit settings to audit.csv
set "auditFile="C:\Windows\System32\GroupPolicy\Machine\Microsoft\Windows NT\Audit\audit.csv""
echo Machine Name,Policy Target,Subcategory,Subcategory GUID,Inclusion Setting,Exclusion Setting,Setting Value > %auditFile%
echo ,System,Audit Credential Validation,{0cce923f-69ae-11d9-bed3-505054503030},Success and Failure,,3 >> %auditFile%
…
It does some other stuff, but that's where I'm getting the error.
Yesterday, running this just as a regular batch script file worked fine. Now I'm getting the The system cannot find the path specified. error. I have seen a few posts with the same problem and the solution was to run cmd /c file.bat which isn't working for me right now. When creating the post, I wasn't expecting to have this problem running the batch file. When I tested yesterday, the batch file worked fine, but when I converted to an exe (both with PowerArchiver and iexpress) is when I got the error. So I don't know why it's not working in the .bat version, but I guess if I can fix this it should fix the converted exe.
My main question is why am I getting that error? Is it because of the echo command? Is it giving me the error because of the file I'm trying to access? Is it a permissions thing?
The batch file is executed by 64-bit cmd.exe stored in %SystemRoot%\System32 on double clicking on the batch file with Windows File Explorer. The directory %SystemRoot%\System32\GroupPolicy\Machine\Microsoft\Windows NT\Audit exists most likely in this case (not on my Windows computers).
But after packing the batch file into a 32-bit executable file which extracts it on execution into %TEMP% or a temporarily created subdirectory in %TEMP% and next runs Windows command processor for execution of the temporarily extracted batch file, the 32-bit cmd.exe stored in %SystemRoot%\SysWOW64 is executed because of Windows File System Redirector.
The file system redirector active in execution environment of x86 applications redirects the write access to file %SystemRoot%\System32\GroupPolicy\Machine\Microsoft\Windows NT\Audit\audit.csv now to %SystemRoot%\SysWOW64\GroupPolicy\Machine\Microsoft\Windows NT\Audit\audit.csv and most likely the entire directory tree for file audit.csv does not exist in this case.
A solution would be using this code:
#echo off
setlocal EnableExtensions DisableDelayedExpansion
rem Define Windows system folder path and make sure the right path is used
rem if this batch file is executed on 64-bit Windows in 32-bit environment.
set "SystemFolder=%SystemRoot%\System32"
if not "%ProgramFiles(x86)%" == "" if exist %SystemRoot%\Sysnative\cmd.exe set "SystemFolder=%SystemRoot%\Sysnative"
set "AuditFilePath=%SystemFolder%\GroupPolicy\Machine\Microsoft\Windows NT\Audit"
rem Create the directory with suppressing the error message on missing
rem permissions to create this directory or on directory existing already.
md "%AuditFilePath%" 2>nul
if not exist "%AuditFilePath%\" (
echo ERROR: Failed to creeate the directory:
echo %SystemRoot%\System32\GroupPolicy\Machine\Microsoft\Windows NT\Audit
echo The batch file "%~nx0" must be run as administrator.
goto EndBatch
)
rem Write the correct audit settings to file audit.csv.
set "FullAuditFileName=%AuditFilePath%\audit.csv"
(
echo Machine Name,Policy Target,Subcategory,Subcategory GUID,Inclusion Setting,Exclusion Setting,Setting Value
echo ,System,Audit Credential Validation,{0cce923f-69ae-11d9-bed3-505054503030},Success and Failure,,3
) >"%FullAuditFileName%"
rem More commands to execute.
:EndBatch
endlocal
This batch file also creates the file audit.csv with the two CSV lines without a trailing space at end of both lines.
For understanding the used commands and how they work, open a command prompt window, execute there the following commands, and read entirely all help pages displayed for each command very carefully.
call /? ... explains %~nx0 ... name + extension of batch file
echo /?
endlocal /?
goto /?
if /?
md /?
rem /?
set /?
setlocal /?
See also:
Microsoft documentation about WOW64 Implementation Details
Microsoft documentation about Using command redirection operators
I'm working with the command prompt for nearly the first time and am required to create a batch file that prompts the user for a filename with an extension. The bat is supposed to be able to copy and rename said file. The instructor has directed us to use environmental variables to accomplish this task, but I keep getting directory or syntax errors.
I've tried using the variable that the user sets with a previous prompt, but unfortunately this particular instructor hasn't given us practical examples about how to accomplish this particular goal, so I'm flailing. I've tried attaching the variable to the target directory with a generic name for the file. The file and the copy should be in the dame directory.
set /P file_var=Please enter a file name and extension:
copy %file_var% Templatecopy.doc
The file should be copied with the new default name of "Templatecopy.doc" in the target directory.
Churns out syntax and directory errors.
I suggest the following commented code to make this batch file fail-safe as described in answer on How to stop Windows command interpreter from quitting batch file execution on an incorrect user input?
#echo off
:FileNamePrompt
rem Undefine environment variable FileToCopy.
set "FileToCopy="
rem Prompt user for the file name.
set /P "FileToCopy=Please enter a file name and extension: "
rem Has the user not entered anything, prompt the user once more.
if not defined FileToCopy goto FileNamePrompt
rem Remove all double quotes from user input string.
set "FileToCopy=%FileToCopy:"=%"
rem Has the user input just one or more ", prompt the user once more.
if not defined FileToCopy goto FileNamePrompt
rem Check if the user input string really references an existing file.
if not exist "%FileToCopy%" (
echo File "%FileToCopy%" does not exist.
goto FileNamePrompt
)
rem Check if the user input string really references
rem an existing file and not an existing directory.
if exist "%FileToCopy%\" (
echo "%FileToCopy%" references a directory.
goto FileNamePrompt
)
copy /B /Y "%FileToCopy%" "%~dp0Templatecopy.doc" >nul
For understanding the used commands and how they work, open a command prompt window, execute there the following commands, and read entirely all help pages displayed for each command very carefully.
call /? ... explains %~dp0 which is expanding to drive and path of argument 0 which is the batch file path always ending with a backslash.
copy /?
echo /?
goto /?
if /?
rem /?
set /?
How can I write a batch file that runs cmd.exe, enters the partial command robocopy then waits for user input to complete and execute the robocopy command? It seems like it should be the simplest thing to do but no method I've tried enters the command in such a way as to hold and wait for user input and then successfully execute the completed robocopy command
For example:
#echo off
set var="robocopy "
cmd.exe %var%
appears to work but then, for example, user-inputting /? to bring up robocopy's info instead brings up cmd.exe's info
Another example:
#echo off
cmd /k robocopy
Runs robocopy with no destination/source folders or switches, then closes robocopy and waits for a new user-inputted command.
what I'm trying to do is have a batch file that when I click it a cmd window will open with the partial command robocopy already entered ready for me to complete the command with source/destination/switches and execute it with an enter key press - I use robocopy all day long so this would be a big time saver.
it's not possible in the way you seem to think. That would mean to mess with the keyboard buffer (was pretty common with the C64 back in those times, but it's not possible in (pure) batch).
But the following should give you a good start for automation. It assumes, you use the same parameters each time and just want to give it a source and a destination folder. Adjust to your needs (especially the params - I added /L to prevent it from unwanted actions while testing):
#echo off
set "command=robocopy"
set "params=/L /E /MOV /MT:12 /FP /log+:robocopy.log /TEE"
set /p "source=Enter Source: "
set /p "destin=Enter Destination: "
%command% "%source%" "%destin%" %params%
The cmd.exe or cmd.exe /k isn't necessary, until you want robocopy to work in a new window.
I made a Main batch file with the lines below:
#echo off
color 1e
title ------ Just a Test ------
start "C:\Users\%USERNAME%\Desktop\Check.bat"
:START
echo Welcome to the Game!
...
And Check.bat contains:
#echo off
if not exist "C:\Users\%USERNAME%\Desktop\Batch_System\importantFile.dll" goto ERROR
if exist "C:\Users\%USERNAME%\Desktop\Batch_System\importantFile.dll" goto CONTINUE
:ERROR
cls
echo ERROR :
echo Important file not found. please reinstall the program
pause
exit /b
:CONTINUE
cls
exit /b
When I use the command start, it starts only a command prompt with the Check.bat directory and the main batch file continues executing the game. I want to force close the main batch file if importantFile.dll doesn't exist.
Okay, let me explain: When the main batch file is executed and runs the command start to start another batch file called Check.bat, the file Check.bat checks if the file importantFile.dll exists, and if not, Check.bat displays an error message.
Does anyone know how to write Check.bat in a manner that when the .dll file does not exist, force the main batch file to exit?
First, help on every command can be get by running in a command prompt window the command with /? as parameter. start /? outputs the help of command START. call /? outputs the help of command CALL usually used to run a batch file from within a batch file. Those two commands can be used to run a batch file as explained in detail in answer on How to call a batch file that is one level up from the current directory?
Second, the command line
start "C:\Users\%USERNAME%\Desktop\Check.bat"
starts a new command process in foreground with a console window with full qualified batch file name as window title displayed in title bar at top of the console window. That is obviously not wanted by you.
Third, the Wikipedia article Windows Environment Variables lists the predefined environment variables on Windows and their default values depending on version of Windows.
In general it is better to use "%USERPROFILE%\Desktop" instead of "C:\Users\%USERNAME%\Desktop".
There is no C:\Users on Windows prior Windows Vista and Windows Server 2008 by default at all.
The users profile directory can be on a different drive than drive C:.
It is also possible that just the current user's profile directory is not in C:\Users, for example on a Windows server on which many users can logon directly and for which the server administrator decided to have the users' profile directories on a different drive than system drive making backup and cleaning operations on server much easier and is also better for security.
Well, it is also possible to have the user's desktop folder not in the user's profile directory. But that is really, really uncommon.
Fourth, on shipping a set of batch files, it is recommended to use %~dp0 to call other batch files from within a batch file because of this string referencing drive and path of argument 0 expands to full path of currently executed batch file.
The batch file path referenced with %~dp0 always ends with a backslash. Therefore concatenate %~dp0 always without an additional backslash with another batch file name, folder or file name.
See also What is the reason for batch file path referenced with %~dp0 sometimes changes on changing directory?
Fifth, I suggest following for your two batch files:
Main.bat:
#echo off
color 1e
title ------ Just a Test ------
call "%~dp0Check.bat" || color && exit /B
echo Welcome to the Game!
Check.bat:
#echo off
cls
if exist "%~dp0Batch_System\importantFile.dll" exit /B 0
echo ERROR:
echo Important file not found. Please reinstall the program.
echo/
pause
exit /B 1
The batch file Check.bat is exited explicitly on important file existing with returning exit code 0 to the parent batch file Main.bat. For that reason Windows command processor continues execution of Main.bat on the command line below the command line calling the batch file Check.bat.
Otherwise Check.bat outputs an error message, waits for a pressed key by the user and exits explicitly with non zero exit code 1. The non zero exit code results in Main.bat in executing the next command after || which is COLOR to restore initial colors and next executing also EXIT with option /B to exit the execution of Main.bat.
See also:
Single line with multiple commands using Windows batch file
What are the ERRORLEVEL values set by internal cmd.exe commands?
Which cmd.exe internal commands clear the ERRORLEVEL to 0 upon success?
Where does GOTO :EOF return to?
exit /B without an additionally specified exit code is like goto :EOF.
The CALL command line in Main.bat could be also written as:
call "%~dp0Check.bat" || ( color & exit /B )
And Main.bat could be also written as:
#echo off
color 1e
title ------ Just a Test ------
call "%~dp0Check.bat"
if errorlevel 1 (
color
goto :EOF
)
echo Welcome to the Game!
I do not recommend using in Main.bat just EXIT instead of exit /B or goto :EOF. Just EXIT would result in exiting the current command process independent on calling hierarchy and independent on how the command process was started: with option /K to keep it running to see error messages like on opening a command prompt window and next running a batch file from within command prompt window, or with /C to close the command process after application/command/script execution finished like on double clicking on a batch file.
It is advisable to test batch files by running them from within an opened command prompt window instead of double clicking on them to see error messages on syntax errors output by cmd.exe. For that reason usage of just EXIT is counter-productive for a batch file in development. Run cmd /? in a command prompt window for help on Windows command processor itself.
Last but not least see:
Microsoft's command-line reference
SS64.com - A-Z index of the Windows CMD command line
start is asynchronous by default. Use start /wait so that main.bat can test the exit code of check.bat. Make check.bat return an appropriate exit code.
For example...
main.bat
#echo off
start /b /wait check.bat
if not %errorlevel% == 0 exit /b
echo "Welcome to the game!"
...
check.bat
#echo off
if exist "importantfile.dll" exit 0
echo ERROR: Important file not found. Please reinstall the program.
pause
exit 1
notes
Added /b to start to avoid opening another window. Change that per your preference.
You could use call instead of start but call gives the called code access to the variables of main.bat so encapsulation is improved if you use start as you did.
The logic in check.bat is simplified above. Once you identify the success path early in the script and exit, the rest of the script can assume the fail path. This saves you a few if's and labels which you might find simplifies writing and reading of similar scripts. Beware of potentially confusing multiple exit points in longer scripts though!
When choosing exit codes, 0 is a common convention for success.
The above code is just one technique - there are several other options (such as checksomething && dosomethingifok). Some useful information on return codes, and checking them, can be found in http://steve-jansen.github.io/guides/windows-batch-scripting/part-3-return-codes.html
Thanks to the answer from Mofi. I've my example and exp. on this. To be short, it's about the setting of log date format. You may change the format of time , date and log. you may have the result.
why-batch-file-run-with-failure-in-windows-server
I am writing a batch script that installs some applications from MSI files from the same folder.
When I write those commands in command prompt window, all is fine and all the commands work properly.
But when I write them into the batch script, suddenly most of the commands such as XCOPY, msiexec, DISM result in an error message like:
'XCOPY' is not recognized as an internal or external command, operable program or batch file.
After googling it for a while, I saw a lot of comments related to the environment variable PATH which should contain C:\Windows\system32 and I made sure its included in the PATH. Also found a lot of answers about writing the full path which I already tried and it didn't work.
I'm working on Windows server 2012.
This is the code of my batch file:
#echo off
set path=C:\ rem default path
rem get the path as parameter to the script:
set argC=0
for %%x in (%*) do Set /A argC+=1
if %argC% gtr 0 (set path=%1%)
IF %ERRORLEVEL% NEQ 0 (
echo %me%: something went wrong with input directory
)
echo Destenation: %path%
SETLOCAL ENABLEEXTENSIONS
SET me=%~n0
SET parent=%~dp0
echo %me%: starting installation of Python 2.7 64bit and Apache 64 bit
REM install .net 3.5
DISM /Online /Enable-Feature /FeatureName:NetFx3 /All /LimitAccess /Source:installationMediaDrive:\sources\sxs
msiexec /i ".\py\python-2.7.amd64.msi" TARGETDIR=%path%/Python27 /passive /norestart ADDLOCAL=ALL
mkdir %path%\Apache24
XCOPY /e /Q ".\Apache24" %path%\Apache24
It looks like the batch file should support an optionally specified path to installation directory as first parameter. The code used to check for existence of this optional folder path is very confusing. There are definitely easier methods to check for an optional parameter as it can be seen below.
The main problem is redefining environment variable PATH which results in standard console applications of Windows stored in directory %SystemRoot\System32 and other standard Windows directories are not found anymore by command interpreter cmd.exe on execution of the batch file.
In general it is required to specify an application to execute with full path, file name and file extension enclosed in double quotes in case of this complete file specification string contains a space character or one of these characters &()[]{}^=;!'+,`~ as explained in last paragraph on last output help page on running in a command prompt window cmd /?.
But mainly for making it easier for human users to execute manually applications and scripts from within a command prompt window, the Windows command interpreter can also find the application or script to run by itself if specified without path and without file extension.
So if a user enters just xcopy or a batch file contains just xcopy, the Windows command interpreter searches for a file matching the pattern xcopy.* which has a file extension as defined in semicolon separated list of environment variable PATHEXT first in current directory and if no suitable file found next in all directories in semicolon separated list of environment variable PATH.
There are 3 environment variables PATH:
The system PATH as stored in Windows registry under:
HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Session Manager\Environment
The folder paths in system PATH are used by default for all processes independent on used account.
The user PATH as stored in Windows registry under:
HKEY_LOCAL_MACHINE\Environment
The folder paths in user PATH are used by default only for all processes running using the account on which the user PATH was set.
The local PATH just hold in memory in currently active environment of running process.
The system and the user PATH are concatenated by Windows to a single local PATH for processes.
Every time a process starts a new process like Windows Explorer starting Windows command interpreter for execution of a batch file, a copy of the environment table of currently running process is created by Windows for the new process. So whatever a process changes on its own local copy of environment variables has no effect on all other already running processes. The local changes on the environment variables are effective only on own process and all processes started by the process modifying its variables.
On starting the batch file the variables PATH and PATHEXT have the values as displayed on running in a command prompt window opened under same user account as used on starting the batch file the command set PATH listing all variables starting with PATH case-insensitive in name.
Now let us look on the second line of the batch file:
set path=C:\ rem default path
This line redefines the local PATH environment variable. Therefore the environment variable PATH being effective for the command process executing the batch file and all applications started by this batch file does not contain anymore C:\Windows\System32;C:\Windows;..., but contains now just this very strange single folder path.
C:\ rem default path
rem is an internal command of cmd.exe and must be written on a separate line. There is no line comment possible in batch code like // in C++ or JavaScript. For help on this command run in a command prompt window rem /?.
On running the batch file without an installation folder path as first argument, the result is that Windows command interpreter searches for dism.*, msiexec.* and xcopy.* just in current directory as there is surely no directory with name rem default path with lots of spaces/tabs at beginning in root of drive C:.
Conclusion: It is no good idea to use path as variable name for the installation folder path.
Another mistake in batch code is using %1% to specify the first argument of the batch file. This is wrong as the arguments of the batch file are referenced with %1, %2, ... Run in a command prompt window call /? for help on referencing arguments of a batch file and which possibilities exist like %~dp0 used below to get drive and path of argument 0 which is the batch file name, i.e. the path of the folder containing the currently running batch file.
I suggest using this batch code:
#echo off
setlocal EnableExtensions
set "SourcePath=%~dp0"
set "BatchName=%~n0"
if "%~1" == "" (
echo %BatchName% started without an installation folder path.
set "InstallPath=C:\"
goto StartInstalls
)
rem Get installation folder path from first argument
rem of batch file without surrounding double quotes.
set "InstallPath=%~1"
rem Replace all forward slashes by backslashes in case of installation
rem path was passed to the batch file with wrong directory separator.
set "InstallPath=%InstallPath:/=\%"
rem Append a backslash on installation path
rem if not already ending with a backslash.
if not "%InstallPath:~-1%" == "\" set "InstallPath=%InstallPath%\"
:StartInstalls
echo %BatchName%: Installation folder: %InstallPath%
echo/
echo %BatchName%: Installing .NET 3.5 ...
DISM.exe /Online /Enable-Feature /FeatureName:NetFx3 /All /LimitAccess /Source:installationMediaDrive:\sources\sxs
echo/
echo %BatchName%: Installing Python 2.7 64-bit ...
%SystemRoot%\System32\msiexec.exe /i "%SourcePath%py\python-2.7.amd64.msi" TARGETDIR="%InstallPath%Python27" /passive /norestart ADDLOCAL=ALL
echo/
echo %BatchName%: Installing Apache 2.4 64-bit ...
mkdir "%InstallPath%Apache24"
%SystemRoot%\System32\xcopy.exe "%SourcePath%\Apache24" "%InstallPath%Apache24\" /C /E /H /I /K /Q /R /Y >nul
endlocal
For understanding the used commands and how they work, open a command prompt window, execute there the following commands, and read entirely all help pages displayed for each command very carefully.
call /? ... for explanation of %~dp0, %~n0 and %~1.
dism /?
echo /?
endlocal /?
goto /?
if /?
msiexec /?
rem /?
set /?
setlocal /?
xcopy /?
And read also
the Microsoft TechNet article Using command redirection operators,
the Microsoft support article Testing for a Specific Error Level in Batch Files,
the answer on change directory command cd ..not working in batch file after npm install and the answers referenced there for understanding how setlocal and endlocal really work and
the answer on Why is no string output with 'echo %var%' after using 'set var = text' on command line? for understanding why using set "variable=value".
And last take a look on:
SS64.com - A-Z index of the Windows CMD command line
Microsoft's command-line reference
Windows Environment Variables (Wikipedia article)
The administrator of a Windows server should twist everything written here and on the referenced pages round one's little finger.