3

Windows Server 2008 R2

I'm trying to use PowerShell to get me a list of users who have logged into Remote Desktop Services (formerly known as Terminal Services) during the past day. With little understanding and much copy and pasting, I have this little script:

$a = (Get-Date).AddDays(-1)
Get-EventLog -LogName Security -after $a | Where-Object {($_.EventID -eq '4624') -and  $_.EntryType -eq 'SuccessAudit') -and ($_.Message | Select-String "Logon Type:\t\t\t10")}

The default output tells me things have happened and when they happened which is a good start. What I'd really like is to also display the User. Darned if I can figure out how to get the User and/or how to display it.

And that's my question: How can I add the username associated with that Event ID 4624 / Logon Type 10 event? Ideally I'd just like to show the login time and user name.

1
  • Good question +1
    – Chadddada
    Sep 27, 2011 at 20:47

2 Answers 2

6

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
1
  • A minor variation of your "Hence" example works delightfully. Thanks!
    – Chris_K
    Sep 22, 2011 at 17:24
3

I'd do it as follows -

$filter = "<QueryList>" + `
               "<Query Id=`"0`" Path=`"Security`">" + `
                    "<Select Path=`"Security`">" + `
                        "*[System[(EventID=4624) and " + `
                        "TimeCreated[@SystemTime&gt;='2011-09-21T06:00:00Z' and @SystemTime&lt;'2011-09-22T06:00:00Z']]] and " + `
                        "*[EventData[Data[@Name=`'LogonType`']=10]]" + `
                    "</Select>" + `
                    "<Suppress Path=`"Security`">" + `
                        "*[EventData[Data[@Name=`'LogonGuid`']=`'{00000000-0000-0000-0000-000000000000}`']]" + `
                    "</Suppress>" + `
               "</Query>" + `
          "</QueryList>"

Get-WinEvent -FilterXML $filter | 
%{ [xml]$xml = $_.ToXml()
   $xml.getElementsByTagName("Data") | where{$_.name -eq "TargetUserName"} | 
   select '#text'
}

EDIT: This now returns the names of the individuals. You can play around with what exactly you'd like to extract from that XML document.

Note: You'll need to putz around with the TimeCreated values (probably generate them on the fly). I included these so you could see the format they required.

Get-WinEvent will be much faster than Get-EventLog since the filtering will be done server-side instead of in the pipeline. You can also get a bit more specific on your queries by using the FilterXML parameter. The usernames associated with the logon events are in the Message property of the returned EventLogRecord.

2
  • A thing of beauty! However, it gives me the exact same output as what I currently have :-( How do I get the username in the output?
    – Chris_K
    Sep 22, 2011 at 15:01
  • Updated to extract just the names. I don't know exactly what you want to see on the output, so I'll let you sort that bit out. If you need help, ask.
    – pk.
    Sep 22, 2011 at 15:39

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .