Escaping dollar signs in PowerShell path is not working

You can actually just use a tick mark to escape the $ like so:

`$

Example:

$number = 5
Write-Host "`$${number}"
# Output: $5

You used double quotes with a single backtick. This is an incorrect combination. In fact, I am not sure that a single backtick alone is sufficient in any case. Your successful options to escape the dollar sign ($) in PowerShell are to use double quotes with a backslash-backtick combination ("\`$find"), or instead to use single quotes with a simple backslash ('\$find'). [However, note the exception at the end about function call parameters.] See below for examples.

Also, for those unfamiliar with the distinction, it is important not to confuse the backtick character (`) with the single-quotation character (') in these escapes.

[SUCCESS] Double quotes as container with backslash-backtick as escape:

PS C:\Temp> 'What is $old?' | ForEach-Object {$_ -replace "\`$old", "(New)"}
What is (New)?
PS C:\Temp>

[FAIL] Double quotes as container with backslash-apostrophe as escape:

PS C:\Temp> 'What is $old?' | ForEach-Object {$_ -replace "\'$old", "(New)"}
What is $old?
PS C:\Temp>

[SUCCESS] Single quotes as container with simple backslash as escape:

PS C:\Temp> 'What is $old?' | ForEach-Object {$_ -replace '\$old', "(New)"}
What is (New)?
PS C:\Temp>

[FAIL] Single quotes as container with backslash-backtick as escape:

PS C:\Temp> 'What is $old?' | ForEach-Object {$_ -replace '\`$old', "(New)"}
What is $old?
PS C:\Temp>

Overall, the easiest option may be to use single quotes as the container and a single backslash as the escape: '\$old'

Update: As if the above were not confusing enough, when you use a function call instead of a command, single quotes are needed without an escape. Trying to use an escape on the function call parameter will not work:

[FAIL] Using an escape in a function parameter:

PS C:\Temp> 'What is $old?' | ForEach-Object {$_.ToString().Replace('\$old', "(New)");}
What is $old?
PS C:\Temp>

[SUCCESS] Using plain single quotes without an escape in a function parameter:

PS C:\Temp> 'What is $old?' | ForEach-Object {$_.ToString().Replace('$old', "(New)");}
What is (New)?
PS C:\Temp>

In my case I needed to escape some $'s used in a string but not others that are variables.

For example, my SSRS instance name has a $ sign:

[ReportServer$SSRS]

To escape the $ sign I use single quotes. Otherwise I use the -join statement to concatenate variables with the strings containing actual $ signs.

 $sql = -join('ALTER DATABASE [ReportServer$', $instanceName,'TempDB]
  SET SINGLE_USER WITH ROLLBACK IMMEDIATE;
  GO

  USE [master]
  RESTORE DATABASE [ReportServer$', $instanceName,'TempDB] FROM  DISK = N''C:\temp\ReportServerTempDB.BAK'' WITH  FILE = 1,
    MOVE N''ReportServerTempDB'' TO N''', $sqlDataDrive + "\data_" + $instanceName, '\ReportServer$', $instanceName,'TempDB.mdf'', 
    MOVE N''ReportServerTempDB_log'' TO N''', $sqlLogDrive + "\log_" + $instanceName, '\ReportServer$', $instanceName,'_TempDBlog.LDF'',  NOUNLOAD,  REPLACE, RECOVERY,  STATS = 5
  GO

  ALTER DATABASE [ReportServer$', $instanceName,'TempDB]
  SET MULTI_USER;
  GO
  ')

Instead of messing around with escaping dollar signs, use single quotes ' instead of double quotes ". It prevents PowerShell expanding $ into a variable. Like so,

$p = "C:\temp\Share\ISO$OEM$"
# Output
C:\temp\Share\ISO$


$p = 'C:\temp\Share\ISO$OEM$'
# Output
C:\temp\Share\ISO$OEM$

If you need to create a path by using variables, consider using Join-Path. Like so,

$s = "Share"
join-path "C:\temp\$s" '\ISO$OEM$' 
# Output
C:\temp\Share\ISO$OEM$

Tags:

Powershell