5

I'm using a slightly modified version of the technique given in this answer to create a context menu item in Windows' file explorer that allows me to run a PowerShell script against specific folders.

The command looks like:

cmd /K PowerShell "C:\PowerShellScript\folder_script.ps1 \"%1\" | clip" 

This works fine except when the folder has an ampersand (&) in its name. Then I get the following error (target folder was named Testing & Testing):

The string starting:
At line:1 char:37
+ C:\PowerShellScript\folder_script.ps1  <<<< "E:\tmp\Testing
is missing the terminator: ".
At line:1 char:53
+ E:\Dropbox\PowerShell\namefixer.ps1 "E:\tmp\Testing  <<<<
    + CategoryInfo          : ParserError: (E:\tmp\Testing :String) [], ParentContainsErrorRecordException
    + FullyQualifiedErrorId : TerminatorExpectedAtEndOfString

Clearly something is interpreting the ampersand as a special character but I'm at a loss as how to fix this. Eliminating the ampersand from the folder name is not a viable solution for me.

A solution that doesn't involve a batch script would be preferred.

I'm using Windows 7 Enterprise (64-bit) with PowerShell 2.

3 Answers 3

3

You can use the verbatim marker of Powershell : --%, it tells Powershell that anything following it should not be interpreted.

This way, your command would become :

cmd /K PowerShell "C:\PowerShellScript\folder_script.ps1 --% \"%1\" | clip" 

Unless there are double quotes in your filenames, it should be ok.

This marker is new to Powershell 3.0, so make sure you have it up to date.

2
+100

You can try to modify your PowerShell script. And change cmd line to batch file...

Your batch (runner.cmd)

set ps_arg="%~1"
@cd /d %~dp0
PowerShell "folder_script.ps1 | clip"

The second line means sets the folder that the runner.cmd file is in as the current folder so you can run the PowerShell script without full path. Makes it easier to move things around as you don't have to edit the runner.cmd file.

And access your path via the following in your script:

$value = $env:ps_arg -replace """",""

The quotes from the batch file seem t o get passed to the PowerShell script and need to be stripped off, hence the -replace """","". As double quotes are illegal in Windows filenames, this will never remove anything important.

So, the command line will be

cmd /K runner.cmd "%1"
3
  • No, ps_arg's value will not include the ampersand or anything after it.
    – Kris
    Nov 29, 2013 at 10:50
  • Try set ps_arg="%~1"
    – Maximus
    Nov 29, 2013 at 16:31
  • Yes, that will work but you'll wind up with a string containing the quotes in the ps script. Need to remove them before using the input.
    – Kris
    Dec 5, 2013 at 12:46
0

It's a quoting issue. Replace the escaped double quotes with escaped single quotes so that your command looks like this:

cmd /K PowerShell "C:\PowerShellScript\folder_script.ps1 \'%1\' | clip"

You're using two different programs (cmd and powershell) and running three different pieces of code which can take arguments (cmd, powershell, and the .ps1 script).

cmd needs three arguments: /K Powershell and the arguments for powershell. The arguments for powershell must be one string, that's why they are inside quotes.

Powershell needs one argument: the command line you want to execute.

The .ps1 script needs on argument: the folder to run against. Powershell needs to interpret the path as a single string so it needs to be in quotes.

When you run the command, cmd launches Powershell and sends it the quoted string with the variable expanded and without the quotes or escape characters: C:\PowerShellScript\folder_script.ps1 "Testing & Testing" | clip

The quotes ensure that the script sees one argument instead of three.

(I'm not sure why the different types of quotes produced different results (they shouldn't have as far as I know), but they did when I tested so I provided the solution that worked on my system. If you can provide more details, I might be able to come up with a solution that works for you as well.)

2
  • Why would I need to escape a single quote? Using a single quote (no escaping) doesn't solve the issue (and also breaks if the folder name contains a single quote) while using an escaped single quote just fails on any input as it seems to view the backslash as part of the argument and not as an escape character.
    – Kris
    Dec 5, 2013 at 12:29
  • I'll try to explain in more depth in an edit to my answer. It worked for my test. What version of windows are you using? What version of powershell?
    – Mark
    Dec 5, 2013 at 16:40

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .