Created
October 7, 2021 00:53
-
-
Save littletoyrobots/bcd78f4bc27f721dc5da65fb7cbebde2 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<# | |
.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