Powershell Security Log Get-EventLog - powershell

I am trying to write something up in powershell and completely new to powershell, I need help. What I'm trying to do is get information from the Security Log. Specifically, the last login for users over the last two weeks. The code that I have so far is getting login's for the event ID 4624 based on the last 100 events. This is also returning not just users but computers as well. How can I limit the results to just users over a period of two weeks? Is this even possible?
$eventList = #()
Get-EventLog "Security" -After $Date `
| Where -FilterScript {$_.EventID -eq 4624 -and $_.ReplacementStrings[4].Length -gt 10} `
| foreach-Object {
$row = "" | Select UserName, LoginTime
$row.UserName = $_.ReplacementStrings[5]
$row.LoginTime = $_.TimeGenerated
$eventList += $row
}
$eventList
EDIT: Solved with code
$Date = [DateTime]::Now.AddDays(-14)
$Date.tostring("MM-dd-yyyy"), $env:Computername
$eventList = #()
Get-EventLog "Security" -After $Date `
| Where -FilterScript {$_.EventID -eq 4624 -and $_.ReplacementStrings[4].Length -gt 10 -and $_.ReplacementStrings[5] -notlike "*$"} `
| foreach-Object {
$row = "" | Select UserName, LoginTime
$row.UserName = $_.ReplacementStrings[5]
$row.LoginTime = $_.TimeGenerated
$eventList += $row
}
$eventList

Use -before and -after parameters to filter the log by date. Use get-help get-eventlog -full to see all the parameters.

The users's last logon is stored in Active Directory. Seems like it would be a lot easier to pull it from there than chewing through event logs.

Use PowerShell to search the Active Directory:
Import-Module ActiveDirectory
Get-QADComputer -ComputerRole DomainController | foreach {
(Get-QADUser -Service $_.Name -SamAccountName username).LastLogon.Value
} | Measure-Latest

Related

powershell hashtable (export-Csv) to CSV

The following code in powershell creates a file with key/value pairs.
$result = #()
Get-EventLog -LogName Security -After ((Get-Date).AddDays(-5)) -InstanceId 4624 |
ForEach-Object {
if ($_.ReplacementStrings[5] -ne "SYSTEM")
{
$result += [PSCustomObject]#{
Time = $_.TimeGenerated
Workstation = $_.ReplacementStrings[11]
}
}
}
#$result | Export-Csv -Path .\Logins.csv -NoTypeInformation
$result | Out-File "C:\Temp\Logins.csv"
The above results in the following file contents:
However, I want the contents in CSV format. If I change the commented lines out as below:
$result = #()
Get-EventLog -LogName Security -After ((Get-Date).AddDays(-5)) -InstanceId 4624 |
ForEach-Object {
if ($_.ReplacementStrings[5] -ne "SYSTEM")
{
$result += [PSCustomObject]#{
Time = $_.TimeGenerated
Workstation = $_.ReplacementStrings[11]
}
}
}
$result | Export-Csv -Path .\Logins.csv -NoTypeInformation
#$result | Out-File "C:\Temp\Logins.csv"
Then I get the following:
Googling around through myriad pages and examples, I (mis?)understand this to be a hashtable and that the Export-Csv should work to create a csv file. I cannot seem to get it to work.
Any help is greatly appreciated.
Hmmm ... the following code works exactly like I'd expect it:
$result =
Get-EventLog -LogName Security -After ((Get-Date).AddDays(-5)) -InstanceId 4624 |
ForEach-Object {
if ($_.ReplacementStrings[5] -ne "SYSTEM") {
[PSCustomObject]#{
Time = $_.TimeGenerated
Workstation = $_.ReplacementStrings[11]
}
}
}
$result | Export-Csv -Path .\Logins.csv -NoTypeInformation
BTW: It is recommended not to use Get-Eventlog anymore. Use Get-WinEvent instead. ;-)
Another option could be just this:
Clear-Host
$result = #()
Get-EventLog -LogName Security -After ((Get-Date).AddDays(-1)) -InstanceId 4624 |
ForEach-Object {
if ($_.ReplacementStrings[5] -ne "SYSTEM")
{
$result += [PSCustomObject]#{
Time = $PSItem.TimeGenerated
Workstation = $PSItem.ReplacementStrings[11]
}
}
}
$result | ConvertTo-Csv -NoTypeInformation | Out-File -FilePath 'Logins.csv'
Get-Content -Path 'Logins.csv'
# Results
<#
"Time","Workstation"
...
"06-Aug-22 16:45:37","-"
"06-Aug-22 16:45:17","-"
"06-Aug-22 16:44:29","-"
...
#>
Update as per my comment.
The results are the same as the above, either to the screen or the file:
Clear-Host
(Get-EventLog -LogName Security -After ((Get-Date).AddDays(-1)) -InstanceId 4624) -ne 'SYSTEM' |
Select-Object -Property #{Name = 'Time';Expression = {$PSItem.TimeGenerated}},
#{Name = 'Workstation';Expression = {$PSItem.ReplacementStrings[11]}} |
Export-Csv -Path 'Logins.csv'
Get-Content -Path 'Logins.csv'

Get-EventLog with Append

