How to escape characters inside of a parameter in Powershell? - powershell

This is a simplified version of my function:
function DetectLocalUser($localGroup, $members)
{
$result = net localgroup "$localGroup"
#$members= $members.Replace("\","\\")
if ($result -match $members)
{
return $true
}
else
{
return $false
}
}
To invoke the function I use this example (Typical values I am going to receive):
DETECTLocalUser "test" "iis apppool\userapi"
The parameters are not controlled by me. If they were I would escape directly the second parameter "iis apppool\\userapi"
On execution I have a problem with the \ in the parameter. The exact error is:
parsing "iis apppool\icisapi" - Unrecognized escape sequence \i. At
C:\k\a.ps1:6 char:9
+ if ($result -match $members)
+ ~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : OperationStopped: (:) [], ArgumentException
+ FullyQualifiedErrorId : System.ArgumentException
I found a workaround by adding #$members= $members.Replace("\","\\") fixes the problem but I am not sure if is the best option.
Is my workaroud acceptable or is there a better way of escaping $members parameter?

[RegEx]::Escape($members)
That will ensure that characters in strings get interpreted as literals and not as part of the RegEx.
To explain further, the -match operator is doing a regular expression match, so the string you pass to it is interpreted as a regular expression.
Backslash happens to be the escape character in a regular expression, so that's where your issue is. Using [RegEx]::Escape() ensures that other characters won't be interpreted, such as [,],.,+,(,),^,$,?,*, etc.

Related

Check if powershell string contains an asterisk

