I'm trying to run a simple icacls to a directory on my computer and I'm facing this error:
PS C:\Users\gguer\Documents> icacls.exe '.\My Digital Editions\'
.\My Digital Editions": The filename, directory name, or volume label syntax is incorrect.
Successfully processed 0 files; Failed processing 1 files
I'm using single quotes to escape the spaces as I was thought, so I don't know what is the issue here.
To add an explanation to your own effective workaround (not including a trailing
\in your argument):What you're seeing is a bug in Windows PowerShell with respect to how it passes arguments to external programs - this problem has been fixed in PowerShell (Core) 7+.
Behind the scenes, PowerShell (of necessity) translates your single-quoted argument containing spaces to a double-quoted form, because external CLIs can only be assumed to understand
"..."quoting.The command-line parsing rules used by most CLIs consider the sequence
\"to be an escaped"character, i.e. a"character to be considered a verbatim part of the argument rather than delimiting it.Therefore, a verbatim
\at the end of a double-quoted string must itself be escaped as\\in order to be recognized as such - this is what Windows PowerShell neglects to do:That is, Windows PowerShell translates your call as follows:
When
icacls.exeparses this command line, it sees verbatim.\My Digital Editions"(note the verbatim"at the end), as reflected in the error message.PowerShell (Core), by contrast, does perform the necessary escaping:
Workarounds:
In a literal path, simply omit a trailing
\- which won't work for a root path, however, and it also assumes that this doesn't change the meaning of the argument from the target program's perspective (it doesn't foricacls.exe).Programmatic solution:
Alternatively - which also works for root paths - manually double the trailing
\Quick-and-dirty programmatic solution, knowing that file-system paths may contain duplicated
\separators without ill-effects (however, it may affect path comparisons):A robust, cross-edition programmatic solution that doesn't modify the argument is a bit more cumbersome:
As an aside:
A related bug that affects how
"(double quotes) embedded in arguments are passed to external programs is affects PowerShell (Core) up to 7.2.x - see this answer.