14

I am calling PowerShell from within a Java application (through the Windows command prompt) to read various file attributes.

For example,

powershell (Get-Item 'C:\Users\erlpm\Desktop\Temp\s p a c e s.txt').creationTime

I am enclosing the file path in single quotes, because it may contain spaces. It worked fine, until I encountered a file path containing square brackets, which seem to be interpreted as a wildcard character. I managed to solve it by adding the -literalPath parameter:

powershell (Get-Item -literalpath 'C:\Users\erlpm\Desktop\Temp\brackets[].txt').creationTime

So far, so good... But file paths may also contain single quotes, dollar signs, ampersands, etc., and all these characters seem to have a specific function in PowerShell for which the -literalPath parameter does not seem to work.

I tried enclosing the path with double quotes or escaping with the `character, but that did not solve my problem either :-(

Any suggestions on how to pass a file path to PowerShell which may contain spaces, single quotes, square brackets, ampersands, dollar signs, etc.?

Someone here already showed me how to get it working from within PowerShell, but somehow the answer has been removed(?).

Anyway, I did create a file called $ & ' [].txt. This works form within PowerShell (needed to escape the &):

Get-Item -LiteralPath "C:\Users\erlpm\Desktop\Temp\`$ & ' [].txt"


    Directory: C:\Users\erlpm\Desktop\Temp


Mode                LastWriteTime     Length Name
----                -------------     ------ ----
-a---        2012-08-23     14:22          0 $ & ' [].txt

But when I execute the same PowerShell command through the Windows command prompt, ...

powershell Get-Item -LiteralPath "C:\Users\erlpm\Desktop\Temp\`$ & ' [].txt"

... I get this error:

Ampersand not allowed. The & operator is reserved for future use; use "&" to pass ampersand as a string.
At line:1 char:55 \

  • Get-Item -LiteralPath C:\Users\erlpm\Desktop\Temp`$ & <<<< ' [].txt \
    • CategoryInfo : ParserError: (:) [], ParentContainsErrorRecordException \
    • FullyQualifiedErrorId : AmpersandNotAllowed

Using the -command parameter and putting the PowerShell command between {} gives exactly the same error message ...

powershell -command {Get-Item -LiteralPath "C:\Users\erlpm\Desktop\Temp\`$ & ' [].txt"}
4
  • Could you provide a few examples of paths which are not working, and the exact error you get? You have only provided working paths so far, so it's hard to tell where the problem is.
    – latkin
    Commented Aug 23, 2012 at 14:21
  • I updated my question and added some working and non-working examples. As you can see, I can get it to work from within the Powershell prompt, but not by executng powershell from the Windows command prompt. Commented Aug 23, 2012 at 15:11
  • I reproduced your issue by creating a file named "$ * ' [].txt". Then, from a powershell prompt, I typed get-item <tab> and powershell completed the filename for me, but I can't paste the completed filename in here because markdown eats all the special characters. Give it a try and see if that helps.
    – joXn
    Commented Feb 5, 2013 at 22:54
  • For reference, here are the PowerShell wildcard docs: learn.microsoft.com/en-us/powershell/module/… Commented Feb 4, 2019 at 15:21

3 Answers 3

10

This is really a question about cmd.exe string escaping, then. Combining cmd and PowerShell string escaping is a total nightmare. After quite a few attempts, I got your specific example to work:

powershell.exe -nologo -noprofile -command ^&{ dir -LiteralPath ^"""".\`$ & ' [].txt"" }

    Directory: C:\Users\latkin
Mode                LastWriteTime     Length Name
----                -------------     ------ ----
-a---         8/23/2012   8:46 AM          0 $ & ' [].txt

Totally intuitive, right?

You can spend 15 minutes wrestling with escape sequences every time, or you can try some other approaches.

Put the file name in a text file, and read it out of there.

powershell.exe -command "&{dir -literal (gc .\filename.txt)  }"

or

Use a script

powershell.exe -file .\ProcessFiles.ps1  # In processfiles.ps1 you are in fully powershell environment, so escaping is easier

or

Use -EncodedCommand

See powershell.exe -? (last item shown) or http://dmitrysotnikov.wordpress.com/2011/07/06/passing-parameters-to-encodedcommand/

1
  • As you suggested, I gave up trying to escape the special characters and wrote the filepath to a temporary file. This seems to work fine ! Commented Aug 24, 2012 at 13:09
7

If you can write the path to a temporary .txt file, the following works OK:

(Get-Item -literalpath (gc 'C:\Temp\path.txt')).creationTime

The file @ C:\Temp\path.txt contains the path with special characters in it, other than this I think you would have to escape each special character on a per path basis.

In addition to the hack above, it appears PowerShell V3 may help out here with the addition of a new 'magic parameter' language feature. Specifically, see the section headed 'Easier Reuse of Command Lines From Cmd.exe' here and because I hate link-rot, here it is, shamelessly reproduced below:

Easier Reuse of Command Lines From Cmd.exe

The web is full of command lines written for Cmd.exe. These commands lines work often enough in PowerShell, but when they include certain characters, e.g. a semicolon (;) a dollar sign ($), or curly braces, you have to make some changes, probably adding some quotes. This seemed to be the source of many minor headaches.

To help address this scenario, we added a new way to “escape” the parsing of command lines. If you use a magic parameter --%, we stop our normal parsing of your command line and switch to something much simpler. We don’t match quotes. We don’t stop at semicolon. We don’t expand PowerShell variables. We do expand environment variables if you use Cmd.exe syntax (e.g. %TEMP%). Other than that, the arguments up to the end of the line (or pipe, if you are piping) are passed as is. Here is an example:

 echoargs.exe --% %USERNAME%,this=$something{weird}
 Arg 0 is <jason,this=$something{weird}>
2
  • Still helping after 12 years. Using -LiteralPath solved my problem with file names containing square brackets. I didn't need to write my file paths to a file.
    – dougp
    Commented May 3 at 23:07
  • Naturally, now that I read learn.microsoft.com/en-us/powershell/module/…, I realize understanding wildcards in file paths would have also led me there. I have a long way to go to know enough PowerShell to code without SO. (Although, I did try escaping the square brackets with a backtick and that failed.)
    – dougp
    Commented May 3 at 23:17
7

This thread is 5 years old so maybe times have changed, but the current answer that worked for me was to use the backtick (`) symbol to escape the special character.

In my case, it was a dollar sign in a directory path that was failing. By putting a backtick before the dollar sign, everything worked.

Before:

$dir = "C:\folder$name\dir"  # failed

After:

$dir = "C:\folder`$name\dir" # succeeded
0

Not the answer you're looking for? Browse other questions tagged or ask your own question.