Share

PowerShell, square brackets and apostrophes

This is a follow-up post to the one about square brackets and Unicode in PowerShell.

I discovered recently that there is another PITA character that interferes with my workaround — it’s a single quote, or apostrophe.

It’s fine to start PowerShell inside a folder with an apostrophe in its name, but we have to escape it when using inside Powershell commands or passing into PowerShell from anywhere else.

Below are my experiments to find the best way to open PowerShell in any folder… if ever possible.


I’m using PowerShell 6 here in my examples. Just to make sure my results are up to date with current development on GitHub and could be referenced there if needed.

When running PowerShell from Cmd, we can do string replacement in variables (explained here and there). But only one template a time — escaping all problematic characters can’t be fit into single expression.

Console logs

[brackets] folder:

click to showhide
c:\ps_test\[brackets]>pwsh
PowerShell v6.0.0-rc.2
Copyright (c) Microsoft Corporation. All rights reserved.

https://aka.ms/pscore6-docs
Type 'help' to get help.

PS C:\Program Files\PowerShell\6.0.0-rc.2> exit

c:\ps_test\[brackets]>pwsh -NoExit -Command cd -LiteralPath %cd%
PS C:\ps_test\[brackets]> exit

c:\ps_test\[brackets]>pwsh -NoExit -Command cd -LiteralPath %cd:'=`'%
PS C:\ps_test\[brackets]> exit

c:\ps_test\[brackets]>pwsh -NoExit -Command cd -LiteralPath '%cd:'=`'%'
PS C:\ps_test\[brackets]> exit

c:\ps_test\[brackets]>
click to showhide

with spaces folder:

click to showhide
c:\ps_test\with spaces>pwsh
PowerShell v6.0.0-rc.2
Copyright (c) Microsoft Corporation. All rights reserved.

https://aka.ms/pscore6-docs
Type 'help' to get help.

PS C:\ps_test\with spaces> exit

c:\ps_test\with spaces>pwsh -NoExit -Command cd -LiteralPath %cd%
Set-Location : A positional parameter cannot be found that accepts argument 'spaces'.
At line:1 char:1
+ cd -LiteralPath c:\ps_test\with spaces
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo          : InvalidArgument: (:) [Set-Location], ParameterBindingException
+ FullyQualifiedErrorId : PositionalParameterNotFound,Microsoft.PowerShell.Commands.SetLocationCommand

PS C:\ps_test\with spaces> exit

c:\ps_test\with spaces>pwsh -NoExit -Command cd -LiteralPath '%cd%'
PS C:\ps_test\with spaces> exit

c:\ps_test\with spaces>pwsh -NoExit -Command cd -LiteralPath %cd:'=`'%
Set-Location : A positional parameter cannot be found that accepts argument 'spaces'.
At line:1 char:1
+ cd -LiteralPath c:\ps_test\with spaces
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo          : InvalidArgument: (:) [Set-Location], ParameterBindingException
+ FullyQualifiedErrorId : PositionalParameterNotFound,Microsoft.PowerShell.Commands.SetLocationCommand

PS C:\ps_test\with spaces> exit

c:\ps_test\with spaces>pwsh -NoExit -Command cd -LiteralPath '%cd:'=`'%'
PS C:\ps_test\with spaces> exit

c:\ps_test\with spaces>
click to showhide

killy's folder:

click to showhide
c:\ps_test\killy's>pwsh
PowerShell v6.0.0-rc.2
Copyright (c) Microsoft Corporation. All rights reserved.

https://aka.ms/pscore6-docs
Type 'help' to get help.

PS C:\ps_test\killy's> exit

c:\ps_test\killy's>pwsh -NoExit -Command cd -LiteralPath %cd%
The string is missing the terminator: '.
+ CategoryInfo          : ParserError: (:) [], ParentContainsErrorRecordException
+ FullyQualifiedErrorId : TerminatorExpectedAtEndOfString

PS C:\ps_test\killy's> exit

c:\ps_test\killy's>pwsh -NoExit -Command cd -LiteralPath %cd:'=`'%
PS C:\ps_test\killy's> exit

c:\ps_test\killy's>pwsh -NoExit -Command cd -LiteralPath '%cd:'=`'%'
The string is missing the terminator: '.
+ CategoryInfo          : ParserError: (:) [], ParentContainsErrorRecordException
+ FullyQualifiedErrorId : TerminatorExpectedAtEndOfString

PS C:\ps_test\killy's> exit

c:\ps_test\killy's>
click to showhide

