Jump to content

Powershell help needed with ForEach-Object cmdlet


Recommended Posts

Posted (edited)

I'm a newbie to PS and am really enjoying it but still wrapping my head around alot of the commands and how to use them. I have an issue which I'm hoping someone on this forum will be able to assist me with getting working.

 

My task at hand is as follows:

- I have daily log files in csv format that contain all of a user's daily logins.

- I have created a file containing only the date and the user id as shown below.

- What I need to do is get each user's last\most recent logon.

 

DATE USER

Sat Dec 25 00:41:59 EST 2010 user1

Sat Dec 25 00:41:58 EST 2010 user1

Fri Dec 24 17:54:13 EST 2010 user8

Fri Dec 24 17:54:12 EST 2010 user8

Fri Dec 24 17:54:08 EST 2010 user8

Fri Dec 24 17:52:56 EST 2010 user8

Fri Dec 24 17:52:46 EST 2010 user8

Fri Dec 24 17:52:39 EST 2010 user8

Fri Dec 24 17:42:01 EST 2010 user8

Fri Dec 24 17:41:36 EST 2010 user8

Fri Dec 24 17:36:16 EST 2010 user8

Fri Dec 24 17:35:18 EST 2010 user2

Fri Dec 24 17:33:51 EST 2010 user2

 

- What I have so far after creating the csv file containing only the rows I wanted, namely date and user

 

- I used: $Users = Import-Csv "./logfile.csv" | sort-object User, Date to sort the file by user and then date.

 

- The next step is where I'm unsure how to proceed, I assume I need to perform something along the following lines:

 

| Foreach-Object ($user in $users) {determine each users latest login} I only want the one line for each user (bolded line), I just can't figure out how to do that, any help would be very greatly appreciated! Hope that makes sense.

 

S

Edited by Shark
Posted (edited)

Can't figure it out generally (the algorithm) or specifically (the power shell code to implement that)? The general approach would be

 

# Set Compare string to some value that will never be a username
CompUser = "XXXXXXXXHJGASDLASHG"

foreach user in users

  # If the current user is not the same as the compare string, then the user has changed
  # and since the data is sorted in order of latest login first, then every time the user changes
  # we have our target.

  if CompUser <> user then
     print user, date
     # Set the comparison to this user so we effectively ignore other older entries for this user
     CompUser = user
  end if

next

 

That's not powershell code - just the general case.

Edited by pcstru
Posted

Hi Pcstru,

 

That was very helpful!, I got the script working to this point. question now is - sorting by user is fine but how do I sort on the 'date' property as secondary after 'user' property since it's in the weird format below?:

Date NoteProperty System.String Date=Sat Dec 25 00:41:59 EST 2010

 

A second question which could make the sort unnecessary, the Group-object cmdlet is very nice as it groups each user, do you know how to set or retrieve the first entry of 'date' from the group-object?

 

 

 

$users = Import-Csv E:\PSDevScripts\auditlogbackup_1226*.csv #| Sort-Object User, Date #| group-object -property {$_.user)

 

$UserComp = "abcdef"

 

Foreach ($user in $users)

{

 

if ($user.user -ine $UserComp)

{

$userComp = $user.user

# will write user to output file

}

else

}

Posted

I think the problem for the sort is that it's interpreting the date as a string. You either need a different format in the file or you need to convert to a date. If the sort worked on the dates you wouldn't need the grouping (which is just a sort of sorts)

 

The indexof function would help you parse the date out of the string (by finding the position of the "="). You could then use ParseExact to convert that part of the string into a date type. If you then use the same concept of storing a date before any possible date and then compare to the date you have parsed out and if it is later than the comparison, set that to be the latest date. Then when the user changes, print the user and the date tracking variable, then set the user to the next value and the date back to a value before any possible values in the file.

 

You do have hashes (dictionaries) available so you could, since you need to parse the whole file anyway, do the whole thing more quickly in one pass by using the username as a key for the date comparitor. At end of file you would have a hash containing all the unique users with the value being the latest date. Much more efficient but somewhat more advanced and difficult to write.

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now



×
×
  • Create New...