Skip to content

Instantly share code, notes, and snippets.

@littletoyrobots
Created October 7, 2021 00:53
Show Gist options
  • Save littletoyrobots/bcd78f4bc27f721dc5da65fb7cbebde2 to your computer and use it in GitHub Desktop.
Save littletoyrobots/bcd78f4bc27f721dc5da65fb7cbebde2 to your computer and use it in GitHub Desktop.
<#
.SYNOPSIS
Get-WinEvent with xml property expansion
.EXAMPLE
This will get user logoff events from localhost & 'target1' for user 'User42'
$WinEventParams = @{
ComputerName = $env:COMPUTERNAME, 'target1'
LogName = 'Security'
ID = 4647, 4634
Data = 'User42'
}
Get-WinEventHelper @WinEventParams
.NOTES
Author(s) - Adam Yarborough (@LittleToyRobots)
#>
function Get-WinEventHelper {
[cmdletbinding(SupportsShouldProcess)]
param (
[Parameter(
ValueFromPipeline = $true,
ValueFromPipelineByPropertyName = $true)]
[string[]]$ComputerName = $env:COMPUTERNAME,
[Parameter()]
[string[]]$LogName,
[Parameter()]
[string[]]$ProviderName,
[Parameter()]
[int[]]$ID,
[Parameter()]
[int[]]$Level,
[Parameter()]
[string[]]$Data,
[Parameter()]
[int]$MaxEvents,
[Parameter()]
[datetime]$StartTime,
[Parameter()]
[datetime]$EndTime,
[Parameter()]
[Management.Automation.PSCredential]$Credential = [Management.Automation.PSCredential]::Empty
)
begin {
# Envorces most strict best practice
Set-StrictMode -Version Latest
$Stopwatch = [System.Diagnostics.Stopwatch]::StartNew()
Write-Debug "[$($MyInvocation.MyCommand)] --- BEGIN $($MyInvocation.MyCommand) ---"
foreach ($keyValue in $PSBoundParameters.GetEnumerator()) { Write-Debug "[$($MyInvocation.MyCommand)] param $($keyValue.Key) = $($keyValue.Value)" }
$FilterHash = @{ }
if ($PSBoundParameters.ContainsKey('LogName')) { $FilterHash['LogName'] = $LogName }
if ($PSBoundParameters.ContainsKey('ProviderName')) { $FilterHash['ProviderName'] = $ProviderName }
if ($PSBoundParameters.ContainsKey('ID')) { $FilterHash['ID'] = $ID }
if ($PSBoundParameters.ContainsKey('Data')) { $FilterHash['Data'] = $Data }
if ($PSBoundParameters.ContainsKey('Level')) { $FilterHash['Level'] = $Level }
if ($PSBoundParameters.ContainsKey('StartTime')) { $FilterHash['StartTime'] = $StartTime }
if ($PSBoundParameters.ContainsKey('EndTime')) { $FilterHash['EndTime'] = $EndTime }
$WinEventParams = @{ Verbose = $false; ErrorAction = 'Stop' }
if ($PSBoundParameters.ContainsKey('Credential')) { $WinEventParams['Credential'] = $Credential }
if ($PSBoundParameters.ContainsKey('MaxEvents')) { $WinEventParams['MaxEvents'] = $MaxEvents }
}
process {
Write-Debug "[$($MyInvocation.MyCommand)] --- PROCESS $($MyInvocation.MyCommand) ---"
$ComputerProgress = 1
$TotalEvents = 0
# Add the UserName(s) to the filter for faster results
Write-Progress -Activity 'Retrieving Event(s)'
foreach ($Computer in $ComputerName) {
$ComputerEvents = 0
Write-Progress -Activity 'Retrieving Event(s)' -Status "Computer: $Computer ($ComputerProgress / $($ComputerName.Count))" -PercentComplete (100 * $ComputerProgress / $ComputerName.Count)
try {
if ($PSCmdlet.ShouldProcess($Computer, 'retrieving events')) {
Write-Debug "[$($MyInvocation.MyCommand)] retrieving events from target ""$Computer"""
Get-WinEvent -ComputerName $Computer -FilterHashtable $FilterHash @WinEventParams | ForEach-Object {
$RetObject = [ordered]@{
TimeCreated = $_.TimeCreated
MachineName = $_.MachineName
ProviderName = $_.ProviderName
LogName = $_.LogName
ID = $_.ID
Keywords = $_.Keywords
KeywordsDisplayNames = $_.KeywordsDisplayNames
Level = $_.Level
LevelDisplayName = $_.LevelDisplayName
Message = $_.Message
}
# Adds all the event properties explicitly
([xml]$_.ToXml()).Event.EventData.Data | ForEach-Object {
try {
$RetObject[$_.Name] = if (Get-Member -InputObject $_ -Name '#text') { $_.'#text' } else { $null }
}
catch {
Write-Debug "[$($MyInvocation.MyCommand)] $($Error[0].Exception.Message) [$($Error[0].Exception.GetType().FullName)]"
}
}
$RetObject['PSComputerName'] = $Computer
[PSCustomObject]$RetObject
$ComputerEvents += 1
$TotalEvents += 1
}
}
}
catch {
if ('No events were found that match the specified selection criteria.' -eq $Error[0].Exception.Message) {
Write-Verbose "No events were found that match the specified selection criteria on target ""$Computer"""
Write-Debug "[$($MyInvocation.MyCommand)] $($Error[0].Exception.Message) [$($Error[0].Exception.GetType().FullName)]"
}
else {
Write-Warning "Problem retrieving events from target ""$Computer"""
Write-Debug "[$($MyInvocation.MyCommand)] $($Error[0].Exception.Message) [$($Error[0].Exception.GetType().FullName)]"
throw $error[0]
}
}
Write-Debug "[$($MyInvocation.MyCommand)] events retrieved from $Computer`: $ComputerEvents"
$ComputerProgress += 1
}
Write-Progress -Activity 'Retrieving Event(s)' -Completed
}
end {
Write-Debug "[$($MyInvocation.MyCommand)] total events retrieved: $TotalEvents"
$Stopwatch.Stop()
Write-Debug "[$($MyInvocation.MyCommand)] --- Duration: $($Stopwatch.Elapsed.Minutes) minutes, $($Stopwatch.Elapsed.Seconds) seconds, $($Stopwatch.Elapsed.Milliseconds) milliseconds"
Write-Debug "[$($MyInvocation.MyCommand)] --- END $($MyInvocation.MyCommand) ---"
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment