Matthias
Matthias

Reputation: 13414

Powershell comparing strings in if structure gives wrong results

Simple Powershell script:

$key = Get-ItemProperty "HKLM:\SYSTEM\CurrentControlSet\Control\Session Manager"
$bootexecute = $key.BootExecute

write-host $bootexecute

if ($bootexecute -eq "autocheck autochk *") {
    return $false
} else {
    return $true
}

This is What I'm getting as output:

autocheck autochk /r \??\C: autocheck autochk *
False

So even though the $bootexecute variable does not exactly equals "autocheck autochk *" I still get "False" as a result, whereas it should return "True" here.

What's going on, what am I missing here?

Edit, to clarify: I literally want to check for the string "autocheck autochk *". Asterisk included.

Upvotes: 2

Views: 3246

Answers (3)

Matt
Matt

Reputation: 46680

Your -eq condition is not what you want.

You are doing a equal comparison on a long string with a partial match that will always be false. You might actually want a wildcard like.

$bootexecute -like "autocheck autochk *"

That should get what you want. However if you are trying to match the string literal then -like would not be good. I had assumed incorrectly that you were using a wildcard.

The point is that -eq would not work as there is more to the string then just "autocheck autochk *".

Consider the following to show why the -eq was "failing"

"autocheck autochk *" -eq "autocheck autochk *"
True

"autocheck autochk /r \??\C: autocheck autochk *" -eq "autocheck autochk *"
False

Working with arrays

As pointed out by Tony in comments you are getting an array returned. When treated as a string PowerShell concats it with spaces which is why write-host is displaying what it was. Since you know the full element you are testing for the array operator -contains makes more sense here.

$bootexecute -contains "autocheck autochk *"

Looking at the registry you see that BootExecute is a REG_MULTI_SZ so getting an array would be expected.

Upvotes: 2

Tony Hinkle
Tony Hinkle

Reputation: 4742

A string array is being returned from get-itemproperty, so $bootexecute is an array. The if statement evaluates to true because one of the items in the array is equal to the specified string.

If you want to compare just the first item in the array, you can change the if statement to:

if ($bootexecute[0] -eq "autocheck autochk *")

If you're wanting to compare all of them (which is what the posted code is doing), you could use .contains to make the code clearer:

if ($bootexecute.contains("autocheck autochk *"))

Upvotes: 1

Dave Markle
Dave Markle

Reputation: 97671

Since $bootexecute is evaluating to:

autocheck autochk /r \??\C: autocheck autochk *

-eq is probably not what you want.

Instead, use a regular expression and -match:

if ($bootexecute -match "autocheck autochk .*") {
    return $false
} else {
    return $true
}

which can just be simplified to:

$bootexecute -match "autocheck autochk .*"
return

Upvotes: 2

Related Questions