太多 - 或者在 powershell 的过滤器中?

Cha*_*ith 2 powershell active-directory

我正在尝试编写一个脚本,该脚本将从我们的公司 AD 中删除 90 天内未登录的计算机对象。当我运行以下命令并将其导出到 csv 时,导出中的所有设备的登录日期都超过 90 天前。

$LastLogonDate = (Get-Date).Adddays(-(90))
Get-ADComputer -Filter {LastLogonTimeStamp -le $LastLogonDate}
Run Code Online (Sandbox Code Playgroud)

当我使用更多与名称相关的过滤器(如“namingscheme”)或名称(如“anothernamingscheme”等)运行相同的脚本时,它会额外添加 660 个在 90 天内签入的设备,其中大多数是在过去2周。命令中有 37 个“-or”加上 1 个“and”,总共有 38 个名称类型。太多?我正在尝试寻找绝对不是我们服务器的设备,但每个办公室都有自己的命名约定(我们正在努力标准化它们)。我确信有更好的方法来做到这一点?我尝试执行 Name -ne "servername" 但这些命名约定也是全面的。

有什么想法为什么当我开始将名称选项添加到过滤器时会显示额外的 660 设备?我希望这是有道理的......

$LastLogonDate = (Get-Date).Adddays(-(90))
Get-ADComputer -Filter {LastLogonTimeStamp -le $LastLogonDate}
Run Code Online (Sandbox Code Playgroud)

以上给出了 90 天内未签入的所有设备的准确读数。1805 台设备。

$LastLogonDate = (Get-Date).Adddays(-(90))
Get-ADComputer -Filter {LastLogonTimeStamp -le $LastLogonDate -and Name -like "office-*" -or Name -like "office-*" -or Name -like "office-*" -or Name -like "office-*" -or Name -like "office-*" -or Name -like "office-*" -or Name -like "office-*" -or Name -like "office-*" -or Name -like "office-*" -or Name -like "office-*" -or Name -like "office-*" -or Name -like "office-*" -or Name -like "office-*" -or Name -like "office-*" -or Name -like "office-*" -or Name -like "office-*" -or Name -like "office-*" -or Name -like "office-*" -or Name -like "office-*" -or Name -like "office-*" -or Name -like "office-*" -or Name -like "office-*" -or Name -like "office-*" -or Name -like "office-*" -or Name -like "office-*" -or Name -like "office-*" -or Name -like "office-*" -or Name -like "office-*" -or Name -like "office-*" -or Name -like "office-*" -or Name -like "office-*" -or Name -like "office-*" -or Name -like "office-*" -or Name -like "office-*" -or Name -like "office-*" -or Name -like "office-*" -or Name -like "office-*" -or Name -like "office-*"} -Properties LastLogonTimeStamp, Name, OperatingSystem | Export-csv "c:\LastLogOn90Days.csv"
Run Code Online (Sandbox Code Playgroud)

上面给出了额外的 660 台设备,总共 2465 台。请注意,仅针对本文,“office”名称已更改为 office。它们在实际脚本中都是不同的实际名称,并且这些名称确实在导出中报告。与第一个脚本相比,仅报告 90 天内签入的 660 个额外设备

San*_*zon 6

原因很可能是您的OR条件中缺少括号:

Get-ADComputer -Filter { LastLogonTimeStamp -le $LastLogonDate -and Name -like 'office-*' -or Name -like 'office-*' ... }
Run Code Online (Sandbox Code Playgroud)

应该:

Get-ADComputer -Filter { LastLogonTimeStamp -le $LastLogonDate -and (Name -like 'office-*' -or Name -like 'office-*' ...) }
Run Code Online (Sandbox Code Playgroud)

为什么会这样?由于 AD 提供商如何转换过滤器,您可以使用Convert-ADFilter来了解提供商如何将过滤器转换为LDAP 语法,请参阅下面的比较:

$LastLogonDate = (Get-Date).Adddays(-90)
$convertADFilterSplat = @{
    Filter      = { LastLogonTimeStamp -le $LastLogonDate -and Name -like 'office-*' -or Name -like 'office-*' }
    CommandName = 'Get-ADComputer'
}

Convert-ADFilter @convertADFilterSplat
Run Code Online (Sandbox Code Playgroud)

转换为 LDAP 过滤器:

(|
  (&
    (LastLogonTimeStamp<=133434401747575412)
    (name=office-*)
  )
  (name=office-*)
)
Run Code Online (Sandbox Code Playgroud)

这显然是错误的,您可以将其读作“(其LastLogonTimeStamp小于或等于133434401747575412 AND Name开头的对象office-OR (Nameoffice-) 开头”

相反,如果使用括号来包裹OR条件:

$LastLogonDate = (Get-Date).Adddays(-90)
$convertADFilterSplat = @{
    Filter      = { LastLogonTimeStamp -le $LastLogonDate -and (Name -like 'office-*' -or Name -like 'office-*') }
    CommandName = 'Get-ADComputer'
}

Convert-ADFilter @convertADFilterSplat
Run Code Online (Sandbox Code Playgroud)

翻译为:

(&
  (LastLogonTimeStamp<=133434402342044131)
  (|
    (name=office-*)
    (name=office-*)
  )
)
Run Code Online (Sandbox Code Playgroud)

这听起来好多了,可以读作“(低于或等于的对象)AND(以OR开头)”LastLogonTimeStamp133434401747575412Nameoffice- Nameoffice-


另外,提醒一下,LastLogonTimeStamp属性并不精确,最多可能存在 14 天的差异。如果您想获得准确的结果,您必须使用过滤器中的LastLogon属性查询所有域控制器。有关更多详细信息,请参阅此答案。