如何在PowerShell foreach循环中输出去重后的唯一结果列表?
解决Active Directory登录日志去重问题
嘿,我明白你的困扰——现在输出一堆重复的登录条目,想只保留唯一的记录对吧?问题出在你现在是直接用Write-Host把结果打印出来,没有把这些数据结构化存储,所以后面的Get-Unique根本没法作用在这些输出上(因为Write-Host的内容不会进入管道)。
咱们换个思路,先把所有符合条件的登录信息存成自定义对象,再对这些对象做去重操作,这样就能得到你想要的唯一结果了。
修改后的完整代码
# Find DC list from Active Directory $DCs = Get-ADDomainController -Filter * # Define time for report (default is 1 day) $startDate = (Get-Date).AddDays(-1) # 创建一个数组来存储结构化的登录记录 $loginRecords = @() foreach ($DC in $DCs){ $slogonevents = Get-Eventlog -LogName Security -ComputerName $DC.HostName -After $startDate -InstanceId 4624 | Where-Object {$_.ReplacementStrings[5].ToLower() -eq "administrator"} foreach ($e in $slogonevents){ if ($e.EventID -eq 4624 -and $e.ReplacementStrings[8] -in 3..10){ if([ipaddress]::TryParse($e.ReplacementStrings[18],[ref][ipaddress]::Loopback)) { # 将每条记录封装成自定义对象 $record = [PSCustomObject]@{ Type = $e.ReplacementStrings[8] IPAddress = $e.ReplacementStrings[18] HostName = ([system.net.dns]::GetHostByAddress($e.ReplacementStrings[18])).HostName } # 添加到数组中 $loginRecords += $record } } } } # 对结构化数据去重并输出 $loginRecords | Select-Object -Unique -Property Type, IPAddress, HostName
关键修改点说明
- 新增了
$loginRecords数组来存储每个登录记录的结构化对象,而不是直接打印字符串 - 用
[PSCustomObject]把Type、IP、主机名封装成属性,这样后续可以基于这些属性精准去重 - 最后用
Select-Object -Unique指定要去重的属性,确保只要这三个属性都相同的记录只保留一条
额外优化建议
如果担心DNS解析失败(比如某些IP无法反查主机名),可以加个try-catch块避免报错中断:
try { $hostName = ([system.net.dns]::GetHostByAddress($e.ReplacementStrings[18])).HostName } catch { $hostName = "无法解析主机名" }
这样运行后,你就能得到每个唯一的登录条目啦!
内容的提问来源于stack exchange,提问作者ehh
相关产品推荐
相关产品推荐