[killy's] folder:

click to showhide
c:\ps_test\[killy's]>pwsh
PowerShell v6.0.0-rc.2
Copyright (c) Microsoft Corporation. All rights reserved.

https://aka.ms/pscore6-docs
Type 'help' to get help.

PS C:\Program Files\PowerShell\6.0.0-rc.2> exit

c:\ps_test\[killy's]>pwsh -NoExit -Command cd -LiteralPath %cd%
The string is missing the terminator: '.
+ CategoryInfo          : ParserError: (:) [], ParentContainsErrorRecordException
+ FullyQualifiedErrorId : TerminatorExpectedAtEndOfString

PS C:\Program Files\PowerShell\6.0.0-rc.2> exit

c:\ps_test\[killy's]>pwsh -NoExit -Command cd -LiteralPath %cd:'=`'%
PS C:\ps_test\[killy's]> exit

c:\ps_test\[killy's]>pwsh -NoExit -Command cd -LiteralPath '%cd:'=`'%'
The string is missing the terminator: '.
+ CategoryInfo          : ParserError: (:) [], ParentContainsErrorRecordException
+ FullyQualifiedErrorId : TerminatorExpectedAtEndOfString

PS C:\Program Files\PowerShell\6.0.0-rc.2> exit

c:\ps_test\[killy's]>
click to showhide

[killy's spaces] folder:

click to showhide
c:\ps_test\[killy's spaces]>pwsh
PowerShell v6.0.0-rc.2
Copyright (c) Microsoft Corporation. All rights reserved.

https://aka.ms/pscore6-docs
Type 'help' to get help.

PS C:\Program Files\PowerShell\6.0.0-rc.2> exit

c:\ps_test\[killy's spaces]>pwsh -NoExit -Command cd -LiteralPath %cd%
The string is missing the terminator: '.
+ CategoryInfo          : ParserError: (:) [], ParentContainsErrorRecordException
+ FullyQualifiedErrorId : TerminatorExpectedAtEndOfString

PS C:\Program Files\PowerShell\6.0.0-rc.2> exit

c:\ps_test\[killy's spaces]>pwsh -NoExit -Command cd -LiteralPath '%cd%'
The string is missing the terminator: '.
+ CategoryInfo          : ParserError: (:) [], ParentContainsErrorRecordException
+ FullyQualifiedErrorId : TerminatorExpectedAtEndOfString

PS C:\Program Files\PowerShell\6.0.0-rc.2> exit

c:\ps_test\[killy's spaces]>pwsh -NoExit -Command cd -LiteralPath %cd:'=`'%
Set-Location : A positional parameter cannot be found that accepts argument 'spaces]'.
At line:1 char:1
+ cd -LiteralPath c:\ps_test\[killy`'s spaces]
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo          : InvalidArgument: (:) [Set-Location], ParameterBindingException
+ FullyQualifiedErrorId : PositionalParameterNotFound,Microsoft.PowerShell.Commands.SetLocationCommand

PS C:\Program Files\PowerShell\6.0.0-rc.2> exit

c:\ps_test\[killy's spaces]>pwsh -NoExit -Command cd -LiteralPath '%cd:'=`'%'
The string is missing the terminator: '.
+ CategoryInfo          : ParserError: (:) [], ParentContainsErrorRecordException
+ FullyQualifiedErrorId : TerminatorExpectedAtEndOfString

PS C:\Program Files\PowerShell\6.0.0-rc.2> exit

c:\ps_test\[killy's spaces]>
click to showhide

Results

Command [brackets] with spaces killy’s [killy’s] [killy’s spaces]
1 pwsh ✔️ ✔️
2 pwsh -NoExit -Command cd -LiteralPath %cd% ✔️ ⚠️ ⚠️ ⚠️❌ ⚠️❌
3 pwsh -NoExit -Command cd -LiteralPath '%cd%' ✔️ ✔️ ⚠️ ⚠️❌ ⚠️❌
4 pwsh -NoExit -Command cd -LiteralPath %cd:'=`'% ✔️ ⚠️ ✔️ ✔️ ⚠️❌
5 pwsh -NoExit -Command cd -LiteralPath '%cd:'=`'%' ✔️ ✔️ ⚠️ ⚠️❌ ⚠️❌
  • ❌ — PowerShell opened in default location
  • ⚠️ — error is shown
  • ✔️ — PowerShell opened in proper folder, without errors

Fourth option provides best compatibility overall, but still unable to cope with most difficult case. And the warning in a basic case of paths with spaces is undesireable too.

I’ve also tested few other options but didn’t include here because produced results were no different from some of the listed ones — double quotes were no different from no quotes, multiple backticks were no different from single backtick.

Registry, QTTabBar

Unfortunately, for context menu commands there is a different set of variables available, and replacement cannot be used. So it leaves us with only options 1 and 3. And even more than that, third option is not working with apostrophes there. What’s left is the choice — either you have apostrophes (system default) or square brackets (workaround with LiteralPath, as in previous post).

QTTabBar’s application launcer is pretty much the same story — it has own set of variables and no ways to escape strings.

Some additional application will be required to properly escape the path and run PowerShell, unless this issue will be addressed in PowerShell itself. Currently there is one related issue opened on GitHub: #5752.

comments powered by Disqus