Update: A standalone command --- no script file dependency.
Copy, paste, and execute this code in a PowerShell console for an instant "proof-of-concept" demo:
$msg = @'
$Args[0] : {0}
$Args[1] : {1}
'@
&{echo ($msg -f $Args[0], $Args[1])} --% I'm an unquoted string with an apostrophe and spaces.
Output:
PS C:\> $msg = @'
>> $Args[0] : {0}
>> $Args[1] : {1}
>> '@
>> &{echo ($msg -f $Args[0], $Args[1])} --% I'm an unqoted string with an apostroohe and spaces.
$Args[0] : --%
$Args[1] : I'm an unqoted string with an apostroohe and spaces.
PS C:\>
- (interesting that
--%
is both functional and captured as an argument)
The "magic bullet" is the Stop parsing token: --%
. Per the documentation:
The stop-parsing symbol (--%), introduced in PowerShell 3.0, directs
PowerShell to refrain from interpreting input as PowerShell commands or
expressions.
...
When it encounters a stop-parsing symbol, PowerShell treats the remaining
characters in the line as a literal.
Though intended for use with arguments to executables, it also works with arguments to script blocks as the above code demonstrates.
So to execute Set-Location
with an unquoted path, the syntax is:
&{Set-Location -LiteralPath $Args[1]} --% <unquoted path>
And thus our registry command becomes:
powershell.exe -NoExit -Command &{Set-Location -LiteralPath $Args[1]} --%% %V
- Note the doubled percent sign (
%%
) is needed to produce the literal %
symbol in the resulting command.
To modify the command machine-wide, edit the registry directly. The relevant keys are:
HKLM\SOFTWARE\Classes\Directory\Background\Shell\PowerShell\Command
HKLM\SOFTWARE\Classes\Directory\Shell\PowerShell\Command
Take ownership of the key and assign yourself full control.
Edit the (Default)
value, changing it to:
powershell.exe -NoExit -Command &{Set-Location -LiteralPath $Args[1]} --%% %V
Remove the Full Control
permission you added for your user.
Change owner back to TrustedInstaller
by speecifying NT Service\TrustedInstaller
as the username in the steps you followed to take ownership.
To modify the command on a per-user basis, simply create and edit the registry keys:
HKCU\Softwar\Classes\Directory\Background\Shell\PowerShell\Command
HKCU\Software\Classes\Directory\Shell\PowerShell\Command
Changing the value of (Default)
to:
powershell.exe -NoExit -Command &{Set-Location -LiteralPath $Args[1]} --%% %V
or just copy, pasee, and execute the follwoing:
'Background\','' | ForEach{
$splat = @{
'Path' = ('HKCU:\Software\Classes\Directory\{0}Shell\PowerShell\Command' -f $_)
'Value' = 'powershell.exe -NoExit -Command &{Set-Location -LiteralPath $Args[1]} --%% %V'
}
New-Item @splat -Force
}
Original Reply
For a 5.1 workaround, I can't think of a way with just a PowerShell command line, but calling a one-line script seems to do the trick:
(Code edit/improvement per @mklement0's comment)
### OpenHere.ps1
Set-Location -LiteralPath $Args[0]
### (HKCU|HKLM)\Software\Classes\Direcory[\Background]\Shell\PowerShell\Command
###
###powershell.exe -noexit -File "C:\Path\to\OpenHere.ps1" "%V"
###
- Save as "OpenHere.ps1" to an appropriate location
- You can then modify either:
HKLM\SOFTWARE\Classes\Directory\Shell\PowerShell\Command
if you have Admin access and are comfortable dealing with ownership and permissions.
Otherwise, you can create per-user entries under:
HKCU\Software\Classes\Directory\Shell\PowerShell\Command
The syntax for the registry command line is:
powershell.exe -noexit -File "C:\Path\to\OpenHere.ps1" "%V"
Here's a "self-installing" version of the above code that will create the context menu entries under HKCU
(per-user mod).
- Save the following as a
.ps1
file in the directory where it will reside.
- Run the script from a PowerShell console with no arguments. The code uses the current Path\FileName of the
.ps1
file in the command line it creates.
### OpenHere.ps1
If ($Args) { ### Launched from context menu
Set-Location -LiteralPath $Args[0]
} Else { ### Create HKCU registry entries
'Background\','' | ForEach {
$splat = @{
'Path' = ('HKCU:\Software\Classes\Directory\{0}Shell\PowerShell\Command' -f $_)
'Value' = ('powershell.exe -NoExit -File "{0}" "%V"' -f $PSCommandPath)
'Type' = 'ExpandString'
}
New-Item @splat -Force
}
}
### The "(Default)" value is created as a REG_EXPAND_SZ to allow for subsequent
### editing that can include environmental variables