Unexpected Results when Comparing Different Datatypes in PowerShell

Earlier this week, I saw a tweet from a fellow PowerShell community member who mentioned PowerShell was returning inaccurate results. The command shown in the tweet was similar to the one in the following example.

1Get-AppxPackage |
2Where-Object -Property IsFramework -eq 'False' |
3Select-Object -Property Name, SignatureKind, IsFramework

datatype-victim1a.jpg

Why would results be returned where IsFramework is true when the command is filtering them down to only the ones that are false?

I knew exactly what the problem was because I've been bit by it more times than I care to remember. Piping the Get-AppxPackage command to Get-Member shows that the IsFramework property returns a Boolean and the results in the previous example where skewed because a string was being compared to a Boolean.

1Get-AppxPackage | Get-Member

datatype-victim2a.jpg

Simply changing the comparison value in the Where-Object statement from the string False to the Boolean $false returns the expected results as shown in the following example.

1Get-AppxPackage |
2Where-Object -Property IsFramework -eq $false |
3Select-Object -Property Name, SignatureKind, IsFramework

datatype-victim3a.jpg

Because of the way implicit datatype conversion is performed in PowerShell, your mileage may vary depending on which way the comparison is being perform as shown in the following example where False is equal to $false, but $false isn't equal to False.

1'False' -eq $false
2$false -eq 'False'

datatype-victim4a.jpg

µ