up vote 0 down vote favorite
share [g+] share [fb]

Can someone describe a good pattern to compare $entry[X] to $entry[Y] to determine if they are the same? I'm trying to get readable summaries of my logs and don't want to spit out 400 identical lines.

foreach ($log in $logs) {

	$nm = $log.LogDisplayName

	$header = $log.LogDisplayName
	Write-Host $header
	Add-Content $output "$header Log Errors/Warnings, Past 48 Hours"

	$entries = $log.Entries | ? {$_.TimeWritten -gt ($(Get-Date).AddDays(-2)) -and (($_.EntryType -like "Error") -or ($_.EntryType -like "Warning"))}

	foreach ($entry in $entries) { 


		***here is where I think I need to compare array elements***


	}


	out-string -inputobject $entries | add-content $output
link|improve this question

68% accept rate
Do you want to check whether each line is unique within the file or whether a line is the same as the previous line? – Dennis Williamson Sep 16 '09 at 13:11
Just the previous line. Actually, I probably will want to see if some portion of the lines are the same, but I'll cross that bridge after I figure out how to compare each line with its predecessor in general. – Doug Chase Sep 16 '09 at 13:33
feedback

3 Answers

To compare the current entry to the previous one:

$preventry = ""
$newarray = $()
foreach ($entry in $entries) {
    if ($entry -ne $preventry) { $newarray += @($entry) }
    $preventry = $entry
}

The resulting array $newarray contains all the contents of $entries but with the adjacent duplicates removed.

link|improve this answer
feedback

You might try:

$entry | sort-object -unique
$entry | sort-object -property TimeWritten

(if that's the appropriate field).

The idea is to get rid of duplicates then put it back in the original order.

link|improve this answer
feedback

Select-Object is your friend for this sort of task.

Here's how you can eliminate any duplicates from a collection of strings:

[123] PS↑ C:\> 'a','b','b','c','d','e','e','f','g' | Select-Object -Unique
a
b
c
d
e
f
g

If you're working with objects with multiple properties though, that won't be very helpful if the string representation of the object is the same for every object (e.g. Get-Service | Select-Object -Unique returns one object because all service objects convert to System.ServiceProcess.ServiceController when converted to a string, which cannot be used to uniquely identify a service). In cases like that you need to specify which property you want to check for uniqueness.

Here's another example, that shows you how to get a list of the unique extensions of files in the current directory:

Get-ChildItem | Select-Object -Property Extension -Unique

One of these two techniques should help you get the unique collection you are looking for.

link|improve this answer
$entries = $entries | select-object -unique – Dennis Williamson Sep 16 '09 at 15:26
By the way, I get a "positional parameter" error because of the sequence of letters at the end of your command. – Dennis Williamson Sep 16 '09 at 15:29
The script isn't showing up correctly here. Something to do with the newline character that is being used. The sequence of letters after -Unique should be each on their own line immediately below the command (they are the output of the command). – Poshoholic Oct 15 '09 at 19:19
There, fixed the output now by moving the command and output into a code block. Thanks for pointing out that it didn't paste correctly. – Poshoholic Oct 15 '09 at 19:31
feedback

Your Answer

 
or
required, but never shown

Not the answer you're looking for? Browse other questions tagged or ask your own question.