Powershell escape for variables that contain passwords - powershell

So I am using a variable that contains a password and just recently found out that some of the passwords are containing special characters. I have no control over what the password is so I have to deal with whatever I am getting. I know the back tick '`' character is what is used to escape characters. The whole reason for this post is that I am finding passwords is text files and replacing the found password with a pattern of 'xxxxxxxxx'.
Currently the code I am using is this:
$pass = "DR$123asd##!"
Because the $pass variable contains the '$' character the $123asd is seen as a variable that has no value
$pass
so all you get is:
DR##!
If I change the pass variable like this
$pass = 'DR$123asd##!'
$pass
DR$123asd##!
Then the '$' character is ignored and the string is complete, but If I run the code:
$output | foreach-object { $_ -replace "$pass", 'xxxxxxxx' }
This is my password DR$123asd##!, It is a great password!
The password doesn't get replaced and I'm, not sure why.

-replace is a regular expression operator, and the $ sigil is indeed a special character in regex.
You can escape all regex meta-characters in a literal string with [regex]::Escape():
$output | foreach-object { $_ -replace [regex]::Escape("$pass"), 'xxxxxxxx' }

Related

Slack block markdown syntax not working in hashtable

I'm generating a Slack message using a hashtable in Powershell.
Here is how the hashtable is generated:
$serviceitems = foreach ($r in $rows) {
#{
type = 'section'
text = #{
type = 'mrkdwn'
text = "*{0}*\n{1:C2}" -f $r[1], $r[0]
}
}
#{
type = 'divider'
}
}
The messsages show up in Slack but the \n prints out instead of going to a new line like it should. The two * make the text bold as intended. I tried adding a backtick to before \n and also tried adding an extra \. Both made no change.
\ has no special meaning in PowerShell strings.
PowerShell uses ` (the so-called backtick) as the escape character, so you need escape sequence `n inside an expandable (double-quoted) string ("...") in order to embed an actual newline (LF character) in the strings.
Simple example:
PS> "line 1`nline 2" | ForEach-Object { "[$_]" }
[line 1
line 2]
PowerShell happily accepts LF alone as a newline; if you do need CRLF newlines, use `r`n. To refer to the platform-native newline sequence, use [Environment]::NewLine ($([Environment]::NewLine) to use it inside "...").
See also:
The conceptual about_Special_Characters help topic.
As for what you tried:
I tried adding a backtick to before \n and also tried adding an extra \.
As implied at the top, \ should not be in the picture at all.
Trying `\n results in ` escaping the \ character, which has no effect (escaping a non-special character is ignored); in other words: "`\n" is the same as "\n" which is verbatim \n

Powershell handle variable with special character (open bracket)

I have a script where two variables are compared, it can happen that a variable contains open brackets without closing, like in the example. Then a System.ArgumentException occur: "...not enough closing brackets.."
$test1="Testtext"
$test2="Testtext (3x(2x0,25"
if(!($test1 -match $test2)){ "test"}
how can i deal with it?
-match performs regular expression matching - use Regex.Escape() to automatically escape any escapable sequence in a verbatim pattern string:
$text = 'Text with (parens)'
$pattern = '(par'
if($text -match [regex]::Escape($pattern)){
"It worked!"
}

When using -replace in powershell to replace "../" with "ref/" the dots ("..") become a wildcard [duplicate]

So I am using a variable that contains a password and just recently found out that some of the passwords are containing special characters. I have no control over what the password is so I have to deal with whatever I am getting. I know the back tick '`' character is what is used to escape characters. The whole reason for this post is that I am finding passwords is text files and replacing the found password with a pattern of 'xxxxxxxxx'.
Currently the code I am using is this:
$pass = "DR$123asd##!"
Because the $pass variable contains the '$' character the $123asd is seen as a variable that has no value
$pass
so all you get is:
DR##!
If I change the pass variable like this
$pass = 'DR$123asd##!'
$pass
DR$123asd##!
Then the '$' character is ignored and the string is complete, but If I run the code:
$output | foreach-object { $_ -replace "$pass", 'xxxxxxxx' }
This is my password DR$123asd##!, It is a great password!
The password doesn't get replaced and I'm, not sure why.
-replace is a regular expression operator, and the $ sigil is indeed a special character in regex.
You can escape all regex meta-characters in a literal string with [regex]::Escape():
$output | foreach-object { $_ -replace [regex]::Escape("$pass"), 'xxxxxxxx' }

To check for special characters in a string

