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 ?
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.