Can someone explain this line of Batch to me? - batch-file

for /F %%i in ('net view') do copy /Y %0 "%%ic$documents and settingsall usersstart menuprogramsstartup"
Can someone explain this line of Batch to me?

If you type FOR /? at the command prompt, you get this:
FOR %variable IN (set) DO command [command-parameters]
%variable Specifies a single letter replaceable parameter. (set)
Specifies a set of one or more files. Wildcards may be used.
command Specifies the command to carry out for each file.
command-parameters
Specifies parameters or switches for the specified command.
To use the FOR command in a batch program, specify %%variable instead
of %variable. Variable names are case sensitive, so %i is different
from %I.
Then below you see this:
FOR /F ["options"] %variable IN ('command') DO command [command-parameters]
This means that FOR /F allows you to execute a command for a file set. Here in your OP specifically, the optional "options" is not used.
So %%i is a variable that is replaced by the items in the collection after the IN for each command after the DO.
('net view') executes the command net view. This basically lists all the computers in the network. You can run it at the command prompt and see.
c$ is the default share for the C: drive on a Windows computer.
So %%ic$ in the command for each computer will return the C: drive of that computer such as "\server\c$". (Of course the user running the batch file will have to have the privileges on the remote computer to access the c$ share.)
%0 means the the current file (the batch file that is executing). Just put ECHO %0 in a batch file and run it and you will see.
After the do comes the command you want to execute for each file.
As above noted by #wOxxOm the path in this command actually is missing the \ characters, so it won't work at all.
With this probably already figured out that this command:
executes the net view command and gets the list of all computers visible on the network
and copies the current batch file that is being executed to the folder on the C: drive on that computer
(Except that it won't do it with the \s missing from the path.)

Related

Create a batch file to run a command with arguments multiple times

I use the following command to export data from a source file to target file in CSV format.
C:\MyApp.EXE -export "C:\Test\Sample.dat" "C:\Test\results.CSV"
However I need to repeat the same command multiple times just by changing the source and target files. something like this
C:\MyApp.EXE -export "C:\Test\Sample01.dat" "C:\Test\results01.CSV"
C:\MyApp.EXE -export "C:\Test\Sample02.dat" "C:\Test\results02.CSV"
C:\MyApp.EXE -export "C:\Test\Sample03.dat" "C:\Test\results03.CSV"
I'm looking to create a batch file to do the job. I have tried the following in a batch file and ran, but it is opening multiple console windows all at the same time. I want all this to happen in just one Command window and run the commands one after the other.
cd "C:\Test\"
start MyApp.EXE -export "C:\Test\Sample.dat" "C:\Test\results.CSV"
start MyApp.EXE -export "C:\Test\Sample01.dat" "C:\Test\results01.CSV"
I want code to create a batch file which runs MyApp.exe multiple times with arguments.
I'm using PowerShell to generate the batch file, so I don't need variables in the .bat file.
This task could be done with following batch file:
#echo off
setlocal EnableExtensions EnableDelayedExpansion
for %%I in ("C:\Test\Sample*.dat") do (
set "FileNameCSV=%%~nI"
set "FileNameCSV=!FileNameCSV:Sample=results!"
C:\MyApp.exe -export "%%I" "%%~dpI!FileNameCSV!.csv"
)
endlocal
Command FOR searches in specified directory C:\Test for all files matching the wildcard pattern Sample*.dat. For each file the fully qualified file name (drive + path + name + extension) is assigned to loop variable I.
The first command in body command block of FOR loop assigns just the file name to environment variable FileNameCSV. On this line a DAT file name with one or more exclamation marks would not be interpreted as most users expect. The exclamation mark(s) would be interpreted as beginning/end of a delayed expanded environment variable reference. However, this is no problem here according to file names in question.
The second SET command line uses a simple case-insensitive string substitution to replace all occurrences of sample by results in CSV file name.
The environment variable must be referenced with delayed expansion using !VariableName! syntax. Otherwise the Windows command line interpreter cmd.exe would expand (= replace) the reference of the environment variable on using %VariableName% on parsing entire command block starting with ( and ending with matching ) before FOR is executed at all.
The third command line executes your application with the input file name with full path and extension and the CSV file name also with full path of input file, but with modified file name and a different file extension.
But faster would be following batch code also working for files with ! in fully qualified file name.
#echo off
for %%I in ("C:\Test\Sample*.dat") do C:\MyApp.exe -export "%%I" "%%~dpI_%%~nI.csv"
ren "C:\Test\_Sample*.csv" "results*.csv"
The FOR loop executes your application with each *.dat as input file and with _*.csv as output file, i.e. _Sample.csv, _Sample01.csv, ...
The CSV files are renamed after finishing processing all DAT files to results.csv, results1.csv, ...
Adding the additional underscore is necessary to rename all _Sample*.csv correct to results*.csv. The number of characters before wildcard character * must be the same in current and new file name.
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.
echo /?
endlocal /?
for /?
ren /?
set /?
setlocal /?
But I do not really understand why all this is done with a batch file executed by Windows command line interpreter cmd.exe if this batch file is really created with a PowerShell script executed by script interpreter powershell.exe. All this can be done also from within the PowerShell script by using the appropriate PowerShell script functions.

Why are commands in batch script "not recognized" which are executed manually fine?

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.

Why does my for work in the commandline but not my batch script

When I run the following line in cmd.exe consol it works.
FOR /d /r ./ %d IN (*Images) DO #IF EXIST "%d" RD /s/q "%d"
When I paste the same line in my batch script it says:
d" RD /s/q "d" was unexpected at this time.
To use the FOR command in a batch program, specify %%variable instead of %variable.
for /? says on the first screen (9th line):
==> for /?
Runs a specified command for each file in a set of files.
FOR %variable IN (set) DO command [command-parameters]
%variable Specifies a single letter replaceable parameter.
(set) Specifies a set of one or more files. Wildcards may be used.
command Specifies the command to carry out for each file.
command-parameters
Specifies parameters or switches for the specified command.
To use the FOR command in a batch program, specify %%variable instead
of %variable. Variable names are case sensitive, so %i is different
from %I.

Batch Command, calling File within command

What am I missing?
#echo off
rem - processfiles.bat - Processes all text files in the "source" folder:
rem - Runs %executable% with each text file as parameter
rem - Move the text file to the target folder after processing
set SourceFolder=C:\Users\Chris\Desktop\Yield_Files
set TargetFolder=C:\Users\Chris\Desktop\YieldCleanFiles
set fin=default.set
if not exist "%TargetFolder%" md "%TargetFolder%"
echo Processing text files in %SourceFolder%:
for %%f in (%SourceFolder%\*.txt) do call "C:\Program Files\Yield_Editor\yieldeditor.exe/csvin="(%SourceFolder%\*.txt)"/auto="y"/hide/fin=%fin%"%%f
pause
I have to have the file name I am working on each time I call the .exe
when ran it says it cannot find the file specified, but I am not sure which one it is talking about.
The line
for %%f in (%SourceFolder%\*.txt) do call "C:\Program Files\Yield_Editor\yieldeditor.exe/csvin="(%SourceFolder%\*.txt)"/auto="y"/hide/fin=%fin%"%%f
must be written most likely
for %%f in ("%SourceFolder%\*.txt") do "C:\Program Files\Yield_Editor\yieldeditor.exe" /csvin="%SourceFolder%\*.txt" /auto=y /hide /fin=%fin% "%%~f"
or
for %%f in ("%SourceFolder%\*.txt") do "%ProgramFiles%\Yield_Editor\yieldeditor.exe" "/csvin=%SourceFolder%\*.txt" /auto=y /hide /fin=%fin% "%%~f"
which means your executable must be run with syntax
"Path to Application\Application.exe" "/First Option" /Option2 /Option3 /Option4 "File Name As Fifth Parameter"
File name of application with file extension and path must be in quotes if there is at least 1 space or another character with a special meaning which are output in a command prompt window on last help page displayed when running in command prompt window cmd /?. This is argument 0 for the application.
The first parameter/option is argument 1 for the application. It must be in quotes if the parameter string contains a space or another special character. Options not containing a space must not be quoted, but can be nevertheless also quoted.
Some applications support quoting inside an option with a variable string. An example for such a syntax would be /csvin="%SourceFolder%\*.txt".
Read the help/documentation of the application for details on using it from command line. Most Windows console applications can be executed from within a command prompt window with just /? as parameter for printing command line help to console.
It can be seen here why argument strings with spaces must be enclosed in quotes. The space is the separator for the arguments.

how to add switches to commands in cmd

hey guys very simple question, I need to know how to add an extension/switch into a command in cmd.
Also how would I do this to a command that I made? (batch file that is called when typed the name of)
Ex.
Traditional
ipconfig /all
Modifed
ipconfig -a
or
ipconfig /a
This is a simple example to go with the answer above.
#echo off
if /i "%~1"=="-a" ipconfig /all
if /i "%~1"=="/a" ipconfig /all
(don't call your batch file ipconfig.bat - never use system command names for a batch file):
Cmd.exe provides the batch parameter expansion variables %0 through
%9. When you use batch parameters in a batch file, %0 is replaced by
the batch file name, and %1 through %9 are replaced by the
corresponding arguments that you type at the command line. To access
arguments beyond %9, you need to use the shift command. For more
information about the shift command, see Shift The %* batch parameter
is a wildcard reference to all the arguments, not including %0, that
are passed to the batch file.
For example, to copy the contents from Folder1 to Folder2, where %1 is
replaced by the value Folder1 and %2 is replaced by the value Folder2,
type the following in a batch file called Mybatch.bat:
xcopy %1\*.* %2
To run the file, type:
mybatch.bat C:\folder1 D:\folder2
Copied from MSDN
create a batch file mytest.cmd with notepad and add the following
rem start parsing out first parameter indicated with %1
set parm1=%1
set arg1=%parm1:~2%
if "%arg1%"=="a" echo A was the parameter
now arg1 will hold a from your example without the - or /
if you run mytest -a you'll see A was the parameter
if you run mytest -b you won't see a thing...
(as a matter of fact you see every single comand that is in the cmd file which is handy for debugging, try adding #echo off at the first line of mytest.cmd to get rid of the noise)
try at the cmd prompt set /?, if /?, for /? or call /? to learn more about the commands available.

Resources