问题
I am attempting to view the last 5 login events on an Enterprise machine as an Admin after a security event. I do initial investigations and am trying to find a way to quickly spit out a list of potential, 'suspects'.
I have been able to generate output that lists the logfile but under account name where you would generally see \Domain\username I only get the output, "SYSTEM" or similar.
If I had recently remoted into the machine it will pull my \Domain\Username and display it no problem.
Ideally I would like to make a script that pulls the logon events from a machine on the network with a list of who logged in recently and when.
This is what I have so far:
Get-EventLog -LogName security -InstanceId 4624 -ComputerName $_Computer -Newest 5 | Export-Csv C:\Users\username\Documents\filename
回答1:
I've been fiddling with this too and also decided to use the Get-WinEvent cmdlet for this, because unfortunately, using Get-EventLog the info you want is all in the .Message item and that is a localized string..
My approach is a little different than Lee_Daily's answer as I get the info from the underlying XML like this:
#logon types: https://docs.microsoft.com/en-us/windows/desktop/api/ntsecapi/ne-ntsecapi-_security_logon_type#constants
$logonTypes = 'System','Undefined','Interactive','Network','Batch','Service','Proxy','Unlock',
'NetworkCleartext','NewCredentials','RemoteInteractive','CachedInteractive',
'CachedRemoteInteractive','CachedUnlock'
$dataItems = @{
SubjectUserSid = 0
SubjectUserName = 1
SubjectDomainName = 2
SubjectLogonId = 3
TargetUserSid = 4
TargetUserName = 5
TargetDomainName = 6
TargetLogonId = 7
LogonType = 8
LogonProcessName = 9
AuthenticationPackageName = 10
WorkstationName = 11
LogonGuid = 12
TransmittedServices = 13
LmPackageName = 14
KeyLength = 15
ProcessId = 16
ProcessName = 17
IpAddress = 18
IpPort = 19
}
$result = Get-WinEvent -FilterHashtable @{LogName="Security";Id=4624} -MaxEvents 100 | ForEach-Object {
# convert the event to XML and grab the Event node
$eventXml = ([xml]$_.ToXml()).Event
# get the 'TargetDomainName' value and check it does not start with 'NT AUTHORITY'
$domain = $eventXml.EventData.Data[$dataItems['TargetDomainName']].'#text'
if ($domain -ne 'NT AUTHORITY' ) {
[PSCustomObject]@{
Domain = $domain
UserName = $eventXml.EventData.Data[$dataItems['TargetUserName']].'#text'
UserSID = $eventXml.EventData.Data[$dataItems['TargetUserSid']].'#text'
LogonType = $logonTypes[[int]$eventXml.EventData.Data[$dataItems['LogonType']].'#text']
Date = [DateTime]$eventXml.System.TimeCreated.SystemTime
Computer = $eventXml.System.Computer
}
}
}
$result | Sort-Object Date -Descending | Group-Object -Property UserName | ForEach-Object {
if ($_.Count -gt 1) { $_.Group[0] } else { $_.Group }
} | Format-Table -AutoSize
On my machine the output looks like
Domain UserName UserSID LogonType Date Computer
------ -------- ------- --------- ---- --------
MyDomain MyUserName S-1-5-21-487608883-1237982911-748711624-1000 Interactive 27-1-2019 20:36:45 MyComputer
MyDomain SomeoneElse S-1-5-21-487608883-1237982911-748765431-1013 Interactive 27-1-2019 18:36:45 MyComputer
回答2:
this uses the far faster Get-WinEvent cmdlet & the -FilterHashtable parameter to both speed things up a tad and to add more selectors. you may want to remove some of the filters - this was written quite some time ago for another project. [grin]
#requires -RunAsAdministrator
# there REALLY otta be a way to get this list programmatically
$LogonTypeTable = [ordered]@{
'0' = 'System'
'2' = 'Interactive'
'3' = 'Network'
'4' = 'Batch'
'5' = 'Service'
'6' = 'Proxy'
'7' = 'Unlock'
'8' = 'NetworkCleartext'
'9' = 'NewCredentials'
'10' = 'RemoteInteractive'
'11' = 'CachedInteractive'
'12' = 'CachedRemoteInteractive'
'13' = 'CachedUnlock'
}
$EventLevelTable = [ordered]@{
LogAlways = 0
Critical = 1
Error = 2
Warning = 3
Informational = 4
Verbose = 5
}
$WantedLogonTypes = @(2, 3, 10, 11)
$AgeInDays = 15
$StartDate = (Get-Date).AddDays(-$AgeInDays)
$ComputerName = $env:COMPUTERNAME
$GWE_FilterHashTable = @{
Logname = 'Security'
ID = 4624
StartTime = $StartDate
#Level = 2
}
$GWE_Params = @{
FilterHashtable = $GWE_FilterHashTable
ComputerName = $ComputerName
MaxEvents = 100
}
$RawLogonEventList = Get-WinEvent @GWE_Params
$LogonEventList = foreach ($RLEL_Item in $RawLogonEventList)
{
$LogonTypeID = $RLEL_Item.Properties[8].Value
if ($LogonTypeID -in $WantedLogonTypes)
{
[PSCustomObject]@{
LogName = $RLEL_Item.LogName
TimeCreated = $RLEL_Item.TimeCreated
UserName = $RLEL_Item.Properties[5].Value
LogonTypeID = $LogonTypeID
LogonTypeName = $LogonTypeTable[$LogonTypeID.ToString()]
}
}
}
$NewestLogonPerUser = $LogonEventList |
Sort-Object -Property UserName |
Group-Object -Property UserName |
ForEach-Object {
if ($_.Count -gt 1)
{
$_.Group[0]
}
else
{
$_.Group
}
}
$NewestLogonPerUser
current output on my system ...
LogName : Security
TimeCreated : 2019-01-24 1:50:44 PM
UserName : ANONYMOUS LOGON
LogonTypeID : 3
LogonTypeName : Network
LogName : Security
TimeCreated : 2019-01-24 1:50:50 PM
UserName : [MyUserName]
LogonTypeID : 2
LogonTypeName : Interactive
来源:https://stackoverflow.com/questions/54385710/remote-powershell-find-last-5-user-logins