Skip to content

Instantly share code, notes, and snippets.

@ion-storm
Forked from automationhaus/Get-SecurityLogs.ps1
Created January 21, 2017 02:03
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save ion-storm/585436e3a91140419c5c47826200a2d5 to your computer and use it in GitHub Desktop.
Save ion-storm/585436e3a91140419c5c47826200a2d5 to your computer and use it in GitHub Desktop.
PowerShell function used to collect security events from a list of servers using a start date, end date, username or domain as needed
function Get-SecurityLogs
{
<#
.SYNOPSIS
Pulls security logs from the given list of computers using the given date range
.DESCRIPTION
Using the computername, startdate and enddate parameters you can pull the event logs for the given computers. Once the data is collected to a variable you can alter the output as needed.
.EXAMPLE
PS>Get-SecurityLogs
Collects the security logs for the last day on the local machine
.EXAMPLE
PS>Get-SecurityLogs -ComputerName "DC1","SQL1","FS1" -StartDate "11/21/2016"
Collects the security logs from the given start date to today on all the computers in the list
.EXAMPLE
PS>Get-SecurityLogs -ComputerName "DC1","SQL1","FS1" -StartDate $((Get-Date).AddDays(-14)) -EndDate $((Get-Date).AddDays(-7))
Collects the security logs from 2 weeks to 1 week ago on all the computers in the list
.EXAMPLE
PS>Get-SecurityLogs -UserName "username" -Domain "FABRIKAM" -EventID "4648","4624"
Check logon events for the last day pertaining to user username on the domain FABRIKAM
.EXAMPLE
PS>(Get-ADComputer -SearchBase "CN=Servers,DC=Fabrikam,DC=com").Name | Get-SecurityLogs -StartDate $((Get-Date).AddDays(-14)) -EndDate $((Get-Date).AddDays(-7))
Pipeline input from Get-ADComputer for each computer in the Servers OU
.OUTPUTS
Deserialized.Selected.System.Diagnostics.Eventing.Reader.EventLogRecord
.NOTES
Britt Thompson
bthompson@automation.haus
Some code sourced from http://bit.ly/2giP9yW
.LINK
https://gist.github.com/amesritter/82e0972de5d75135b0b6ac3a9e3977e3
#>
[CmdletBinding(SupportsShouldProcess=$true)]
Param
(
# ComputerName array of strings
[Parameter(
ValueFromPipeline=$true,
ValueFromPipelineByPropertyName=$true,
ValueFromRemainingArguments=$false,
Position=0,
ParameterSetName='Computer'
)]
[Alias("Computer")]
[string[]]$ComputerName = $env:COMPUTERNAME,
# Earliest date to collect logs from - last day by default
[Parameter()]
[datetime]$StartDate = (Get-Date).AddDays(-1),
# Latest date to collect logs from
[Parameter()]
[datetime]$EndDate = (Get-Date),
# Event IDs to search for - Logon / Logoff by default
[Parameter()]
[string[]]$EventID = @("4648","4647","4624","4634"),
# Usernames to include in the search - SubjectUserName
[Parameter()]
[string[]]$Username,
# Domain name to include inthe search - SubjectDomainName
[Parameter()]
[string]$DomainName
)
Begin
{
# Get time difference in milliseconds for the XML query
$LTMS = ((Get-Date) - $StartDate).TotalMilliseconds
$GTMS = ((Get-Date) - $EndDate).TotalMilliseconds
$EventIDs = @()
foreach($ID in $EventID){ $EventIDs += "(EventID=`"$ID`")" }
[string]$IDs = $EventIDs -join " or "
if($Username -or $DomainName)
{
# Generate the XML for all the usernames if they exist
$EventData = "*[EventData["
if($Username)
{
$Users = @()
$Username |
%{
$Users += "Data[@Name=`"SubjectUserName`"] and (Data=`"$_`")"
}
$EventData += $Users -join " or "
}
# Append the XML for the domain name if it exists
if($DomainName)
{
$EventData += " and Data[@Name=`"SubjectDomainName`"] and (Data=`"$_`")"
}
$EventData += "]] and "
} else { $EventData = $null }
}
Process
{
# Process if WhatIf not present
if ($PSCmdlet.ShouldProcess($ComputerName))
{
# Build the script block to use in the invoke-command
$SB = {
# XML filter for the date range in the security log
[xml]$FilterXML = @"
<QueryList>
<Query Id="0" Path="Security">
<Select Path="Security">
$Using:EventData
*[System[($Using:IDs)
and TimeCreated[timediff(@SystemTime) &lt;= $Using:LTMS
and timediff(@SystemTime) &gt;= $Using:GTMS]]]
</Select>
</Query>
</QueryList>
"@
try
{
$ErrorActionPreference = "Stop"
$Events = Get-WinEvent -FilterXml $FilterXML
foreach ($Event in $Events)
{
# Convert the event to XML
$EventXML = [xml]$Event.ToXml()
# Iterate through each one of the XML message properties
for ($i=0; $i -lt $EventXML.Event.EventData.Data.Count; $i++)
{
# Append these as object properties
Add-Member -InputObject $Event -MemberType NoteProperty -Force `
-Name $EventXML.Event.EventData.Data[$i].name `
-Value $EventXML.Event.EventData.Data[$i].'#text'
}
}
$Events | Select-Object *
}
catch
{
if($_.Exception -match "No events were found")
{
Write-Warning "[$(hostname)] No events found"
} else { $_ }
}
}
# Run the command on all the computers in the list
Invoke-Command -ScriptBlock $SB -ComputerName $ComputerName
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment