#1 16 Dec 2020 22:55

RedHut
Member
Registered: 16 Dec 2020
Posts: 3

Where-Object gives two different results using a equivalent syntax

I'm trying to understand why I get a different result from the two equivalent where-object syntax.

Basically I get a different result from using ? {$_.CreationTime -lt $_.LastWriteTime} versus ? CreationTime -lt LastWriteTime on a file object.

Here is the test case which gives the same result each time:

$folder = 'mymediafilesfolder'
get-child-item $folder |ft name,CreationTime,LastWriteTime

Name     CreationTime        LastWriteTime     
----     ------------        -------------     
02 - feb 08.12.2020 04.59.37 10.12.2020 03.50.23

gci $folder |ft name,CreationTime,LastWriteTime

Name                              CreationTime        LastWriteTime     
----                              ------------        -------------     
20200201-DJI_0902.MP4     10.12.2020 03.50.23 01.02.2020 20.50.48
20200201-DJI_0903.MP4     08.12.2020 13.20.33 01.02.2020 20.55.48
20200201-DJI_0904.MP4     08.12.2020 04.59.37 01.02.2020 21.00.50

gci $folder |ft name,CreationTime,LastWriteTime | ? CreationTime -lt LastWriteTime

Name                              CreationTime        LastWriteTime     
----                              ------------        -------------     
20200201-DJI_0902.MP4     10.12.2020 03.50.23 01.02.2020 20.50.48
20200201-DJI_0903.MP4     08.12.2020 13.20.33 01.02.2020 20.55.48
20200201-DJI_0904.MP4     08.12.2020 04.59.37 01.02.2020 21.00.50

gci $folder |ft name,CreationTime,LastWriteTime | ? {$_.CreationTime -lt $_.LastWriteTime}

No items match the filter


According to the docs on this site, the two ways of writing comprising statements should give the same result, but the don't. Why is it behaving this way? Strangely enough, this code returns a result:

gci $folder |ft name,LastWriteTime,CreationTime | ? {$_.CreationTime -eq $_.LastWriteTime}

Name                              LastWriteTime       CreationTime       
----                              -------------       ------------       
20200201-DJI_0902.MP4     01.02.2020 20.50.48 10.12.2020 03.50.23
20200201-DJI_0903.MP4     01.02.2020 20.55.48 08.12.2020 13.20.33
20200201-DJI_0904.MP4     01.02.2020 21.00.50 08.12.2020 04.59.37

The behaviour is not logical to me but apologies if my confusion is from not understanding basic concept.

Offline

#2 17 Dec 2020 01:23

Simon Sheppard
Super Administrator
Registered: 27 Aug 2005
Posts: 1,100
Website

Re: Where-Object gives two different results using a equivalent syntax

Try changing the |ft into |select

gci $folder |SELECT name,CreationTime,LastWriteTime | ? {$_.CreationTime -lt $_.LastWriteTime}

I think what is happening here is the table formatting is converting everything into strings
and then your comparison is being fed a bunch of effectively random strings instead of neat PowerShell objects

An interesting question is why does your -eq comparison return True?
Try replacing one of the values with $Null and see what happens.

Last edited by Simon Sheppard (17 Dec 2020 01:32)

Offline

#3 18 Dec 2020 01:33

RedHut
Member
Registered: 16 Dec 2020
Posts: 3

Re: Where-Object gives two different results using a equivalent syntax

I think you might be on to something here. It looks like I'm seeing several variations of an issue here with objects being passed on as a string.

gci $folder |SELECT name,CreationTime,LastWriteTime | ? {$_.CreationTime -gt $_.LastWriteTime}

Name                              CreationTime        LastWriteTime     
----                              ------------        -------------     
20200201-DJI_0902.MP4     10.12.2020 03.50.23 01.02.2020 20.50.48
20200201-DJI_0903.MP4     08.12.2020 13.20.33 01.02.2020 20.55.48
20200201-DJI_0904.MP4     08.12.2020 04.59.37 01.02.2020 21.00.50

I've made a conclusion to go forward with this syntax:

gci $folder |? {$_.CreationTime -gt $_.LastWriteTime}

