Check if powershell string contains an asterisk - powershell

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)

Related

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 'Invoke-Expression' command with single quotation

I am trying to invoke the following the command which contains the single quotation, but I am not able to execute and returns as an error:
$expression = $snapshot.properties.activities[1].typeProperties.parameters.rawinputlocation = '$$Text.Format(`'wasb://document.blob.co
re.windows.net/{0:yyyy}/{0:MM}/{0:dd}/DocumentActivity/raw/{{*}}.csv'`, SliceEnd)'
Invoke-Expression $expression
Error:
Invoke-Expression $expression
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
CategoryInfo : ParserError: (:) [Invoke-Expression], ParseException
FullyQualifiedErrorId : UnexpectedToken,Microsoft.PowerShell.Commands.InvokeExpressionCommand
This happens as the single quote, ', is escaped with a backtick, `.
The first one works, but the latter one is in the wrong order: the backtick is after the single quote. Consider the difference:
`'wasb://...csv'`
`'wasb://...csv`'

Converting time stamp in powershell

I get the below time stamp from API response how do i convert this to human readable text in power shell, i tried below but it is throwing error.
PS C:\Users\foobar\ddd> [datetime]::ParseExact('20100804T104413+0100','
yyyyMMdd'T'HHmmsszzz',[System.Globalization.CultureInfo]::InvariantCulture)
At line:1 char:57
+ [datetime]::ParseExact('20100804T104413+0100','yyyyMMdd'T'HHmmsszzz', ...
+ ~
Missing ')' in method call.
At line:1 char:57
+ ... me]::ParseExact('20100804T104413+0100','yyyyMMdd'T'HHmmsszzz',[System ...
+ ~~~~~~~~~~~~
Unexpected token 'T'HHmmsszzz'' in expression or statement.
At line:1 char:69
+ ... e]::ParseExact('20100804T104413+0100','yyyyMMdd'T'HHmmsszzz',[System. ...
+ ~
Missing argument in parameter list.
At line:1 char:122
+ ... dd'T'HHmmsszzz',[System.Globalization.CultureInfo]::InvariantCulture)
+ ~
Unexpected token ')' in expression or statement.
+ CategoryInfo : ParserError: (:) [], ParentContainsErrorRecordException
+ FullyQualifiedErrorId : MissingEndParenthesisInMethodCall
20170125T153341-050020170125T153344-0500
Your only problem seems to be the errant (lack of) quoting of T in your code; removing it seems to work fine:
[datetime]::ParseExact('20100804T104413+0100','yyyyMMddTHHmmsszzz', $null)
Also, since you're providing a format string in which all characters are specified individually and numerically, you needn't specify a culture (passing $null, which defaults to the current culture, will do).

when can I use methods and when command line options?

Why can I use split as a method and command line switch, but not join? How do I discover what flags (e.g. -join) an object supports?
> "a,b,c,d" -split ','
a
b
c
d
> "a,b,c,d".split(',')
a
b
c
d
> "a,b,c,d".split(',').join(';')
Method invocation failed because [System.String] does not contain a method named 'join'.
At line:1 char:1
+ "a,b,c,d".split(',').join(';')
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : InvalidOperation: (:) [], ParentContainsErrorRecordException
+ FullyQualifiedErrorId : MethodNotFound
> "a,b,c,d".split(',') -join ';'
a;b;c;d
Why can I use split as a method and command line switch, but not join?
Because String objects have a method Split(), but arrays don't have a method Join(), whereas -split and -join are operators provided by PowerShell.
The String class does have a (static) Join() method complementing Split(), though. You use it like this:
[String]::Join(',', ("a,b,c,d" -split ','))
Another thing you could do is set the output field separator ($OFS) to your delimiter character and embed your array in a string:
$OFS = ','
"$("a,b,c,d" -split ',')"
BTW, -split and Split() don't work the same way, so don't confuse them. The former uses a regular expression, the latter a character array.
PS C:\> 'a b' -split '\s+'
a
b
PS C:\> 'a b'.Split('\s+')
a b
PS C:\> 'a,b;c' -split (',', ';')
Cannot convert value ";" to type "System.Int32". Error: "Input string was not in
a correct format."
At line:1 char:9
+ 'a,b;c' -split (',', ';')
+ ~~~~~~
+ CategoryInfo : NotSpecified: (:) [], RuntimeException
+ FullyQualifiedErrorId : RuntimeException
PS C:\> 'a,b;c'.Split((',', ';'))
a
b
c
How do I discover what flags (e.g. -join) an object supports?
By reading the documentation. -join isn't a method, flag, or commandline switch. It's a PowerShell operator.
If you will do:
"String" | Get-Member
you will see that there is no Join Method available, only Split().
You can Use however the -Join Operator instead, which exist for -Split as well
In your Example:
"a,b,c,d".split(',') -join ";"
or Use the: [string]::Join() Class

How to escape characters inside of a parameter in 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.