The system cannot find the path specified - batch to exe - batch-file

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

Related

How to store Parent Directory as a variable, Cmd/Bat files

Problem
I am writing some .cmd / .bat files on a windows machine that need to work on an sd card with variable parent directories. The sd card will likely change drive names (Drive A, Drive E, etc.) as it moves from device to device and I want to write cmd files that will anticipate that. I would like this to work with my linux steam deck if possible, but if not I understand.
Rom Location
E:\Games\Nintendo\3DS\Games\Animal Crossing New Leaf.3ds
Core Location
E:\Games\RetroArch\cores\citra_libretro.dll
3DS.cmd , currently works at this address
#echo off
echo Keeping Window Active for GOG Time Tracking
cd "E:\Games\RetroArch\"
"retroarch.exe" -L "cores\citra_libretro.dll" %1 -f
Animal Crossing New Leaf.cmd , currently works at this address
#echo off
call "3DS.cmd" "E:\Games\Nintendo\3DS\Games\Animal Crossing New Leaf.3ds"
Question
How would I write the code above as a windows file on any non-specific drive directory where the current Directory is on the Drive named E:\ ?
(Ex: A:\ , or B:, and so on)
There can be used the following lines in the batch file 3DS.cmd if this batch file is stored in root of the SD card and is executed from the SD card mounted as drive with a drive letter:
#echo off
echo Keeping window active for GOG time tracking
cd /D "%~d0\Games\RetroArch"
retroarch.exe -L cores\citra_libretro.dll %1 -f
The usage help of command CALL output on running call /? in a command prompt window explains how to reference the arguments of a batch file. There is always the argument 0 even on batch file is executed without any argument string passed to the batch file by a user or another process.
%0 references the string used to start the execution of the batch file. On double clicking on a batch file stored on an SD card mounted with a drive letter by Windows, %0 expands to the fully qualified file name of the batch file on the SD card enclosed in " because of the Windows File Explorer starts in background:
C:\WINDOWS\system32\cmd.exe /c ""Animal Crossing New Leaf.cmd" "
The usage help of the Windows Command Processor cmd.exe output on running cmd /? explains how the arguments are interpreted by cmd.exe in this case. The first and the last " are removed from the command line. The started cmd.exe executes therefore:
"E:\Animal Crossing New Leaf.cmd"
That string with the double quotes is argument 0 of the executed batch file.
%~d0 can be used in the batch file to reference just the drive letter and the colon of the currently running batch file respectively \\ if the batch file is stored on a network resource executed using its UNC path.
The code above works only for batch file being stored in root of a storage media mounted with a drive letter.
A code for 3DS.cmd working always independent on which storage media the batch file is stored and in which directory and how the batch file is started as long as the directory Games is a subdirectory of the directory containing the batch file is:
#echo off
setlocal EnableExtensions DisableDelayedExpansion
cls
if "%~1" == "" echo ERROR: %~nx0 called without game file name!& pause & exit /B
pushd "%~dp0Games\RetroArch"
echo Keeping window active for GOG time tracking
retroarch.exe -L cores\citra_libretro.dll %1 -f
popd
endlocal
%~dp0 expands to full path of the batch file always ending with a backslash.
See also: What is the reason for batch file path referenced with %~dp0 sometimes changes on changing directory? The bug of cmd.exe does not matter here because of %~dp0 is used before changing the current directory the first time with the command PUSHD.
The batch file Animal Crossing New Leaf.cmd stored in same directory as 3DS.cmd should contain only the single command line:
#call "%~dp03DS.cmd" "%~dp0Games\Nintendo\3DS\Games\Animal Crossing New Leaf.3ds"
The two batch files can be used with these improvements also on copying all directories and files on the SD card to a directory of user´s choice like %UserProfile%\RetroGames.
It is also possible to use only one batch file with name Animal Crossing New Leaf.cmd stored in the directory with the subdirectory Games and all the other directories and files with the following lines:
#echo off
setlocal EnableExtensions DisableDelayedExpansion
pushd "%~dp0Games\RetroArch" || (echo ERROR: Missing subdirectory "Games\RetroArch"& pause & exit /B)
echo Keeping window active for GOG time tracking
retroarch.exe -L cores\citra_libretro.dll "%~dp0Games\Nintendo\3DS\Games\Animal Crossing New Leaf.3ds" -f
popd
endlocal
To understand the commands used and how they work, open a command prompt window, execute there the following commands, and read the displayed help pages for each command, entirely and carefully.
call /?
cd /?
echo /?
endlocal /?
exit /?
if /?
pause /?
popd /?
pushd /?
setlocal /?
I used Chat GPT, it gave me this result that is now working.
3ds.cmd
#echo off
echo Keeping Window Active for GOG Time Tracking
set sd_dir=%cd:~0,1%
cd "%sd_dir%:\Games\RetroArch\"
"retroarch.exe" -L "cores\citra_libretro.dll" %1 -f
Animal Crossing New Leaf.cmd
#echo off
set sd_dir=%cd:~0,1%
call "3DS.cmd" "%sd_dir%:\Games\Nintendo\3DS\Games\Animal Crossing New Leaf.3ds"

