locked
Need help in trying to extract user info from logon event ID 4672 RRS feed

  • Question

  • I would like to extract the following information from the Message property:

    • Security Identifier
    • Account Name
    • Account Domain. 


    So far what I have is:

    $UserLastLogonEvent = Get-WinEvent -Computer misw7v-120 -FilterHashtable @{Logname='Security';ID=4672} -MaxEvents 1
    $UserLastLogonEvent | Format-List 


    The output is:



    TimeCreated  : 6/22/2016 3:30:38 PM

    ProviderName : Microsoft-Windows-Security-Auditing

    Id           : 4672

    Message      : Special privileges assigned to new logon.

                   

                   Subject:

                       Security ID:        

                   S-1-5-22-67644591-240755714-2144928816-55394

                       Account Name:        jdoe

                       Account Domain:        BIGCORP

                       Logon ID:        0x1eb0edd

                   

                   Privileges:        SeSecurityPrivilege

                               SeBackupPrivilege

                               SeRestorePrivilege

                               SeTakeOwnershipPrivilege

                               SeDebugPrivilege

                               SeSystemEnvironmentPrivilege

                               SeLoadDriverPrivilege

                               SeImpersonatePrivilege 

    I am trying to learn string manipulation using regex, but I am far from an expert and I would be eternally grateful to anyone who can help me in solving this problem. The data that I need to extract from the Message property in the output above is bolded. 

    Thank you so much. 

    Wednesday, June 22, 2016 10:37 PM

Answers

  • Simple stuff:

    PS > $x=Get-WinEvent -FilterHashtable @{Logname='Security';ID=4672} -MaxEvents 1
    PS > '{0}\{1}' -f $x.Properties[1].Value,$x.Properties[2].Value
    SYSTEM\NT AUTHORITY


    \_(ツ)_/

    Wednesday, June 22, 2016 11:19 PM
  • Edited JRV Code

    $x=Get-WinEvent -FilterHashtable @{Logname='Security';ID=4672} -MaxEvents 1
    '{0}\{1}\{2}' -f $x.Properties[0].Value,$x.Properties[1].Value,$x.Properties[2].Value
    
    SID\Account\Domain

    Thursday, June 23, 2016 8:57 AM
  • Using properties:


    $event = Get-WinEvent -FilterHashtable @{ LogName='Security'; ID=4672 } -MaxEvents 1
    $sidString = ($event.Properties[0]).Value
    $sid = [Security.Principal.SecurityIdentifier] $sidString
    $accountName = $sid.Translate([Security.Principal.NTAccount]).Value
    # $accountName now contains DOMAIN\accountname
    


    -- Bill Stewart [Bill_Stewart]



    Thursday, June 23, 2016 12:29 PM

