1

I have an intune package which runs a batch script as follows.

SET INST=%~dp0

xcopy %INST%\Folder1\* "C:\Program Files (x86)\Test\Folder2" /s /i

Goal is to copy files from Folder1 to Folder2. The Batch script and folder 1 are in the same main folder. No files are being copied so I'm confused.

Thanks,

Nebelz Cheez
  • 307
  • 2
  • 4
  • 15
  • OK, in that case, is the value of `INST` exactly what you expect it to be? Also, the correct filesystem permissions for a user should prevent writing in the "C:\Program Files (x86)" directory. Please see [How-to: Windows Environment Variables](https://ss64.com/nt/syntax-variables.html) for the normal locations that you might use, such as `APPDATA` or `LOCALAPPDATA`. – Andrew Morton Apr 29 '22 at 17:18
  • 1
    Your first line should read as `SET "INST=%~dp0"`, and the second should be `%SystemRoot%\System32\xcopy.exe "%INST%Folder1" "%ProgramFiles(x86)%\Test\Folder2\" /S`. You should note that this code will only work if your end user has permissions for the destination directory. – Compo Apr 29 '22 at 17:38
  • @Mofi , I just tried your implementation and it worked! thank you! – Nebelz Cheez Apr 29 '22 at 18:49

1 Answers1

0

The two command lines could be replaced by the single command line:

%SystemRoot%\System32\xcopy.exe "%~dp0Folder1" "%ProgramFiles(x86)%\Test\Folder2\" /S

The batch file with this command line needs to be run as administrator because of the directory referenced with %ProgramFiles(x86)% is usually write-protected for standard users.

The help output on running cmd /? in a command prompt window explains on last help page that a file name (or any other argument string like a password) containing a space or one of these characters &()[]{}^=;!'+,`~ (or literally to interpret <>| as in a password) must be enclosed in " to be interpreted as one argument string on which all characters are interpreted literally with the exception of % and ! if delayed expansion is enabled on parsing the command line in the batch file. It is advisable to enclose file/folder argument strings always in double quotes if there is not guaranteed that " are not needed as for %SystemRoot%\System32\xcopy.exe.

The Windows command XCOPY is specified with fully qualified file name. That improves efficiency as the Windows Command Processor does not need to search in file system for an executable/script with file name xcopy in current directory and in the directories listed separated with semicolons in value of local environment variable PATH with a file extension listed in value of local environment variable PATHEXT. The usage of the fully qualified file name makes this command line also fail safe because of no xcopy.cmd in current directory or a corrupted PATH not containing anymore %SystemRoot%\System32 can cause anymore a different execution of this command line than the expected one.

There is no backslash between %~dp0 and Folder1 in source argument string because of %~dp0 always expands to full path of the directory containing the batch file ending with \. So the resulting argument string of %~dp0Folder1 is 100% valid which must not be modified in any way by the Windows file I/O functions before passing the directory argument string to the file system.

There can be appended to source argument string \*, i.e. use "%~dp0Folder1\*" as first argument string for XCOPY, but copying all files in the specified source directory, and with option /S also all files in non-empty directories, is the default.

The destination argument string ends with a backslash. That makes it 100% clear for XCOPY that the destination is a directory. That backslash at end makes it unnecessary to use option /I. XCOPY creates always the entire directory tree to the destination directory. The destination is definitely a directory with destination argument string ending with a backslash.

The usage of XCOPY is deprecated since Windows Vista and Windows Server 2003 on which ROBOCOPY is installed by default in the Windows system directory. ROBOCOPY is a more robust and more powerful file/directory copying/moving program. Run in a command prompt window robocopy /? for output of its usage help or read the Microsoft documentation for robocopy.

The same directory copying task can be done with ROBOCOPY with:

%SystemRoot%\System32\robocopy.exe "%~dp0Folder1" "%ProgramFiles(x86)%\Test\Folder2" /S /NDL /NFL /NJH /NJS /R:2 /W:3 >nul

ROBOCOPY creates also the entire destination directory tree if that is necessary.

It is important to mention that robocopy.exe uses a special argument string parsing like reg.exe. A \ left to one more \ or a " is interpreted as escape character for the following backslash or double quote character. For that reason no argument string of ROBOCOPY enclosed in " should end with a single backslash as that would be interpreted as escape for the double quote and so everything up to next " is interpreted as one argument string although a directory path cannot contain the character " at all.

Valid ROBOCOPY command lines are regarding to source and destination:

%SystemRoot%\System32\robocopy.exe "%~dp0Folder1" "%ProgramFiles(x86)%\Test\Folder2" /S
%SystemRoot%\System32\robocopy.exe "%~dp0Folder1\\" "%ProgramFiles(x86)%\Test\Folder2\\" /S

Invalid ROBOCOPY command lines are regarding to source and destination:

%SystemRoot%\System32\robocopy.exe %~dp0Folder1 %ProgramFiles(x86)%\Test\Folder2 /S
%SystemRoot%\System32\robocopy.exe "%~dp0Folder1\" "%ProgramFiles(x86)%\Test\Folder2\" /S

The first line is invalid as %~dp0 could expand to a string containing a space or one of these characters &()[]{}^=;!'+,`~ and %ProgramFiles(x86)% expands by default to a string containing a space and both round brackets and therefore source and destination path must be enclosed in double quotes.

If the root directory of a drive is the source or destination on which it is necessary that the directory path ends with a backslash, it is best not enclosing the root directory path like C:\ or D:\ in double quotes.

AbeZ
  • 3
  • 2
Mofi
  • 46,139
  • 17
  • 80
  • 143