在 Active Directory 中搜索过去 30 天内登录过的计算机

在 Active Directory 中搜索过去 30 天内登录过的计算机

我正在尝试对 AD 进行 PowerShell 搜索,以仅查找过去 30 天内登录过的计算机(不是服务器或其他计算机)。除了 30 天限制部分外,我已经编写了大部分脚本。任何帮助都将不胜感激。

Get-ADComputer -Filter * -Properties * | FT 名称,操作系统,LastLogonDate -Autosize | Out-File C:\Temp\ComputerLastLogonDate.csv

答案1

获取 ADComputer -过滤器 * -属性 *

仅获取您要使用的属性...这样更高效。当您实际上不需要所有属性时,检索域中所有计算机的所有属性会对您的域控制器造成不必要的负担。这很浪费。

Get-ADComputer -Filter * -Properties OperatingSystem, LastLogonDate更好,因为你不需要全部属性。(始终包含“Name”属性。)

| FT 名称、操作系统、上次登录日期 - 自动调整大小

直到最后才格式化输出。换句话说,Format-Table 和 Format-List 应该是数据通过管道传输到的整个 cmdlet 链中的最后一个 cmdlet。

Get-ADComputer -Filter * -Properties OperatingSystem, LastLogonDate | Where { $_.LastLogonDate -GT (Get-Date).AddDays(-30) }

这稍微好一点,但仍然有些效率低下,因为你仍然在检索一组全部计算机……您可以让域控制器为您进行过滤。

$LastMonth = $(((Get-Date).AddDays(-30)).ToFileTime())

Get-ADComputer -LDAPFilter "(lastLogonTimeStamp>=$LastMonth)" -Properties OperatingSystem,LastLogonDate

我之所以在这里使用 lastLogonTimeStamp(即“文件时间”,而不是 .NET DateTime),是因为“LastLogonDate”不是真正的 LDAP 属性。LastLogonDate 只是 PowerShell 自动为您转换 lastLogonTimestamp 属性的一种有用方法。lastLogonTimestamp 是“真正的”LDAP 属性。

允许域控制器向您返回筛选后的集合,而不是所有计算机的完整集合,意味着通过网络传输的数据更少,PowerShell 需要处理的数据也更少。

另请注意,您将必须处理以下计算机:

  • 有一个 (null) LastLogonDate
  • LastLogonDate 为 1/1/1601,或纪元的开始。

答案2

您的命令根本没有针对工作站进行过滤。

您需要使用 LastLogonTimeStamp 字段,以便您可以轻松地对其进行过滤,然后将其转换为 DateTime 进行导出。

这些信息也可以在网上轻松找到。就像这里的例子一样,我稍作修改,只返回工作站。注意,它们只查询所需的属性。这样效率更高。另外,我不知道为什么他们在这个脚本中有一个 $domain 变量。它看起来完全没用。

# Gets time stamps for all computers in the domain that have NOT logged in since after specified date 
# Mod by Tilo 2013-08-27 
import-module activedirectory  
$domain = "domain.mydom.com"  
$DaysInactive = 90  
$time = (Get-Date).Adddays(-($DaysInactive)) 

# Get all AD computers with lastLogonTimestamp less than our time 
Get-ADComputer -Filter {LastLogonTimeStamp -lt $time -and OperatingSystem -notlike "*server*"} -Properties LastLogonTimeStamp,OperatingSystem | 

# Output hostname and lastLogonTimestamp into CSV 
select-object Name,@{Name="Stamp"; Expression={[DateTime]::FromFileTime($_.lastLogonTimestamp)}} | export-csv OLD_Computer.csv -notypeinformation

参考自这里:https://gallery.technet.microsoft.com/scriptcenter/Get-Inactive-Computer-in-54feafde

另请参阅以下与此相关的参考资料:

LastLogonTimeStamp 属性/其设计目的

将时间戳转换为日期时间

答案3

这应该可以帮助您朝着想要的方向前进。

Get-ADComputer -Properties * -Filter {
     Enabled -eq $True -and
     OperatingSystem -like 'Windows*' -and
     OperatingSystem -notlike "Windows Server*" -and
     OperatingSystem -notlike "Windows 7*"
} -SearchBase "DC=hhmtx,DC=org" | FT Name, OperatingSystem, LastLogonDate -Autosize | Out-File C:\Temp\ComputerLastLogonDate.csv

答案4

请记住,LastLogonDate 是 LastLogonTimeStamp 的转换版本。LastLogonTimeStamp 并不是实际计算机上次登录时间的最准确表示。默认情况下,它可能相差 14 天。更多信息 -https://social.technet.microsoft.com/wiki/contents/articles/22461.understanding-the-ad-account-attributes-lastlogon-lastlogontimestamp-and-lastlogondate.aspx

如果您想要获得更精确的上次登录时间,则必须使用 lastLogon 属性,但该属性不会复制到所有域控制器,因此您必须遍历所有域控制器以获取最新值。您必须计算上次登录时间,然后才能将其限制为“最近 30/60/90 天”。

您可以在这里找到如何实现该算法来获取用户上次登录时间的示例:

Import-Module ActiveDirectory

function Get-ADUserLastLogon([string]$userName)
{
$dcs = Get-ADDomainController -Filter {Name -like "*"}
$time = 0
foreach($dc in $dcs)
{
$hostname = $dc.HostName
$user = Get-ADUser $userName | Get-ADObject -Properties lastLogon
if($user.LastLogon -gt $time)
{
$time = $user.LastLogon
}
}
$dt = [DateTime]::FromFileTime($time)
Write-Host $username "last logged on at:" $dt }
Get-ADUserLastLogon -UserName username

还有其他方法可以更轻松、更快地获得相同的结果。您可以尝试 Active Directory 报告工具 -AD FastReporter 免费版。它将为您进行精确的上次登录计算。只需安装它,转到“计算机”选项卡并选择 - “过去 30 天登录的计算机”,按“生成”。结果也将包括 DC 服务器,但您可以在导出到 .csv、.xlsx 文件后轻松删除它们。PS 我是此工具的所有者和开发者。

相关内容