Take the 2-minute tour ×
Server Fault is a question and answer site for professional system and network administrators. It's 100% free, no registration required.

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
share|improve this question
    
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

4 Answers 4

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.

share|improve this answer

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.

share|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

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.

share|improve this answer

The help for Group-Object in Poweshell has very similar example:

get-eventlog -logname system -newest 1000 | group-object -property {$_.TimeWritten - $_.TimeGenerated}

you can easily swap some of the parameters:

Get-EventLog system -after (Get-Date).adddays(-2) | ?{($_.EntryType -like "Error") -or ($_.EntryType -like "Warning")} | group -property index | ?{$_.count -gt 1}

This will get all the system log entries for the last 48 hours that are Errors or Warnings and group them by their index. This is uniquely assigned number for each log entry that you can use to identify duplicates. The last part simply filters out all of the entries that are unique and leaves the duplicate ones.

If you want to check for uniqueness in the messages then use this:

Get-EventLog system -after (Get-Date).adddays(-2) | ?{($_.EntryType -like "Error") -or ($_.EntryType -like "Warning")} | group -property messages -noelement

This shows the count of the unique messages in the given log interval.

share|improve this answer

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

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