Executing PowerShell script via explorer context menu on items containing ampersands in their names

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.


Solution 1:

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.

Solution 2:

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"