Batch symbolic link creation from .txt list

I need a way to create symbolic links to multiple files in one folder, all listed in a .txt file. Filenames in the list lack the file extension. I used to do copy with the following script, and I failed to replace the copy command to symlink creation.
#echo off
chcp 65001 > nul
for /f "usebackq delims=" %%i IN ("selection_list.txt") DO (
xcopy "..\%%i.zip" "..\selection\%%i.zip*"
)
pause
Using relative paths because i wanna be able to use this in multiple folders.
Filenames in the .txt file don't include file extensions.
For instantce, let's say I wanna use this in a folder "F:\assets", i'll put my script in a folder "F:\assets\selection_script" along with the .txt file named selection_list.txt. After launching the script, it'll create a folder "F:\assets\selection" with all the files I wanted in it.
I tried replacing xcopy command with mklink /D, using this syntax example
mklink /D "C:\Link To Folder" "C:\Users\Name\Original Folder"
New script looks like this
#echo off
chcp 65001 > nul
for /f "usebackq delims=" %%i IN ("selection_list.txt") DO (
mklink /D "..\selection_links\%%i.zip*" "..\%%i.zip"
)
pause
Obviously this didn't work. Says System can't find the file selection_list.txt
I tried to manually run the command for a single named file with relative paths and it worked, so my problem is getting it to work in a function with a list. Seems to me that file extensions being added on top of filename from .txt list might be the problem, but idk how to resolve it. I tried few syntax variations I found, without success
I'm quite unexperienced with this so any help would be greatly appreciated!
Let me first explain better the task to do. There are following folders and files:
F:\assets
selection
Development & Test(!).zip
;Example Zip File.zip
selection_script
create_selection.cmd
selection_list.txt
The text file selection_list.txt contains the lines:
Development & Test(!)
;Example Zip File
Not existing file
The execution of create_selection.cmd should result in the following folders and files:
F:\assets
selection
Development & Test(!).zip
;Example Zip File.zip
selection_links
Development & Test(!).zip
;Example Zip File.zip
selection_script
create_selection.cmd
selection_list.txt
The directory entries Development & Test(!).zip and ;Example Zip File.zip in created directory selection_links are symbolic links and not copies of the two files in directory selection.
This symbolic links creation task can be done with F:\assets\selection_script\create_selection.cmd with the following command lines:
#echo off
setlocal EnableExtensions DisableDelayedExpansion
for /F "tokens=*" %%G in ('%SystemRoot%\System32\chcp.com') do for %%H in (%%G) do set /A "CodePage=%%H" 2>nul
%SystemRoot%\System32\chcp.com 65001 >nul 2>&1
for %%I in ("%~dp0..\selection_links") do set "LinksFolder=%%~fI"
if not exist "%LinksFolder%\" md "%LinksFolder%" 2>nul
if not exist "%LinksFolder%\" echo ERROR: Failed to create directory: "%LinksFolder%"& goto EndBatch
pushd "%LinksFolder%"
if exist "%~dp0selection_list.txt" for /F "usebackq eol=| delims=" %%I in ("%~dp0selection_list.txt") do if exist "..\selection\%%I.zip" if not exist "%%I.zip" mklink "%%I.zip" "..\selection\%%I.zip" >nul
popd
:EndBatch
%SystemRoot%\System32\chcp.com %CodePage% >nul
endlocal
There is defined first completely the required execution environment with the first two command lines setting up a local execution environment with command echo mode turned off, command extensions enabled and delayed variable expansion disabled as required for this task.
There is next determined the currently active code page and stored in environment variable CodePage using a command line published by Compo on DosTips forum topic [Info] Saving current codepage. Then the active code page is changed to UTF-8 although not really needed for the example.
There is next determined once the full path of the folder in which the symbolic links should be created which is the folder selection_links being a subfolder of the parent folder F:\assets of the folder selection_script containing the batch script. It does not matter if this folder already exists or not on determining the fully qualified folder name.
There is next verified if the target folder exists. The folder selection_links is created on not existing with checking once again if the folder really exists now. A useful error message is output on creation of folder failed and the batch file restores the initial code page and the initial execution environment.
The target folder is made the current directory by using the command PUSHD which should not fail anymore now after verification that the target folder exists.
There are next processed the lines in the text file selection_list.txt referenced with its fully qualified file name by using %~dp0 which expands to drive and path of argument 0 which is the full path of the batch file always ending with a backlash.
Each non-empty line not starting with the character | is assigned completely one after the other to the loop variable I. The character | is not valid for a file name as explained in the Microsoft documentation about Naming Files, Paths, and Namespaces. There is verified next if there is really a ZIP archive file with that name in the folder selection and if there is no directory entry with same name in current folder selection_links.
If these two conditions are both true, MKLINK is executed to create in current directory selection_links a file symbolic link to the ZIP file in the directory selection.
Please note that a ZIP archive file is not a directory and for that reason the usage of MKLINK option /D to create a directory symbolic link cannot work ever.
Finally the initial current directory is restored using POPD and the initial code page and the initial execution environment are also restored by the batch file before it ends.
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 ... drive and path of argument 0 – the batch file path
chcp /?
echo /?
endlocal /?
for /?
goto /?
if /?
md /?
mklink /?
popd /?
pushd /?
set /?
setlocal /?
See also:
Microsoft documentation about Using command redirection operators
Single line with multiple commands using Windows batch file