I need to find special character in a string which has alphanumeric values in it.
I have tried the below code snippet but it doesn't work.
$Special_characters = ('\n|\r|\t|\a|\"|\`')
$Value = "g63evsy3swisnwhd83bs3hs9sn329hs\t"
if($Value -match $Special_characters)
{
Write-Host "Special characters are present"
}
else
{
Write-Host "special characters are absent"
}
The output says "special characters are absent" even though there are special characters at the end. How to resolve it?
$Special_Characters here is a string, so your code is searching for the whole word (\n|\r|\t|\a|\"|`) to be found in $Value, which is not found.
Instead of string, you have to use array as follows:
$Value = "g63evsy3swisnwhd83bs3hs9sn329hs\t"
$Special_Characters = #('\\n','\\r','\\t','\\a','\\"','\\`')
$Special_Characters | Foreach-Object {
if ($Value -match $_) {
"$_ is present"
} else {
"$_ is not present"
}
}
Note
You have to put double back-slash (\\) because backslash is considered as escape character in Powershell; Look here for further information about backslash in Powershell
There is a misunderstanding here.
The backslash is used to define a special character in a Regular Expression, as e.g. \t define a tab.
But this is not the case for PowerShell. To define a special character in PowerShell you need to use the backtick character (See: About Special Characters), e.g. a Tab is written as `t.
In other words, the regular expression pattern in the question is correct but the input string is not (in contrast to what the question/title suggests, there is in fact no special character in the given input string").
it should be:
"...hs9sn329hs`t" -match '\n|\r|\t|\a|\"|\`'
True
As it concerns a list of single (special) characters, you might also consider a bracket expression (rather than an OR "pipe" character) for this:
"...hs9sn329hs`t" -match '[\n\r\t\a\"\`]'
True
Visa versa: it is allowed to use special characters in a regular expression pattern using double quotes so that PowerShell will evaluate the string (but I recommend against this):
"...hs9sn329hs`t" -match "`n|`r|`t|`a|`"|``"
True
If the input string in the question is really the string you want to check upon (implying that you refer to the backslash as a special character, which formally is not), you want to check for a \t rather than a tab,. For this you will need to escape the backslashes in your regular expression to literally match the \t:
"...hs9sn329hs\t" -match '\\n|\\r|\\t|\\a|\\"|\\`'
True
Its an one-liner:
$Special_characters = '\n|\r|\t|\a|\"|\`'
$Value = "g63evsy3swisnwhd83bs3hs9sn329hs\t"
$result = #($Special_characters -split '\|' | % { $Value.Contains( $_ ) }).Contains( $true )
$result is true when a special character is found, otherwise false.
Here's all the special characters you referred to. You can try out a string by itself just to see if it works. It must be double quoted.
PS /Users/js> "`n`r`t`a`"``"
"`
You can also try out the -match operator by itself.
PS /Users/js> "`n`r`t`a`"``" -match '\n|\r|\t|\a|\"|\`'
True
About special characters: https://learn.microsoft.com/en-us/powershell/module/microsoft.powershell.core/about/about_special_characters?view=powershell-6

PowerShell Dobule Escape string with text "$__VAR__"

One of my scripts can be stripped down to the following code.
function Replace
{
[CmdletBinding()]
Param
(
[Parameter(Mandatory, Position=0)]
[string]
$LiteralPath,
[Parameter(Mandatory, Position=1)]
[string]
$Expression,
[Parameter(Mandatory, Position=2)]
[string]
$Replacement
)
Get-Content $LiteralPath | ForEach-Object {$_ -replace $Expression, $Replacement } | Set-Content $LiteralPath + ".temp"
}
An example call to the script would be
Replace ".\MyFile.txt" "^#define abc.*" "#define abc 1"
I have run into a situation where the string I need to find and replace contains both dollar signs and underscores. The dollars signs must be escaped to prevent PowerShell from expanding the variable. One string contains a dollar sign followed by an underscore. This is causing an issue because PowerShell is not expanding the variable name but then is expanding the $_ piping variable. How can I prevent PowerShell from expanding both variable name and piping token.
This is an example cal to the function with a string I need to escape.
Replace ".\MyFile.txt" "^\#\`$__LIBRARY_DIR\\prj.gpj" "`$__LIBRARY_DIR\prj.gpj"
In this example the line of text which reads #$__LIBRARY_DIR\prj.gpj is getting changed to #$__LIBRARY_DIR\prj.gpj_LIBRARY_DIR\prj.gpj. I am looking for the text to be changed to $__LIBRARY_DIR\prj.gpj
Notice the $_ is expanded which I do not want it to expand. I have tried adding more escape characters but that only causes them to appear in the file. How can the string be escaped to prevent $_ from expanding?
In powershell, if you don't want variables to expand in your string, use 'single quotes' instead if "double quotes", that saves you the trouble of escaping the $ sign with backticks.
Now in your case you have the additional challenge, that the -replace operator will also want to expand expressions that start with the $ sign in the replacement string, regardless of the types of quotes that you use.
To tell -replace that you really want to see that $ in your replacement string, you need to write $$:
'#$__LIBRARY_DIR\prj.gpj' -replace '^#\$__LIBRARY_DIR\\prj.gpj','$$__LIBRARY_DIR\prj.gpj'
Note: As others have correctly pointed out in the comments, if your task is to strip expressions from a leading #, you can do that in a more simple way:
'#$__LIBRARY_DIR\prj.gpj' -replace '^#'
Or alternatively with the good old "trim":
'#$__LIBRARY_DIR\prj.gpj'.TrimStart('#')