ehh
ehh

Reputation: 3480

How to write to host a list of unique results from a for each loop in Powershell?

In the following code, I am getting a list of duplicate values. I am trying to have only one line for each duplicated lines, distinct.

This is the code:

# Find DC list from Active Directory
$DCs = Get-ADDomainController -Filter *

# Define time for report (default is 1 day)
$startDate = (get-date).AddDays(-1)

# Store successful logon events from security logs with the specified dates and workstation/IP in an array
foreach ($DC in $DCs){
$slogonevents = Get-Eventlog -LogName Security -ComputerName $DC.HostName  -after $startDate -InstanceId 4624 | where {$_.ReplacementStrings[5].ToLower() -eq "administrator"}

# Crawl through events; print all logon history with type, date/time, status, account name, computer and IP address if user logged on remotely

  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))
      {
        $type = $e.ReplacementStrings[8]
        $ip = $e.ReplacementStrings[18]
        $hostname=([system.net.dns]::GetHostByAddress($ip)).HostName

        write-host "Type:" $type "`tIP Address: " $ip  "`tHost Name: " $hostname             
      }
    }
  }
} Get-Unique #this does not work, also tried Unique

I am getting an output similar to the following"

Type: 3  IP Address: 192.168.1.1 Host Name: ABCD
Type: 3  IP Address: 192.168.1.1 Host Name: ABCD
Type: 3  IP Address: 192.168.1.1 Host Name: ABCD
Type: 3  IP Address: 192.168.1.2 Host Name: EFGH
Type: 3  IP Address: 192.168.1.2 Host Name: EFGH
Type: 3  IP Address: 192.168.1.2 Host Name: EFGH
Type: 3  IP Address: 192.168.1.1 Host Name: ABCD

I would like to get:

Type: 3  IP Address: 192.168.1.1 Host Name: ABCD
Type: 3  IP Address: 192.168.1.2 Host Name: EFGH

Upvotes: 0

Views: 588

Answers (1)

jrider
jrider

Reputation: 1640

I think the reason why you are not getting unique values is you are writing to host in your foreach loop, prior to the Unique. Essentially writing them out before it knows what is unique

What I would do is create a PSCustomObject and assign it within your foreach. This would allow you to call it later using | Select -Unique

# Find DC list from Active Directory
$DCs = Get-ADDomainController -Filter *

# Define time for report (default is 1 day)
$startDate = (get-date).AddDays(-1)

# Store successful logon events from security logs with the specified dates and workstation/IP in an array
foreach ($DC in $DCs){
$slogonevents = Get-Eventlog -LogName Security  -after $startDate -InstanceId 4624 | where {$_.ReplacementStrings[5].ToLower() -eq "administrator"}

# Crawl through events; print all logon history with type, date/time, status, account name, computer and IP address if user logged on remotely

  foreach ($e in $slogonevents){  
     $report = @() 
    if ($e.EventID -eq 4624 -and $e.ReplacementStrings[8] -In 3..10){            
      if([ipaddress]::TryParse($e.ReplacementStrings[18],[ref][ipaddress]::Loopback))
      {
        $object = New-Object PSCustomObject -Property @{
            type = $e.ReplacementStrings[8]
            ip = $e.ReplacementStrings[18]
            hostname=([system.net.dns]::GetHostByAddress($($e.ReplacementStrings[18]))).HostName        
        }
        $report += $object
      }
    }
  }
}
$report | select -Unique

Upvotes: 1

Related Questions