Why does execution of batch script end unexpected on IF/ELSE statement?

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 /?

Making a directory on a path stored inside a variable in batch file

I'm new in batch programming. The thing is I have a path and a new folder name in 2 variables, so I want to concatenate it and make a new folder in that result path. I tried many things but nothing worked. Please help
I tried this code
#echo off
setlocal EnableDelayedExpansion
set ver=project
set spath=d:\a\svn\
set path=!%spath%%ver%!
mkdir %path%
pause
endlocal
Do not use path as name for an environment variable because such an environment variable is defined already by default with a very important meaning, see the answers on What is the reason for 'sort' is not recognized as an internal or external command, operable program or batch file?
To concatenate two environment variable values just reference those two environment variables on assigning the value to one of the two environment variables or a new environment variable.
#echo off
setlocal EnableExtensions DisableDelayedExpansion
set "ProjectVersion=project"
set "SvnPath=d:\a\svn\"
set "ProjectPath=%SvnPath%%ProjectVersion%"
mkdir "%ProjectPath%"
pause
endlocal
See also answer on Why is no string output with 'echo %var%' after using 'set var = text' on command line? for the reason using set "variable=value" with double quotes around string value to variable assignment, i.e. around the argument string of command SET.
The commands SETLOCAL and ENDLOCAL would not be really necessary here.
Possible would be also:
#echo off
set "ProjectVersion=project"
set "SvnPath=d:\a\svn\"
set "ProjectPath=%SvnPath%%ProjectVersion%"
mkdir "%ProjectPath%" 2>nul
if not exist "%ProjectPath%\" echo Failed to create directory "%ProjectPath%" & pause & goto :EOF
The batch file above creates the directory with suppressing any error message by redirecting STDERR to device NUL. An error message is output if the directory already exists or it was not possible to create the directory because NTFS permissions denies folder creation for current user or in directory path there is a file with the name of a directory in path, e.g. there is a file with name project in directory d:\a\svn or there is a file svn in directory d:\a. The next command with a backslash appended to directory path checks if the directory exists after execution of command MKDIR and outputs an error message with PAUSE and next exiting batch file when the directory still does not exist.
Read also the Microsoft article about Using Command Redirection Operators for an explanation of 2>nul and Single line with multiple commands using Windows batch file for an explanation of & operator.
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 /?
goto /?
if /?
mkdir /?
pause /?
set /?
setlocal /?
#echo off
setlocal EnableDelayedExpansion
set version=project
set spath=d:\a\svn\
set mypath=%spath%%version%
mkdir %mypath%
pause
endlocal
path is a reserved name - it defines the sequence of directories that is searched for an executable if the executable is not found in the current directory. If you change it, well - in short, gloom
ver is not a reserved name, but it is the name of a inbuilt utility and makes a poor choice for variable-name.
Your code was attempting to set your desired new pathname to the contents of the variable d:\a\svn\project. Since this variable is very unlikely to exist, you would have attempted to make a directory named nothing.
btw - there is no need to set mypath - md %spath%%ver% would work just as well. MD is a synonym of mkdir and is used more often.

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.

Resources