0

I have this string variable:

$path = "C:\Windows"

I have this array of strings:

$badDir = "windows",
        "i3\ic",
        "program",
        "system",
        "pagefile.sys",
        "system",
        "swapfile.sys",
        "sourcecd", 
        "backup",
        "wwwroot",
        "users",
        "desktop",
        "documents"

I'm trying to evaluate if $path has any of the strings contained in the array $badDir anywhere in its value. E.g. since my $path value is C:\Windows, and one of the elements of my array is windows, "Windows" should be matched and the following evaluation should return true.

$badDir -Match $path.ToLower()

However, it's returning false. What am I doing incorrectly here?

Thanks!

2
  • @Matt, this doesn't seem to be working. I want to match on the array item by looking anywhere in the $path variable. So if I had C:\Someotherdir\Windows\Hello it would still return true. Commented Sep 18, 2018 at 19:38
  • "without using regular expressions" - I'm curious why you put this. I'm expecting you found solutions saying $path -match ($badDir -join '|') or similar? You ask to avoid using regular expressions, and then use -match in your code, and -match always treats the thing on the right as a regular expression. Commented Sep 18, 2018 at 19:51

2 Answers 2

2

What am I doing incorrectly here?

You're testing the wrong thing, and testing the wrong way round.

Since your $path value is "C:\Windows", and $badDir does not contain 'c:\windows' and does not contain (a string containing "c:\windows"), the evaluation should return false

If you don't want to use regex, you need to loop over $badDir and test each item, and then look at the results:

$path = "C:\Windows"

$badDir = "windows",
    "i3\ic",
    "program",
    "system",
    "pagefile.sys",
    "system",
    "swapfile.sys",
    "sourcecd", 
    "backup",
    "wwwroot",
    "users",
    "desktop",
    "documents"

$badDirmatch = $badDir.Where({$path.ToLower().contains($_)}, 'First').Count -as [bool]

.Where() is faster than | Where-Object and the 'first' cutoff will let it stop instantly on a match, and not test all the rest of the elements.

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

1 Comment

This is very elegant and works perfectly. Thank you and thanks to @Matt for explaining what I was missing
0

$badDir -Match $path.ToLower() would compare "C:\Windows" against each element of $baddir. Since none of those are matches that is why you are getting false. The operation is muddied also since your pattern string contains regex. However this is not what you want anyway....

Pretty sure you need to compare each element of $baddirs individually against $path. I am not aware of a single operator that will do lazy matching like you expect here

($badDir | ForEach-Object{$path -match [regex]::Escape($_)}) -contains $true

$badDir elements contain regex metacharacters so we need to escape those to get true matches. Then we just check if the resulting boolean array contains any true elements. Slap that into a if block or in the pipe and you should be able to get the results you want.

There are other way to work with this depending on your actual implementation but the above should suffice.

Without Regex

Title says without regex so lets adapt what we have above to remove that part of the approach. Logic is still the same

($badDir | ForEach-Object{$path.ToLower().IndexOf("$_".ToLower()) -ge 0}) -contains $true

Check if one string is located within another. If there is we evaluate as a boolean and just like before check if one of the results are true.

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.