2

I am using a PowerShell script to validate file dates on remote production servers. The check outputs a code number to our deployment tool to report either a passing or failing result to indicate if the file is correct or not.

This works, however the only problem I have is that I cannot get the following script to work with an -eq and have instead used a -gt and put the file date in the script one day less than the actual file date. For instance, 11/17/2014 in the script to check a 11/18/2014 file.

$FileExe= Get-ChildItem "C:\filepath\file.exe" |
    Where-Object {$_.LastWriteTime -gt "11/17/2014"} | Out-String

if($FileExe){Write-Host '0'} else{Write-Host '4';Exit 4}

Assuming the file is the correct 11/18/2014 file, this will output a 0, indicating it passes. If not, then it outputs a 4 indicating the wrong file is in place at which point I can go in and fix it.

If I change the -gt to an -eq and change the date in the script to match the actual file date (11/18/2014 in this example), the script fails and outputs the error code. This is despite the fact the file date and date in the script is correct.

At this point, I am at a loss. Am I doing something wrong with my script, or is there a better way to do what I am trying to do here that will allow an -eq?

Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
h2ocool
  • 39
  • 1
  • 1
  • 7

3 Answers3

3

Just to help complement the other answers I think it is worth pointing out that the -eq operation you are testing for is very unlikely to work. You are comparing the string date "11/18/2014" to a datetime value LastWriteTime. The string date will be converted to a DateTime in order for the comparison to work.

Consider the following

Get-Date "10/06/2014" returns Monday, October 06, 2014 12:00:00 AM As you can see there is a time default to midnight. Your -eq comparison is using that time. Unless your LastWriteTime is actually at midnight the comparison would return false and justly so. If you wanted to just know if the change was that day only you need to compare the date of LastWriteTime

$_.LastWriteTime.Date -eq "10/06/2014"

This way you are comparing both dates at midnight of the respective days.

This answer talks a little about left hand operations with boolean values. It just shows what powershell will attempt to do with what is on the right hand side of the operator.

Community
  • 1
  • 1
Matt
  • 45,022
  • 8
  • 78
  • 119
2

The issue is simple. You are treating it like a string, but it's not. The object that you are comparing the LastWriteTime to is a string, so your comparison is not going to happen like you expect. Instead let's look at the LastWriteTime property to see what you should be comparing it to. Just looking at the first object in my C:\Temp folder as an example, here's what I see:

PS C:\windows\system32> (gci c:\temp)[0].LastWriteTime.GetType()

IsPublic IsSerial Name                                     BaseType                                                                                                                                                                                              
-------- -------- ----                                     --------                                                                                                                                                                                              
True     True     DateTime                                 System.ValueType 

Ok, so it's a DateTime, not a string. Getting a DateTime object is simple, just use Get-Date. So for your purposes consider this:

$Date = Get-Date "11/18/2014"
$FileExe= Get-ChildItem "C:\filepath\file.exe" | Where-Object {$_.LastWriteTime -eq $date}
If($FileExe){"The last write was on $date"}else{"The last write was not on $date"}
TheMadTechnician
  • 34,906
  • 3
  • 42
  • 56
  • If I use a -gt I get this: Mode LastWriteTime Length Name ---- ------------- ------ ---- -a--- 11/18/2014 2:03 PM 21176320 file.exe But get NULL if I use an -eq. Both results were the same with or without the out-string property. I have to compare against the static date time stamp. – h2ocool Nov 18 '14 at 20:58
0

There are two issues going on here. As TheMadTechnician pointed out, you're trying to compare a DateTime and a string. However, the more important issue is the precision of the dates in question. The LastWriteTime property stores the date time up to the millisecond. When you get a DateTime just using the date, it will assign a time of midnight.

$ > $d1 = Get-Date
$ > $d1

Tuesday, November 18, 2014 2:27:16 PM

$ > $d2 = Get-Date "2014-11-18"
$ > $d2

Tuesday, November 18, 2014 12:00:00 AM

$ > $d1 -eq $d2
False

However, since it is a DateTime object, you can use the Date property to get just the date (actually, it returns a full DateTime, with the time set to midnight):

$dt = Get-Date "2014-11-18"
gci | ? { $_.LastWriteTime.Date -eq $dt }

Edited to add that after testing a bit more, you do not need to get a DateTime object for the comparison:

gci | ? { $_.LastWriteTime.Date -eq "2014-11-18} }
KevinD
  • 3,023
  • 2
  • 22
  • 26
  • You dont _need_ a DateTime object but since there is one on the left side of `eq` PowerShell will attempt to convert "2014-11-18" to a DateTime for the purpose of comparison – Matt Nov 18 '14 at 22:10