First I would suggest using the Get-WinEvent
and passing a hash to do as much filtering as possible there (and thus avoid creating lots of objects Where-Object
will throw away):
Get-WinEvent -filterHashtable @{LogName='Security'; StartTime=$a; Id=4624; Level=0}
Level 0 is success audit. This can be performed remotely with the -computer
parameter. Then filter the results to get the login type:
... | Where-Object { $_.Message -match 'Logon Type:\s+10'}
Using a regex to avoid hardcoding the whitespace.
To extract the user and domain from the message would be a little awkward as there are two "Account Name' values: one for the computer and one for the user. But all the replaceable values inserting into the (localisable) message text are in the event's Properties property, so a little checking to see the indexes with a sample1
... | Select-Object *, @{l='LogonAccount';e={$_.Properties[6].Value + "\" + $_.Properties[5].Value }}
Clearly capturing other details (eg. SID, client IP) follows the same pattern.
Hence:
Get-WinEvent -filterHashtable @{LogName='Security'; StartTime=$a; Id=4624; Level=0} |
Where-Object { $_.Properties[8].Value -eq 10} |
Select-Object *, @{l='LogonAccount';e={$_.Properties[6].Value + "\" + $_.Properties[5].Value }}
1 With a single event in $ev
I used:
0..($ev.Properties.Count-1) | Select @{l='Idx';e={$_}},@{l='Property';e={$ev.Properties[$_].Value}} |
ft -auto
to give (with a little censorship, and noting a better way to get the logon type at index #8):
Idx Property
--- --------
0 S-1-5-18
1 *Computer's account*
2 *Computer's Domain*
3 999
4 *User's SID*
5 *User's user name*
6 *User's Domain*
7 151556
8 10
9 User32
10 Negotiate
11 *Computer's Name*
12 00000000-0000-0000-0000-000000000000
13 -
14 -
15 0
16 2964
17 C:\Windows\System32\winlogon.exe
18 *Client IP*
19 15532