All replies


  • $eventString = Get-WinEvent -FilterHashtable @{ LogName='Security'; ID=4672 } -MaxEvents 1 |
      Select-Object -ExpandProperty Message
    $sidString = $eventString | Select-String 'Security ID:\W+([\w-]+)' |
      ForEach-Object { $_.Matches[0].Groups[1].Value }
    $sid = [Security.Principal.SecurityIdentifier] $sidString
    $accountName = $sid.Translate([Security.Principal.NTAccount]).Value
    # $accountName contains DOMAIN\accountname from event string
    


    -- Bill Stewart [Bill_Stewart]


    Wednesday, June 22, 2016 10:53 PM
  • Simple stuff:

    PS > $x=Get-WinEvent -FilterHashtable @{Logname='Security';ID=4672} -MaxEvents 1
    PS > '{0}\{1}' -f $x.Properties[1].Value,$x.Properties[2].Value
    SYSTEM\NT AUTHORITY


    \_(ツ)_/

    Wednesday, June 22, 2016 11:19 PM
  • FANTASTIC!!

    You both are BEAUTIFUL!

    BUT, I also needed the SID as well. 

    Can you perform your magic once more to help me extract that?

    Thank you very much. 


    Thursday, June 23, 2016 12:13 AM
  • jrv, what resource can I read that will help me to better understand how you did this?

    Thanks

    Thursday, June 23, 2016 6:12 AM
  • Edited JRV Code

    $x=Get-WinEvent -FilterHashtable @{Logname='Security';ID=4672} -MaxEvents 1
    '{0}\{1}\{2}' -f $x.Properties[0].Value,$x.Properties[1].Value,$x.Properties[2].Value
    
    SID\Account\Domain

    Thursday, June 23, 2016 8:57 AM
  • Using properties:


    $event = Get-WinEvent -FilterHashtable @{ LogName='Security'; ID=4672 } -MaxEvents 1
    $sidString = ($event.Properties[0]).Value
    $sid = [Security.Principal.SecurityIdentifier] $sidString
    $accountName = $sid.Translate([Security.Principal.NTAccount]).Value
    # $accountName now contains DOMAIN\accountname
    


    -- Bill Stewart [Bill_Stewart]



    Thursday, June 23, 2016 12:29 PM
  • Would anyone know how to extract the Logon Type by any chance, such as in the following example:

    TimeCreated  : 6/26/2016 11:34:08 AM

    ProviderName : Microsoft-Windows-Security-Auditing

    Id           : 4624

    Message      : An account was successfully logged on.

                   

                   Subject:

                       Security ID:        S-1-0-0

                       Account Name:        -

                       Account Domain:        -

                       Logon ID:        0x0

                   

                   Logon Type:            3 


    Thursday, June 30, 2016 11:30 PM
  • It is different for every Event Code.  You have to look it up in the Event Viewer as we have shown you or use an XML query as I have also shown you.


    \_(ツ)_/

    Thursday, June 30, 2016 11:56 PM
  • I just now realized that I can use the filter current log and select the properties I want and it will produce the xml query for me. 

    Thanks 

    Friday, July 1, 2016 4:46 AM

  • It will not create the "LogonType" filter.  That must be added manually.  I posted that for you 5 days ago.


    \_(ツ)_/

    Friday, July 1, 2016 5:06 AM
  • I figured it out by doing the following:

    $Event = Get-WinEvent -ComputerName MyComputer -FilterHashtable @{Logname='Security';ID='4624'} -MaxEvents 1 
    
    $EventXML = [xml]$Event.ToXml()
    
    $EventProperties = [pscustomobject] @{
    
        'UserSID' = $EventXML.Event.EventData.Data[4].'#text'
        'UserName' = $EventXML.Event.EventData.Data[5].'#text'
        'UserDomain' = $EventXML.Event.EventData.Data[6].'#text'
        'LogonType' = $EventXML.Event.EventData.Data[8].'#text'
    }
    
    Switch ($EventProperties.LogonType )
    {
        '2'
        {
            $LastLoggedOnUser = $EventProperties.UserName
        }
    
        '10'
        {
            $LastLoggedOnUser = $EventProperties.UserName
        }
    }
    
    $LastLoggedOnUser



    Friday, July 1, 2016 4:27 PM
  • You managed to discover the absolute hardest and most convoluted way to do this.

    Why n0t just use "Properties[8].Value"?

    Your method still won't work because the one record returned will not be the one you want.  You must either return all records and search the result or use an XML query to find the logontype and the last one of the type.  This cannot be done with your method.  Think about it for a while and you will see why it won't work.

    Only an XML query that is hand coded will do what you are trying to do.


    \_(ツ)_/

    Friday, July 1, 2016 4:53 PM
  • Will this be the right way to do

    Just want to know

    $ev = (Get-WinEvent  -Computer Home -FilterHashtable @{Logname='Security';ID=4624} -MaxEvents 20 | 
                          Where { $_.properties[8].value -eq 2})
    '{0}\{1}\{2}' -f $ev.properties[5].Value , $ev.properties[0].Value , $ev.properties[6].Value

    Output

    Vincent\S-1-5-18\HOME

    Friday, July 1, 2016 6:58 PM
  • Well I finally had the time to go over your post here: 

    https://social.technet.microsoft.com/Forums/windowsserver/en-US/1fdb977d-792f-4a1e-b605-6696ad1074de/4624-logon-events-followed-closely-by-4634-logoff-events?forum=winserverpowershell#657a710d-0aa1-4634-9c11-49bfab0fec2f

    This was BADASS info jrv thanks!!

    It helped me do EXACTLY what I wanted. 

    Here is what I did and please let me know how this looks:

     $xmlquery=@'
    <QueryList>
      <Query Id="0" Path="Security">
        <Select Path="Security">
    		*[System[(EventID='4624')]]
    		and
    		*[EventData[Data[@Name='LogonType'] and (Data='2')]]
    		or
    		*[EventData[Data[@Name='LogonType'] and (Data='10')]]
    	</Select>
      </Query>
    </QueryList>
    '@
    $props1 = @( <# 4624 #>
    	'TimeCreated',
    	'ID',
    	@{ n = 'SecurityId'; e = { $_.Properties[4].Value } },
    	@{ n = 'AccountName'; e = { $_.Properties[5].Value } },
    	@{ n = 'AccountDomain'; e = { $_.Properties[6].Value } },
    	@{ n = 'LogonId'; e = { $_.Properties[7].Value } }
    )
    $events=Get-WinEvent -FilterXml $xmlquery -ComputerName MyComputer -MaxEvents 1 |
    ForEach-Object{
    	if ($_.ID -eq 4624) {
    		$_ | select $props1 
    	}
    }
    $events | Format-List 

    jrv ROCKS!!

    Friday, July 1, 2016 7:12 PM
  • Will this be the right way to do

    Just want to know

    $ev = (Get-WinEvent  -Computer Home -FilterHashtable @{Logname='Security';ID=4624} -MaxEvents 20 | 
                          Where { $_.properties[8].value -eq 2})
    '{0}\{1}\{2}' -f $ev.properties[5].Value , $ev.properties[0].Value , $ev.properties[6].Value

    Output

    Vincent\S-1-5-18\HOME

    No . Even that won't work much of the time.  You MUST use an XML query.  It will extract only the last type 2 or 10 record and by using the name for the data attribute "LogonType".  This same query can be used across multiple record types in the same query.

    Be aware that the event data is stored as compressed XML>  XML queries are native.  Other types are for simple convenience but cannot do what a full query can do.


    \_(ツ)_/

    Friday, July 1, 2016 7:13 PM
  • Here is an example of an XML query:
     $xmlquery=@'
    <QueryList>
      <Query Id="0" Path="Security">
        <Select Path="Security">
    		*[System[(EventID='4624')]]
    		and
    		*[EventData[Data[@Name='LogonType'] and (Data='2')]]
    		or
    		*[EventData[Data[@Name='LogonType'] and (Data='10')]]
    	</Select>
      </Query>
    </QueryList>
    '@
    Get-WinEvent -FilterXml $xmlquery -ComputerName MyComputer -MaxEvents 1
    This was used to this OP almost a week ago.   It pulls both type 2 and 10 types in one query It is very fast and can easily be modified to return a specific user or users.

    \_(ツ)_/


    • Edited by jrv Friday, July 1, 2016 7:18 PM
    Friday, July 1, 2016 7:17 PM

  • No . Even that won't work much of the time.  You MUST use an XML query.  It will extract only the last type 2 or 10 record and by using the name for the data attribute "LogonType".  This same query can be used across multiple record types in the same query.

    Be aware that the event data is stored as compressed XML>  XML queries are native.  Other types are for simple convenience but cannot do what a full query can do.


    \_(ツ)_/

    Thanks for the reply. Will look into XML Query
    Friday, July 1, 2016 7:18 PM
  • Well I finally had the time to go over your post here: 

    https://social.technet.microsoft.com/Forums/windowsserver/en-US/1fdb977d-792f-4a1e-b605-6696ad1074de/4624-logon-events-followed-closely-by-4634-logoff-events?forum=winserverpowershell#657a710d-0aa1-4634-9c11-49bfab0fec2f

    The plus is that, once you understand how it works, you have absolute dominance over every data item in the eventlogs and can produce extremely powerful queries.  Every Admin should place learning this at the top of their to-do list.


    \_(ツ)_/

    Friday, July 1, 2016 7:21 PM
  • Touche

    I changed this a bit to the following, because I really like to use the [pscustomobject] accelerator:

    $XMLQuery=@'
    <QueryList>
      <Query Id="0" Path="Security">
        <Select Path="Security">
    		*[System[(EventID='4624')]]
    		and
    		*[EventData[Data[@Name='LogonType'] and (Data='2')]]
    		or
    		*[EventData[Data[@Name='LogonType'] and (Data='10')]]
    	</Select>
      </Query>
    </QueryList>
    '@
    
    $Events = Get-WinEvent -FilterXml $XMLQuery -ComputerName MyComputer -MaxEvents 1 
    
    Foreach ($Event in $Events)
    {
        [pscustomobject] @{
            
            'UserDomain' = $Event.Properties[6].Value
            'UserLastLogonDateTime' = $Event.TimeCreated
            'UserLogonType' = $Event.Properties[8].Value
            'UserName' = $Event.Properties[5].Value
            'UserSID' = $Event.Properties[4].Value
        }
    }

    Beautiful stuff, jrv!!

    Thanks again man. 


    Friday, July 1, 2016 7:58 PM
  • Unfortunately that won't work/ for all  event codes.  You can use the XML to explicitly extract values by name:

    This I didn't show in my example because I was trying to focus on the XML query.

    Here is an example of the quick and reliable way to extract fields by name;

    PS > [xml]$evt=$events.ToXml() -replace "xmlns='http://schemas.microsoft.com/win/2004/08/events/event'"
    PS > $evt.SelectSingleNode('//Data[@Name="TargetUserName"]').'#text'
    DWM-6
    PS > $evt.SelectSingleNode('//Data[@Name="LogonType"]').'#text'
    2
    


    \_(ツ)_/


    • Edited by jrv Friday, July 1, 2016 8:14 PM
    Friday, July 1, 2016 8:14 PM
  • you are saying the way I am using [pscustomobject] wont work for all event codes?

    It seems to be working pretty well for 4624 at this point. 

    I will check out what you have recommended. 

    Thanks again for you help brother

    Friday, July 1, 2016 8:24 PM
  • you are saying the way I am using [pscustomobject] wont work for all event codes?

    It seems to be working pretty well for 4624 at this point. 

    I will check out what you have recommended. 

    Thanks again for you help brother

    Yes but other event code from that provider that we can retrieve in the same query will not necessarily have the items at the same index but they will be the same name.  By using XML we can query by name so position becomes irrelevant.


    \_(ツ)_/

    Friday, July 1, 2016 8:29 PM
  • Yep, I just now discovered the index issue. 

    Thanks a million.

    Friday, July 1, 2016 8:44 PM

  • PS > [xml]$evt=$events.ToXml() -replace "xmlns='http://schemas.microsoft.com/win/2004/08/events/event'"
    PS > $evt.SelectSingleNode('//Data[@Name="TargetUserName"]').'#text'
    DWM-6
    PS > $evt.SelectSingleNode('//Data[@Name="LogonType"]').'#text'
    2

    That is just SICK!!

    I used your quick and reliable method and I got what I need now. 

    AWESOME stuff!!

    Thanks jrv you seriously kick ass man. 

    If I don't have another issue before the 4th, have a great weekend and a great Independence Day everyone. 


    Friday, July 1, 2016 9:01 PM
  • Our technologies today are extremely sophisticated.  Once you learn the fundamental aspects of program flow control, declarative structure, data manipulation and how the OS supports these and other generalizations you can do powerful things on any platform.

    Keep seeking.  There are more surprises.  These are not my things but are the basics of modern computer systems engineering.


    \_(ツ)_/

    Friday, July 1, 2016 9:05 PM
  • If I don't have another issue before the 4th, have a great weekend and a great Independence Day everyone. 


    Thank you and have a good Fourth.

    \_(ツ)_/

    Friday, July 1, 2016 9:07 PM