So i have this code below that collects the stated EventIDs with the use of append. The problem is have is it only saves to a single file. What i want to do is save the collection to a daily file so i can do a daily report. A little help please?
$endtime = Get-Date
$starttime = (Get-Date).AddHours(-3)
$domain = "ComputerName"
$event = get-eventlog security -ComputerName $domain -after $starttime -before $endtime | where-object {($_.EventID -eq 4724) -or ($_.EventID -eq 4723) -or ($_.EventID -eq 4720)}
$event | select MachineName,EventID,TimeGenerated,Message | export-csv -path "E:\EventLogs\temp.csv"
get-content "E:\EventLogs\temp.csv" | out-File -filepath "E:\EventLogs\AccountAudit.csv" -append -enc ASCII -width 500
Export-Csv Has an -Append Parameter as well, you can shorten your code to:
$event = get-eventlog security -ComputerName $domain -after $starttime -before $endtime |
Where-object {($_.EventID -eq 4724) -or ($_.EventID -eq 4723) -or ($_.EventID -eq 4720)}
$event | select MachineName,EventID,TimeGenerated,Message |
Export-Csv -path "E:\EventLogs\AccountAudit.csv" -Append -Encoding ASCII
Simply add a get-start with some parameters to get a date that's filename friendly (no "/" for example) and save it in a variable. Then replace AccountAudit on the last line with the variable.

Filtering for newest security event records

I found some really nice code on how to display user logins from the past 14 days:
Powershell Security Log Get-EventLog
$Date = [DateTime]::Now.AddDays(-14)
$Date.tostring("MM-dd-yyyy"), $env:Computername
$eventList = #()
Get-EventLog "Security" -After $Date `
| Where -FilterScript {$_.EventID -eq 4624 -and $_.ReplacementStrings[4].Length -gt 10 -and $_.ReplacementStrings[5] -notlike "*$"} `
| foreach-Object {
$row = "" | Select UserName, LoginTime
$row.UserName = $_.ReplacementStrings[5]
$row.LoginTime = $_.TimeGenerated
$eventList += $row
}
$eventList
But my question is, how do I modify this code so that it selects the two newest records?
I tried the following:
Get-EventLog "Security" -After $Date `
| Where -FilterScript {$_.EventID -eq 4624 -and $_.ReplacementStrings[4].Length -gt 10 -and $_.ReplacementStrings[5] -notlike "*$"} `
| {-Newest 2}
And I get the error: Missing expression after unary operator '-'.
What is a clean way to get the last two logins, i.e. current login and the last person who logged in before the current user?
EDIT:Issue solved, here is complete code
$Date = [DateTime]::Now.AddDays(-14)
$Date.tostring("MM-dd-yyyy"), $env:Computername
$eventList = #()
Get-EventLog "Security" -After $Date `
| Where -FilterScript {$_.EventID -eq 4624 -and $_.ReplacementStrings[4].Length -gt 10 -and $_.ReplacementStrings[5] -notlike "*$"} `
| Select-Object -First 2 `
| foreach-Object {
$row = "" | Select UserName, LoginTime
$row.UserName = $_.ReplacementStrings[5]
$row.LoginTime = $_.TimeGenerated
$eventList += $row
}
$eventList
Instead of:
| {-Newest 2}
Try this:
| Select-Object -first 2

Query Multiple event id using Get-EventLog

I have a list of event id which I need to query on Multiple Server using PowerShell 2.0. Below is the script:
$a = Get-Date
$b = $a.AddDays(-1)
$b = $b.ToShortDateString();
$StartTime = "10:00:00 PM"
$EndTime = "11:00:00 PM"
$SMS_000 = "XXSMS01"
$SMS_SQL_000 = "XXXXXSQL01"
Get-EventLog -ComputerName $SMS_000, $SMS_SQL_000 -LogName Application -After $b -Before $b -Source "SMS Server" | ?{$_.EventID -eq 5055 -and $_.Event -eq 6829}
I would like to store the result into an obj which I shall then be passing to creation of an HTML report. The above is just a part of the process. Thanks!
$events = Get-EventLog -ComputerName $SMS_000, ...
However, you need to change your filter from
?{$_.EventID -eq 5055 -and $_.Event -eq 6829}
to
?{$_.EventID -eq 5055 -or $_.EventID -eq 6829}
because $_.Event isn't a valid property and one event can't have 2 different IDs.

Exclude results in a list (returned from Get-QADComputer)

List all active machineaccounts in the current domain
$ComputerScan = #(Get-QADComputer -sizelimit $sizelimit -IncludedProperties LastLogonTimeStamp -WarningAction SilentlyContinue -Inactive:$false -OSName $computerFilter | where {$_.AccountIsDisabled -eq $false} )
# Create list of computers
ForEach ($Computer in $ComputerScan){
$compObj = New-Object PsObject -Property #{
Computer = $computer
Credentials = $credentials
Domain = $domain
}
$computers += $compObj
}
I am doing a foreach on $computers after this but I would like to have a exclusionlist..
Preferably formatted like this
computer1
server4
computet4
But, how?
Greetings from Norway!
A few improvements to the computer query:
LastLogonTimeStamp is returned by default, no need to include it
-Inactive is $false by default, no need to specify it.
Instaed of using where-object, use ldap filters to get enabled computers
$computerScan = Get-QADComputer
-LdapFilter '(!(userAccountControl:1.2.840.113556.1.4.803:=2))'
-Sizelimit $sizelimit -WarningAction SilentlyContinue
-OSName $computerFilter |
Select-Object -ExpandProperty Name
$ComputerScan = #('blah', 'bluh', 'blih', 'bloh')
$ExclusionList = #('blih', 'blah')
$ComputerScan | where { $ExclusionList -notcontains $_ } | Write-Host