3

Today (2017-05-29) I am using PowerShell 5.0.10586.117 on Windows 7 Enterprise and run the following (shortened):

$dateOfLicense = "2017-04-20"
$dateOfToday = '{0:yyyy-MM-dd}' -f (Get-Date)

$TimeDifference = [DateTime]$dateOfToday - [DateTime]$dateOfLicense 
if (($TimeDifference) = 14)
{
    Write-Host "test"
}

Even the difference between both days is 39, my code jumps in the if-clause and sends "test" to screen.

What am I doing wrong here?

mklement0
  • 382,024
  • 64
  • 607
  • 775
Joey
  • 511
  • 6
  • 20

3 Answers3

7

You are assigning 14 to $TimeDifference. Instead you wan't to compare the Days property using -le:

if ($TimeDifference.Days -le 14)
{
    Write-Host "test"
}
Martin Brandl
  • 56,134
  • 13
  • 133
  • 172
3

To complement Martin Brandl's helpful answer:

Like many other languages - but unlike VBScript, for instance - PowerShell uses distinct symbols for:

  • the assignment operator (=)
  • vs. the equality test operator (-eq).

This distinction enables using assignments as expressions, which is what you inadvertently did:

if ($TimeDifference = 14) ... # same as: if (($TimeDifference) = 14) ...

assigns 14 to variable $TimeDifference, as Martin explains, and, because the assignment is (of necessity, to serve as a conditional for if) enclosed in (...), returns the assigned value (the inner (...) around $TimeDifference make no difference here, however) and that value is used as the Boolean conditional for if.

That is, the (...) expression evaluated by if has value 14 - a nonzero number - and is therefore interpreted as $true in this Boolean context, irrespective of the original value of $TimeDifference.

Note:

  • To learn more about PowerShell's operators, run Get-Help about_Operators

  • To learn about how PowerShell interprets arbitrary values as Booleans in conditionals (to-Boolean coercion), see the bottom section of this answer.

  • To test variables or expressions that already are Booleans, just use them as-is or, if necessary, negate them with -not (!); e.g.:

    if ($someBoolean) {      # Better than: if ($someBoolean -eq $true)
    if (-not $someBoolean) { # Better than: if ($someBoolean -eq $false)
    

Finally, here's a streamlined version of your code that doesn't require intermediate variables, uses a cast to convert the string to a [datetime] instance and uses [datetime]::now, the more efficient equivalent of Get-Date (though that will rarely matter).

if (([datetime]::now - [datetime] '2017-04-20').Days -eq 14) {
  "test"
}

Note how "test" as a statement by itself implicitly sends output to PowerShell's (success) output stream, which prints to the console by default.
Write-Host bypasses this stream and should generally be avoided.

mklement0
  • 382,024
  • 64
  • 607
  • 775
0

Not better solution of Martin, just an shorty code

$dateOfLicense = [DateTime]"2017-04-20"
$TimeDifferenceDays = ((Get-Date) - $dateOfLicense).Days 

if ($TimeDifferenceDays -lt 14)
{
    Write-Host "test"
}
mklement0
  • 382,024
  • 64
  • 607
  • 775
Esperento57
  • 16,521
  • 3
  • 39
  • 45