I have a string : $row.TableName_Org[$i]
The value it contains is
This is a happy little asterisk: '*'
Now I want to do an IF based on the fact that the string contains an asterisk.
if($row.TableName_Org[$i] -Match "*") {
//Do Something
}
However gives me this error:
"*" - Kwantiteitsmeter {x,y} wordt door niets voorafgegaan. parseren
At C:\Users\hveijer\VS Code Repos\migratie-uitwissel\ReadData.ps1:33 char:4
+ $row.TableName_Org[$i] -match "*"
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : OperationStopped: (:) [], ArgumentException
+ FullyQualifiedErrorId : System.ArgumentException
As you've found out yourself, the escape character in PowerShells wildcard/glob mechanism is ` (backtick):
'string with * in it' -like '`*'
... but the backtick is also the escape character for expandable (double-quoted) strings, leading to situations with awkward double escaping, like:
$pattern = "${prefix}``*"
For this reason, I prefer to let PowerShell escape my search terms for me instead of doing it manually:
[wildcardpattern]::Escape("${prefix}*")
Turns out I had to escape the * using ` (slash backtick)

PowerShell split on "(" throws error: "Not enough )'s."

I've come across a weird "bug" or foible in PowerShell, trying to split a string on "(". Can anyone tell me what's going on, and if there is an easy work-around?
Here's the code:
$description = 'Get-ParsedData($Data)'
$description -split "("
Result:
parsing "(" - Not enough )'s.
At line:1 char:1
+ $description -split "("
+ ~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : OperationStopped: (:) [], ArgumentException
+ FullyQualifiedErrorId : System.ArgumentException
I've tried using '(' as well as "(", and also
$description -split [char]0x0028
All result in the same error message: parsing "(" - Not enough )'s.
In the end I got around the problem with the following code, which works:
$description.SubString(0, $description.IndexOf('('))
However, I'm still curious as to why I was getting the original error and whether there is a simple work-around.
-split is a regular expression operator, and ( needs to be escaped (\():
$description -split "\("
The error message "Not enough )'s" might seem strange at first, but the reason ( needs to be escaped in regular expressions is that parentheses are used for grouping constructs:
PS C:\> 'abc' -split '(b)'
a
b
c
In the example above, we split on b, but "capture" it's value by enclosing it in ().
So when you pass the string "(" as a pattern, the regex engine sees it and goes "that ( is the start of a capture group", and since it can't find a corresponding ), it throws that error.
You can also use the [regex]::Escape() method to automatically escape any literal character in a regex pattern:
$splitPattern = [regex]::Escape("(")
$description -split $splitPattern
Alternatively, use the String.Split() method which only does simple substring replacement (and ( therefore doesn't need escaping):
$description.Split("(")

PowerShell if -like error

Not sure what's wrong with this script
$SSODelete= "Delete"
$SSOfiles = "SSo.xml"
$channlename = "INC8-Patch"
write-host $channlename
if ($channelname -like *INC8*){
$SSOarg = "$SSODelete $SSOfiles"
Write-Host $SSOarg
}
It throws following error:
You must provide a value expression following the '*' operator.
At line:5 char:25
+ if ($channelname -like *INC8*){
+ ~~~~~
Unexpected token 'INC8*' in expression or statement.
Tried using "*INC8*" and '*INC8' but it then it does not qualify if statement.
Adding screenshot for script and it's results
Simple Script and results
The PowerShell -like operator should be used with the matching string quoted, e.g., $variable -like "*pattern*". -like accepts the simple wildcard (*) only; you can compare against regular expressions (regexps) by using -match. See Get-Help about_Comparison_Operators.
Thanks , it was due to variable name i was comparing ... i need to be more cautious

powershell search function with regular expression

the text file content is:
In this script, we have the following variables:
$input_path to hold the path to the input file we want to parse
$output_file to hold the path to the file we want the results to be stored in
$regex to hold the regular expression pattern to be used when the strings are being matched.
The select-string cmdlet contains various parameters as follows:
-Path which takes as input the full path to the input file
-Pattern which takes as input the regular expression used in the matching process
AllMatches which searches for more than one match (without this parameter it would stop after the first match is found) and is piped to $.Matches and then $_.Value which represent using the current values of all the matches.
Code:
$replace_file=#{}
$replace_text_file_path="EMS_checksystem_script\replace.txt"
$replace_file= gc $replace_text_file_path
$result=0
$valr=read-host "please enter the key word"
for($i=0;$i -lt$file_context.length;$i++)
{
$result=$replace_file[$i] -match $valr
if( $result -eq 1)
{
$replace_file[$i]
}
}
Result:
key word: *pression
Bad argument to operator '-match': parsing "*pression" - Quantifier {x,y} following nothing..
At line:11 char:37
+ $result=$replace_file[$i] -match <<<< '*pression'
+ CategoryInfo : InvalidOperation: (:) [], RuntimeException
+ FullyQualifiedErrorId : BadOperatorArgument
key word: pression*
key word: press*on
NO result
How can use the press*on and *pression keywords to search?
Read up on regex. You can test regex here > http://www.regexr.com/
Your keyword is wrong, use "." to match any character and "*" to match any number of the previous character.
PS C:\>'expression' -match ".*pression"
PS C:\>True

replace exception in powershell

I'm a beginner in powershell and know C# pretty well. I have this command http://www.f2ko.de/programs.php?lang=en&pid=cmd that downloads stuff. I'm writing this script to download all the sgf go games from this url http://www.gogameworld.com/gophp/pg_samplegames.php, and was trying to write a powershell script to do it for me. So I wrote a script:
Get-Content test.txt|
ForEach-Object
{
if($_ -eq "=`"javascript:viewdemogame(`'*.sgf`')`" tit")
{
$filename = $_ -replace '=`"javascript:viewdemogame(`''
$filename = $filename -replace '`')`" tit'
&"(Path)/download.exe" ("http://www.gogameworld.com/webclient/qipu/" + $filename)
}
}
However, when I run the script, I keep getting this error:
Unexpected token '`'' in expression or statement.
At (PATH)\test.ps1:7 char:37
+ $filename = $filename -replace '`' <<<< )'
+ CategoryInfo : ParserError: (`':String) [], ParentContainsErrorRecordException
+ FullyQualifiedErrorId : UnexpectedToken
I've looked at the script lots of times and still can't figure out whats wrong. Thanks.
Try this, read the content of the file as one string and then use the Regex.Matches to get all occurrences of the text contained in the parenthesis:
$content = Get-Content test.txt | Out-String
$baseUrl = 'http://www.gogameworld.com/webclient/qipu/'
[regex]::matches($content,"javascript:viewdemogame\('([^\']+)'\)") | Foreach-Object{
$url = '{0}{1}' -f $baseUrl,$_.Groups[1].Value
& "(Path)/download.exe" $url
}
here's an explanation of the regex pattern (created with RegexBuddy):
javascript:viewdemogame\('([^\']+)'\)
Match the characters “javascript:viewdemogame” literally «javascript:viewdemogame»
Match the character “(” literally «\(»
Match the character “'” literally «'»
Match the regular expression below and capture its match into backreference number 1 «([^\']+)»
Match any character that is NOT a ' character «[^\']+»
Between one and unlimited times, as many times as possible, giving back as needed (greedy) «+»
Match the character “'” literally «'»
Match the character “)” literally «\)»
Match the character “"” literally «"»
'{0}{1}' is used with the -f operator to create a string. {0} maps to the first value on the right hand side of the operator (e.g $baseUrl) and {1} is mapped to the second value. Under the hood, PowerShell is suing the .NET String.Format method. You can read more about it here: http://devcentral.f5.com/weblogs/Joe/archive/2008/12/19/powershell-abcs---f-is-for-format-operator.aspx
'')" tit'
The -replace operator takes 2 arguments, comma separated. The first is a regular expression that matches what you want replaced. The second is the string you want to relace that with. You appear to be missing the second argument.