Get-PastEvents.psm1
<#
.SYNOPSIS Gather Last Event Logs with Parameter DaysPast .DESCRIPTION Gets Eventlogs based on System.Diagnostics.Eventing.Reader.EventLogQuery same as Eventvwr.msc, offers the Option to specify DaysPast to get All events that happend in the specified past timeframe .PARAMETER LogName Specify LogName to Search in .PARAMETER Type Specify Type (Error, Warning, Information) .PARAMETER EventID Specify Event ID for Results .PARAMETER DaysPast Specify Days Past in which Event happened .INPUTS One of the Above Parameter .OUTPUTS Event Logs applying to filter .EXAMPLE Get-EventLog -LogName Microsoft-ServerManagementExperience -Type Error,Warning -DaysPast 0.5 .EXAMPLE Get-EventLog -Type Error -DaysPast 0.1 .EXAMPLE Get-EventLog -LogName System -Type Error,Warning -EventID 610 -DaysPast 3 .NOTES Full Script and Function by CZ #> #Get-EventLog v3 function Get-PastEvents { Param( [CmdletBinding()] #LogName [Parameter(Mandatory=$false, Position=0, HelpMessage="Log Name")] [Alias("Log")] [string[]]$LogName, #$Filters #Type [Parameter(Mandatory=$false, HelpMessage="Entry Type")] [ValidateSet("Error","Warning","Information")] [string[]]$Type, #EventID [Parameter(Mandatory=$false, HelpMessage="Event ID")] [string[]]$EventID, #DaysPast [Parameter(Mandatory=$false, HelpMessage="Days Past")] [decimal]$DaysPast ) #Check for Administrator rights $currentPrincipal = New-Object Security.Principal.WindowsPrincipal([Security.Principal.WindowsIdentity]::GetCurrent()) IF (($currentPrincipal.IsInRole([Security.Principal.WindowsBuiltInRole]::Administrator)) -eq $false) { Write-Host "Get-EventLog: You do not have the required permission to complete this task. Contact the administrator of the authorization policy for the computer '$($Env:COMPUTERNAME)'." -ForegroundColor Red break } #Update Format data to support custom view (EventLogRecordView) for type: System.Diagnostics.Eventing.Reader.EventLogRecord Update-FormatData -AppendPath $PSScriptRoot\EventLogRecordView.ps1xml #Gather All Event Logs (rly not the way to do it) $AllEventLogs = (Get-ChildItem "C:\Windows\System32\winevt\Logs" -Filter "*.evtx" | Where-Object {$_.Length -gt 69632 -and $_.Name -notlike "*Operational.evtx"}).Name -replace "%4","/" -replace ".evtx","" #$AllEventLogs = [System.Diagnostics.Eventing.Reader.EventLogQuery]::new("Application",[System.Diagnostics.Eventing.Reader.PathType]::LogName).Session.GetLogNames() #Init $Filter=@();$level=@();$EventIDs=@();$Select=@() #Build Filter #Type IF ($null -ne $PSBoundParameters.Type){ $PSBoundParameters.Type | ForEach-Object { IF ($_ -eq "Error") {$level += "Level=2"} IF ($_ -eq "Warning") {$level += "Level=3"} IF ($_ -eq "Information") {$level += "Level=4"} } $Filter += $level | Join-String -OutputPrefix "*[System[(" -Separator " or " -OutputSuffix ")]]" } #EventID IF ($null -ne $PSBoundParameters.EventID){ $PSBoundParameters.EventID | ForEach-Object { $EventIDs += "EventID=$_" } $Filter += $EventIDs | Join-String -OutputPrefix "*[System[(" -Separator " or " -OutputSuffix ")]]" } #DaysPast IF ($null -ne $PSBoundParameters.DaysPast){ #1Day = 86400000 (ms) $DPms = $PSBoundParameters.DaysPast * 86400000 $Filter += "*[System[TimeCreated[timediff(@SystemTime) <= $DPms]]]" } #Build Filter $Script:Filter = $Filter $QueryFilter = $Filter | Join-String -Separator " and " #Write-Debug $QueryFilter #LogName IF ($null -ne $PSBoundParameters.LogName){ #$LogNameCount = $PSBoundParameters.LogName.count $PSBoundParameters.LogName | ForEach-Object { #$Select += $_ | Join-String -OutputPrefix $LogNameS = $_ | Join-String -FormatString '"{0}"' $Select += "<Select Path=$LogNameS>$QueryFilter</Select>" #Write-Debug $Select[-1] } } else { $AllEventLogs | ForEach-Object { $LogNameT = $_ | Join-String -FormatString '"{0}"' $Select += "<Select Path=$LogNameT>$QueryFilter</Select>" #Write-Debug $Select[-1] } } #Build Query $QueryID = 0 | Join-String -FormatString '"{0}"' $QueryPath = "Application" | Join-String -FormatString '"{0}"' [string]$Query = "<QueryList><Query Id=$QueryID Path=$QueryPath>$Select</Query></QueryList>" $Script:FunctionQuery = $Query #Write-Debug $Query #Event Reader, execute query $EventReader = [System.Diagnostics.Eventing.Reader.EventLogReader]::new( [System.Diagnostics.Eventing.Reader.EventLogQuery]::new( "Application",[System.Diagnostics.Eventing.Reader.PathType]::LogName,$Query ) ) #Gather EventLog Query Results $EventLog = @() $Continue = $true while ($Continue -eq $true) { try { $Entry = $EventReader.ReadEvent() IF ($Entry.Id -ne 0) { $EventLog += $Entry IF ($EventLog.count -gt 200 -and $choice -eq -1){UserConfirmation} } } catch { $Continue = $false #Write-Debug "Catch, end of results reached" } } #Format Output $EventLog | Sort-Object -Property TimeCreated -Descending #| Select-Object Level, TimeCreated, ID, ProviderName, Message } #Helper Functions #Promt for User Confirmation function UserConfirmation { [int]$DefaultChoice = 1 $Yes = [System.Management.Automation.Host.ChoiceDescription]::new("&Yes", "Continue, might take a while") $No = [System.Management.Automation.Host.ChoiceDescription]::new("&No", "Stop") $options = [System.Management.Automation.Host.ChoiceDescription[]]($yes, $no) $choice = $host.ui.PromptForChoice("$($EventLog.count), Results","Continue? `nMight take a while", $options,$DefaultChoice) if ($choice -eq 0) { } else { break } } #New Auto Completeion Result function New-CompletionResult { param( [Parameter(Mandatory)] [string]$CompletionText, [string]$ListItemText = $CompletionText, [System.Management.Automation.CompletionResultType]$CompletionResultType = [System.Management.Automation.CompletionResultType]::ParameterValue, [string]$ToolTip = $CompletionText ) New-Object System.Management.Automation.CompletionResult $CompletionText, $ListItemText, $CompletionResultType, $ToolTip } #Auto Completeion Provider for LogName function LogNameCompletion { param ( $commandName, $ParameterName, $WordToComplete, $CommandAst, $FakeBoundParameter ) $AllEventLogs = (Get-ChildItem "C:\Windows\System32\winevt\Logs" -Filter "*.evtx" | Where-Object {$_.Length -gt 69632 -and $_.Name -notlike "*Operational.evtx"}).Name -replace "%4","/" -replace ".evtx","" $AllEventLogs | Where-Object { $_.StartsWith($wordToComplete); } | ForEach-Object { New-CompletionResult -CompletionText $_ } } #Register Argument Completer Register-ArgumentCompleter -CommandName Get-EventLog -ParameterName LogName -ScriptBlock $function:LogNameCompletion |