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.

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.

share|improve this question
    
Good question +1 –  Chadddada Sep 27 '11 at 20:47
add comment

2 Answers

up vote 5 down vote accepted

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
share|improve this answer
    
A minor variation of your "Hence" example works delightfully. Thanks! –  Chris_K Sep 22 '11 at 17:24
add comment

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.

share|improve this answer
    
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 '11 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 '11 at 15:39
add comment

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.