# Why does this where-object command work?

**URL:** <https://forums.powershell.org/t/why-does-this-where-object-command-work/11674>\
**Category:** PowerShell Help\
**Created:** [November 15, 2018, 3:50am UTC](https://forums.powershell.org/t/why-does-this-where-object-command-work/11674 "2018-11-15T03:50:55Z")\
**Posts on this page:** 19\
**Page:** 1

<div class="post-metadata">

**Author:** ![rzimmerman](https://avatars.discourse-cdn.com/v4/letter/r/e480ec/32.png) [@rzimmerman](https://forums.powershell.org/u/rzimmerman)\
**Post date:** [November 15, 2018, 3:50am UTC](https://forums.powershell.org/t/why-does-this-where-object-command-work/11674/1 "2018-11-15T03:50:55Z")

</div>

I ran across this line the other day that a student wrote in a beginning PowerShell class. I can’t figure out how it works since there is no size property for the Win32\_QuickFixEngineering object type (which is the object type passed by the Get-Hotfix cmdlet). What is size referring to that makes this command work?

get-hotfix | where {$_.Description -eq ‘Security update’ -and $_.size -lt 5MB}

---

<div class="post-metadata">

**Author:** ![Olaf](https://sea1.discourse-cdn.com/flex019/user_avatar/forums.powershell.org/olaf/32/992_2.png) [@Olaf](https://forums.powershell.org/u/Olaf)\
**Post date:** [November 15, 2018, 4:37am UTC](https://forums.powershell.org/t/why-does-this-where-object-command-work/11674/2 "2018-11-15T04:37:05Z")

</div>

Wow … funny. Obviously it does not matter what property you specify. At least on my system for example

```
get-hotfix | where {$_.Description -eq ‘Security update’ -and $_.Surname -lt ‘RogerRabbit*’}
```
 produces the same output like your original command line. 😉

---

<div class="post-metadata">

**Author:** ![juancrl](https://avatars.discourse-cdn.com/v4/letter/j/278dde/32.png) [@juancrl](https://forums.powershell.org/u/juancrl)\
**Post date:** [November 15, 2018, 5:26am UTC](https://forums.powershell.org/t/why-does-this-where-object-command-work/11674/3 "2018-11-15T05:26:15Z")

</div>

Why is nobody using Strict Mode ? Why is it not enabled by default ? (Rethoric questions)

Use

```
Set-StrictMode -Version Latest

Get-Hotfix ... your Where-Object {}
```

With Strict Mode, you’ll get an error when accessing a property that does not exist (Get-Help Set-StrictMode).

You’ll immediatley see and fix your mistakes, saving lots of time and writing safer code.

Without it, you get $null for each inexistent property.

“AnyText”.Lenght is another nice example…

Another question is why ($null -lt 5MB) and not ($null -gt 5MB)…

www . powershelltraining . eu

&nbsp;

&nbsp;

&nbsp;

---

<div class="post-metadata">

**Author:** ![kvprasoon](https://sea1.discourse-cdn.com/flex019/user_avatar/forums.powershell.org/kvprasoon/32/4449_2.png) [@kvprasoon](https://forums.powershell.org/u/kvprasoon)\
**Post date:** [November 15, 2018, 5:44am UTC](https://forums.powershell.org/t/why-does-this-where-object-command-work/11674/4 "2018-11-15T05:44:39Z")

</div>

this is because of the type casting and comparison. IMO it compares the length if the $\_.size (which is a known existing property hence length is 0) to the ‘5MB’ which has length greater than empty.

the output will be different if you use -gt instead of -lt.

below example proves it

```
1..5 | Where-Object -FilterScript {$_.f -lt 1}
1..5 | Where-Object -FilterScript {$_.f -ge 1}
1..5 | Where-Object -FilterScript {$_.f -ge $null}
```

---

<div class="post-metadata">

**Author:** ![js2010](https://avatars.discourse-cdn.com/v4/letter/j/ebca7d/32.png) [@js2010](https://forums.powershell.org/u/js2010)\
**Post date:** [November 15, 2018, 1:22pm UTC](https://forums.powershell.org/t/why-does-this-where-object-command-work/11674/5 "2018-11-15T13:22:32Z")

</div>

Another way to look at it:

```
get-hotfix | foreach {$_.size -eq $null}
True
True
True
True
True
True
True
True
True
True
True
True
```

---

<div class="post-metadata">

**Author:** ![rzimmerman](https://avatars.discourse-cdn.com/v4/letter/r/e480ec/32.png) [@rzimmerman](https://forums.powershell.org/u/rzimmerman)\
**Post date:** [November 15, 2018, 3:58pm UTC](https://forums.powershell.org/t/why-does-this-where-object-command-work/11674/6 "2018-11-15T15:58:17Z")

</div>

Thank you. Excellent answers. Indeed it does give different results with -gt. And I was unaware of the “null” response for unknown property values. This has been very excellent help and cleared a lot of things up.

&nbsp;

---

<div class="post-metadata">

**Author:** ![postanote](https://avatars.discourse-cdn.com/v4/letter/p/ebca7d/32.png) [@postanote](https://forums.powershell.org/u/postanote)\
**Post date:** [November 15, 2018, 7:21pm UTC](https://forums.powershell.org/t/why-does-this-where-object-command-work/11674/7 "2018-11-15T19:21:08Z")

</div>

Or just do this, which works with or without Strict mode set.

```
Set-StrictMode -Version Latest

 get-hotfix | where Description -eq 'Security Update'

Source Description HotFixID InstalledBy InstalledOn              
------ ----------- -------- ----------- -----------              
Lab01 Security Update KB4457146 NT AUTHORITY\SYSTEM 9/12/2018 12:00:00 AM    
Lab01 Security Update KB4465663 NT AUTHORITY\SYSTEM 11/14/2018 12:00:00 AM   
Lab01 Security Update KB4467694 NT AUTHORITY\SYSTEM 11/14/2018 12:00:00 AM   
Lab01 Security Update KB4467702 NT AUTHORITY\SYSTEM 11/14/2018 12:00:00 AM
```

Also the reason for your ‘-and’ failure, is that there is no property called ‘size’, so combining the will fail of course.

```
(get-hotfix)[0] | Get-Member | ft -a

   TypeName: System.Management.ManagementObject#root\cimv2\Win32_QuickFixEngineering

Name MemberType Definition                                                                                                                
---- ---------- ----------                                                                                                                
PSComputerName AliasProperty PSComputerName = __SERVER                                                                                                 
Caption Property string Caption {get;set;}                                                                                                 
CSName Property string CSName {get;set;}                                                                                                  
Description Property string Description {get;set;}                                                                                             
FixComments Property string FixComments {get;set;}                                                                                             
HotFixID Property string HotFixID {get;set;}                                                                                                
InstallDate Property string InstallDate {get;set;}                                                                                             
InstalledBy Property string InstalledBy {get;set;}                                                                                             
Name Property string Name {get;set;}                                                                                                    
ServicePackInEffect Property string ServicePackInEffect {get;set;}                                                                                     
Status Property string Status {get;set;}                                                                                                  
__CLASS Property string__ CLASS {get;set;}                                                                                                 
__DERIVATION Property string[]__DERIVATION {get;set;}                                                                                          
__DYNASTY Property string__ DYNASTY {get;set;}                                                                                               
__GENUS Property int__ GENUS {get;set;}                                                                                                    
__NAMESPACE Property string__ NAMESPACE {get;set;}                                                                                             
__PATH Property string__ PATH {get;set;}                                                                                                  
__PROPERTY_COUNT Property int__ PROPERTY_COUNT {get;set;}                                                                                           
__RELPATH Property string__ RELPATH {get;set;}                                                                                               
__SERVER Property string__ SERVER {get;set;}                                                                                                
__SUPERCLASS Property string__ SUPERCLASS {get;set;}                                                                                            
PSStatus PropertySet PSStatus {__PATH, Status}                                                                                                 
ConvertFromDateTime ScriptMethod System.Object ConvertFromDateTime();                                                                                      
ConvertToDateTime ScriptMethod System.Object ConvertToDateTime();                                                                                        
InstalledOn ScriptProperty System.Object InstalledOn {get=if ([environment]::osversion.version.build -ge 7000)...
```

Even if you look at the extended properties

```
(get-hotfix)[0] | Select * | Format-List -Force
```

---

<div class="post-metadata">

**Author:** ![js2010](https://avatars.discourse-cdn.com/v4/letter/j/ebca7d/32.png) [@js2010](https://forums.powershell.org/u/js2010)\
**Post date:** [November 15, 2018, 7:24pm UTC](https://forums.powershell.org/t/why-does-this-where-object-command-work/11674/8 "2018-11-15T19:24:11Z")

</div>

I usually check the properties like this:

```
cmdlet | fl *
```

Just “| fl” might use a format file and not show everything.

---

<div class="post-metadata">

**Author:** ![postanote](https://avatars.discourse-cdn.com/v4/letter/p/ebca7d/32.png) [@postanote](https://forums.powershell.org/u/postanote)\
**Post date:** [November 15, 2018, 8:01pm UTC](https://forums.powershell.org/t/why-does-this-where-object-command-work/11674/9 "2018-11-15T20:01:27Z")

</div>

But this will, including some not show any other way, still, no size property, which contributes to the OP’s error.

```
(get-hotfix)[0] | Get-Member -Force

Name MemberType
---- ----------
PSComputerName AliasProperty
pstypenames CodeProperty
psadapted MemberSet
psbase MemberSet
psextended MemberSet
psobject MemberSet
PSStandardMembers MemberSet
Caption Property
CSName Property
Description Property
FixComments Property
HotFixID Property
InstallDate Property
InstalledBy Property
Name Property
ServicePackInEffect Property
Status Property
__CLASS Property
__DERIVATION Property
__DYNASTY Property
__GENUS Property
__NAMESPACE Property
__PATH Property
__PROPERTY_COUNT Property
__RELPATH Property
__SERVER Property
__SUPERCLASS Property
PSStatus PropertySet
ConvertFromDateTime ScriptMethod
ConvertToDateTime ScriptMethod
InstalledOn ScriptProperty
```

---

<div class="post-metadata">

**Author:** ![gourango121](https://avatars.discourse-cdn.com/v4/letter/g/7c8e57/32.png) [@gourango121](https://forums.powershell.org/u/gourango121)\
**Post date:** [November 19, 2018, 12:29pm UTC](https://forums.powershell.org/t/why-does-this-where-object-command-work/11674/10 "2018-11-19T12:29:13Z")

</div>

this is working because, if some property is not present for an object Powershell will create a new custom property. have a look at the below code.

&nbsp;

PS C:\windows\system32\> get-hotfix | select size

## size

&nbsp;

It won’t give any error instead it will create a new property called **size.** As **size** does not have any value it will hold $null.Now if you compare by using (-lt) it will always return true as ($null -lt any value) is true. Have a look at the below code,

&nbsp;

PS C:\windows\system32\> get-hotfix | for each {$\_.size -lt 5}  
True  
True  
True  
True  
True  
True  
True  
True  
True

&nbsp;

now if you change the compare operator to (-gt )it will always give false. As $null -gt any value is false.

---

<div class="post-metadata">

**Author:** ![kvprasoon](https://sea1.discourse-cdn.com/flex019/user_avatar/forums.powershell.org/kvprasoon/32/4449_2.png) [@kvprasoon](https://forums.powershell.org/u/kvprasoon)\
**Post date:** [November 20, 2018, 3:26am UTC](https://forums.powershell.org/t/why-does-this-where-object-command-work/11674/11 "2018-11-20T03:26:22Z")

</div>

Foreach doesn’t behaves like Select-Object. Here comparison happens with the length of the **non-existing property** , hence its true.

---

<div class="post-metadata">

**Author:** ![js2010](https://avatars.discourse-cdn.com/v4/letter/j/ebca7d/32.png) [@js2010](https://forums.powershell.org/u/js2010)\
**Post date:** [November 20, 2018, 9:55am UTC](https://forums.powershell.org/t/why-does-this-where-object-command-work/11674/12 "2018-11-20T09:55:30Z")

</div>

Hmm, but $null isn’t equal to 0?

```
PS C:\users\admin> $null -lt 1
True
PS C:\users\admin> $null -lt -1
False
PS C:\users\admin> $null -le 0
True
PS C:\users\admin> $null -eq 0
False
PS C:\users\ccfadmin> $null -lt 0
True
```

---

<div class="post-metadata">

**Author:** ![juancrl](https://avatars.discourse-cdn.com/v4/letter/j/278dde/32.png) [@juancrl](https://forums.powershell.org/u/juancrl)\
**Post date:** [November 20, 2018, 10:32am UTC](https://forums.powershell.org/t/why-does-this-where-object-command-work/11674/13 "2018-11-20T10:32:52Z")

</div>

Well, $null is $null… it has no type. It is not equal to 0 by itself.

But sometimes, variables in PowerShell can be converted (Cast) to another type. $Null can be converted to [int], and it has to have a valid value. Both

```
[int]$Null
```

```
$Null -AS [int]
```

return 0, by convention.

&nbsp;

---

<div class="post-metadata">

**Author:** ![js2010](https://avatars.discourse-cdn.com/v4/letter/j/ebca7d/32.png) [@js2010](https://forums.powershell.org/u/js2010)\
**Post date:** [November 20, 2018, 10:36am UTC](https://forums.powershell.org/t/why-does-this-where-object-command-work/11674/14 "2018-11-20T10:36:27Z")

</div>

Hmm, $null is in there somewhere close to 0!

```
PS C:\users\admin> $null -gt -.00000000000000000000000000000000000001
True
PS C:\users\admin> $null -lt 0
True
```

---

<div class="post-metadata">

**Author:** ![kvprasoon](https://sea1.discourse-cdn.com/flex019/user_avatar/forums.powershell.org/kvprasoon/32/4449_2.png) [@kvprasoon](https://forums.powershell.org/u/kvprasoon)\
**Post date:** [November 20, 2018, 1:19pm UTC](https://forums.powershell.org/t/why-does-this-where-object-command-work/11674/15 "2018-11-20T13:19:28Z")

</div>

$\_.size -lt 5 converts $null to int and [int]$null is 0, hence it returns true

$\_.size -lt ‘5’ converts $null to string and [string]$null length is 0, hence it returns true .

---

<div class="post-metadata">

**Author:** ![js2010](https://avatars.discourse-cdn.com/v4/letter/j/ebca7d/32.png) [@js2010](https://forums.powershell.org/u/js2010)\
**Post date:** [November 20, 2018, 1:22pm UTC](https://forums.powershell.org/t/why-does-this-where-object-command-work/11674/16 "2018-11-20T13:22:35Z")

</div>

Usually the type is dictated by the left element in the comparison. $null seems to be a special case, since it has no type.

```
PS C:\Users\admin> '10' -gt 9
False
PS C:\Users\admin> 10 -gt '9'
True
PS C:\Users\admin> [datetime]::today -eq '11/20'
True
```

---

<div class="post-metadata">

**Author:** ![kvprasoon](https://sea1.discourse-cdn.com/flex019/user_avatar/forums.powershell.org/kvprasoon/32/4449_2.png) [@kvprasoon](https://forums.powershell.org/u/kvprasoon)\
**Post date:** [November 20, 2018, 2:13pm UTC](https://forums.powershell.org/t/why-does-this-where-object-command-work/11674/17 "2018-11-20T14:13:00Z")

</div>

yes it is a special case, just had a chat with Bruce Payette and PFB his comments.

Bruce Payette:

> $null in a numeric context (like comparing to a number) is converted to 0. And since 0 is less than 1, $null is special-cased by the runtime. It doesn't actually get converted, but is treated as a value less than 0 but greater that the smallest negative number. Likewise in a string context, it is treated as being 'smaller' than the smallest possible string i.e. ''.

---

<div class="post-metadata">

**Author:** ![rzimmerman](https://avatars.discourse-cdn.com/v4/letter/r/e480ec/32.png) [@rzimmerman](https://forums.powershell.org/u/rzimmerman)\
**Post date:** [November 21, 2018, 2:58am UTC](https://forums.powershell.org/t/why-does-this-where-object-command-work/11674/18 "2018-11-21T02:58:32Z")

</div>

This simple question has brought out a lot if interesting nuances and taught me, and hopefully others, a lot. I appreciate all the feedback.

&nbsp;

&nbsp;

---

<div class="post-metadata">

**Author:** ![dotnVo](https://avatars.discourse-cdn.com/v4/letter/d/4af34b/32.png) [@dotnVo](https://forums.powershell.org/u/dotnVo)\
**Post date:** [May 16, 2024, 8:33pm UTC](https://forums.powershell.org/t/why-does-this-where-object-command-work/11674/19 "2024-05-16T20:33:39Z")

</div>