Mode                 LastWriteTime         Length Name                                                                                                                                                                                                           
----                 -------------         ------ ----                                                                                                                                                                                                           
-a----        01.02.2020     20.50     3759236792 20200201-DJI_0902.MP4                                                                                                                                                                                 
-a----        01.02.2020     20.55     3759236146 20200201-DJI_0903.MP4                                                                                                                                                                                 
-a----        01.02.2020     21.00     3759234821 20200201-DJI_0904.MP4 

The rest of the options seems unpredictable:

gci $folder |? CreationTime -gt LastWriteTime

? : The 'Igt' operator failed: Could not compare "12/10/2020 03:50:23" to "LastWriteTime". Error: "Cannot convert value "LastWriteTime" to type "System.DateTime". Error: "The string was not recognized as a valid DateTime. There is an unknown word starting a
t index 0."".
At line:1 char:14
+ gci $folder |? CreationTime -gt LastWriteTime
+              ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    + CategoryInfo          : InvalidOperation: (20200201-DJI_0902.MP4:PSObject) [Where-Object], PSInvalidOperationException
    + FullyQualifiedErrorId : OperatorFailed,Microsoft.PowerShell.Commands.WhereObjectCommand

gci $folder |? LastWriteTime -lt CreationTime

? : The 'Ilt' operator failed: Could not compare "02/01/2020 20:50:48" to "CreationTime". Error: "Cannot convert value "CreationTime" to type "System.DateTime". Error: "The string was not recognized as a valid DateTime. There is an unknown word starting at
index 0."".
At line:1 char:14
+ gci $folder |? LastWriteTime -lt CreationTime
+              ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    + CategoryInfo          : InvalidOperation: (20200201-DJI_0902.MP4:PSObject) [Where-Object], PSInvalidOperationException
    + FullyQualifiedErrorId : OperatorFailed,Microsoft.PowerShell.Commands.WhereObjectCommand

gci $folder |ft name,LastWriteTime,CreationTime | ? {$_.CreationTime -eq $null}

Name                              LastWriteTime       CreationTime       
----                              -------------       ------------       
20200201-DJI_0902.MP4     01.02.2020 20.50.48 10.12.2020 03.50.23
20200201-DJI_0903.MP4     01.02.2020 20.55.48 08.12.2020 13.20.33
20200201-DJI_0904.MP4     01.02.2020 21.00.50 08.12.2020 04.59.37

gci $folder |ft name,LastWriteTime,CreationTime | ? {$_.LastWriteTime -eq $null}

Name                              LastWriteTime       CreationTime       
----                              -------------       ------------       
20200201-DJI_0902.MP4     01.02.2020 20.50.48 10.12.2020 03.50.23
20200201-DJI_0903.MP4     01.02.2020 20.55.48 08.12.2020 13.20.33
20200201-DJI_0904.MP4     01.02.2020 21.00.50 08.12.2020 04.59.37

Offline

#4 18 Dec 2020 11:26

Simon Sheppard
Super Administrator
Registered: 27 Aug 2005
Posts: 1,100
Website

Re: Where-Object gives two different results using a equivalent syntax

What version of PowerShell are you running?

Offline

#5 18 Dec 2020 23:12

RedHut
Member
Registered: 16 Dec 2020
Posts: 3

Re: Where-Object gives two different results using a equivalent syntax

$psversiontable

Name                           Value
----                           -----
PSVersion                      5.1.19041.610
PSEdition                      Desktop
PSCompatibleVersions           {1.0, 2.0, 3.0, 4.0...}
BuildVersion                   10.0.19041.610
CLRVersion                     4.0.30319.42000
WSManStackVersion              3.0
PSRemotingProtocolVersion      2.3
SerializationVersion           1.1.0.1

Offline

#6 19 Dec 2020 14:18

Simon Sheppard
Super Administrator
Registered: 27 Aug 2005
Posts: 1,100
Website

Re: Where-Object gives two different results using a equivalent syntax

OK version 5.1 should be good for this.

From some googling about this it looks like the short comparison statement will only evaluate a single property, or a single comparison.

If you set a variable $demo equal to some date and then try gci $folder |? CreationTime -gt $demo
it will work.

So it looks like you just need to use Select along with the full script block to get the result you are looking for.

Offline

Board footer

Powered by FluxBB