3

今天(2017-05-29)我在 Windows 7 Enterprise 上使用 PowerShell 5.0.10586.117 并运行以下(缩短):

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

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

即使这两天之间的差是 39,我的代码也会在 if 子句中跳转并将“测试”发送到屏幕。

我在这里做错了什么?

4

3 回答 3

7

分配 14$TimeDifference. 相反,您不想Days使用以下方式比较属性-le

if ($TimeDifference.Days -le 14)
{
    Write-Host "test"
}
于 2017-05-29T13:18:13.073 回答
3

为了补充 Martin Brandl 的有用答案

与许多其他语言一样 - 但与 VBScript 不同,例如 - PowerShell使用不同的符号:

  • 赋值运算符( )=
  • 等式测试运算符 ( -eq)相比。

这种区别允许使用赋值作为表达式,这是您无意中所做的:

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

14$TimeDifference正如 Martin 解释的那样赋值给 variable,并且因为赋值必须作为的条件if)包含在布尔条件。(...) (...)$TimeDifferenceif

也就是说,由(...)评估的表达式if具有值14- 一个非零数字 - 因此$true在此布尔上下文中被解释为,而与 的原始值无关$TimeDifference

笔记:

  • 要了解有关PowerShell 运算符的更多信息,请运行Get-Help about_Operators

  • 要了解PowerShell 如何将任意值解释为条件中的布尔值(to-Boolean coercion),请参阅此答案的底部部分。

  • 要测试已经Booleans的变量或表达式,只需按原样使用它们,或者,如有必要,用-not( !) 否定它们;例如:

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

最后,这是您的代码的简化版本,它不需要中间变量,使用强制转换将字符串转换为[datetime]实例并使用[datetime]::now,更有效的等价物Get-Date(尽管这很少重要)。

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

请注意,"test"作为语句本身如何将输出隐式发送到 PowerShell 的(成功)输出流,默认情况下会打印到控制台。
Write-Host绕过这个流,通常应该避免

于 2017-05-29T17:45:23.157 回答
0

马丁没有更好的解决方案,只是一个简短的代码

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

if ($TimeDifferenceDays -lt 14)
{
    Write-Host "test"
}
于 2017-05-29T17:09:45.273 回答