1

I have a string that is returned from an api call , the string is something like

       ".\controllers\myaction   c:\test\path"

I want to use Powershell to check if the string contains c:\

How can i do this ?

I have tried the following:

# if $result is populated with the string above then i do 

if ($result.context.ToLower().Contains("c:\") -eq "True")
{
      #code here
}

how can i do this ?

5
  • 1
    How about using the match operator? about_Comparison_Operators Commented Aug 13, 2024 at 21:57
  • 1
    There is nothing wrong with your code? '.\controllers\myaction c:\test\path'.ToLower().Contains('c:\') is true. Just remove -eq "True" from the condition. Commented Aug 13, 2024 at 21:59
  • @miken32, the suggested duplicate isn't one: in the latter, -eq "False" is the cause of the problem (because it is, in fact, the same as -eq $true(!), given that any nonempty string is coerced to $true in a Boolean context). By contrast, the -eq "True" used here - while unnecessary and conceptually misleading - is not the cause of the problem and incidental to the problem at hand, the latter being that $result in actuality contains an array of strings, as explained in iRon's answer. Commented Aug 15, 2024 at 17:29
  • @mklement0 that's possible but it's hard to say without an MRE. My (admittedly of limited knowledge) advice would be to just do $result -Match "c:\\" or similar. But again, it's just guesswork without the info. Commented Aug 15, 2024 at 17:56
  • @miken32: What the actual problem here is ultimately irrelevant with respect to deciding whether the proposed duplicate is one or not: it isn't, as previously argued (the -eq "True" part is an incidental no-op here, unlike in the alleged duplicate), so I suggest retracting your close vote. As for the actual problem: That the presence of an array is the problem (which may apply to $result and/or the .context property value) is the only plausible explanation, and is also suggested by the fact that Kate accepted iRon's answer. Commented Aug 15, 2024 at 18:21

1 Answer 1

2

To complement helpful answer from Prateekshit Jaiswal with the truth about the -eq "True":

if it really concerns "a string that is returned from an api call", the extra -eq "True" is not an issue:
(although I would really recommend against adding that.)

if (".\controllers\myaction   c:\test\path".ToLower().Contains("c:\") -eq "True") {
    Write-Host 'code here'
}
code here

This is because PowerShell is a loosely typed language where the left-hand-side (LHS) of the condition dictates the comparison method. This means if the LHS is a boolean:

".\controllers\myaction   c:\test\path".ToLower().Contains("c:\") -is [Bool]
True

The RHS is type casted to a Boolean:

[Bool]"True"
True

Because both sides are $True, the condition is simply considered $True (or truthy).

So what's really playing here?

I suspect that $result.context isn't really a string but something like an array of strings:

$result = @{ context = ".\controllers\myaction", "c:\test\path" }
$result.context
.\controllers\myaction
c:\test\path

Or :

"$($result.context)"
.\controllers\myaction c:\test\path

PowerShell's member-access enumeration is a nice feature but often makes things rather confusing:

if you use the .ToLower() (string) method on a string array, this will work wonder well:

$result.context.ToLower()
.\controllers\myaction
c:\test\path

But as the .Contains method is also a method of an array, you might see unexpected results for this method:

$result.context.ToLower().Contains("c:\")
False

This is because the array doesn't contain the (full) string "c:\". Where it does contain the string:

$result.context.ToLower().Contains("c:\test\path")
True

Note that there is actually no reason to use the .ToLower() method here as by default PowerShell does a case-insensitive compare. Yet, this .ToLower() method might make things even more confusing as it "unrolls" any array with a single item to the item itself:

@{ context = @("c:\test\path") }.context.GetType().Name
Object[]

vs:

@{ context = @("c:\test\path") }.context.ToLower().GetType().Name
String

Which explains any unexpected result towards:

@{ context = @("c:\test\path") }.context.Contains("c:\")
False

vs:

@{ context = @("c:\test\path") }.context.ToLower().Contains("c:\")
True

Unfortunately, I can't give you an exact answer as I don't know the actual data type and structure of $result.context (you might consider to add the results of $result.context.GetType().Name and $result.context | ConvertTo-Json -Depth 9 to your question) but I hope that this might clear a few things with regards to the behavior of PowerShell related to your issue.

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.