Compare commits

...
2 Commits
Author SHA1 Message Date
dyoder 4a7e0642ef more fixes 2026-07-08 12:00:25 -04:00
dyoder 3470464b1d fix an error 2026-07-08 11:56:10 -04:00
+86 -34
View File
@@ -36,6 +36,33 @@ Function Test-ActivityDateRangeValue {
Return $true
}
Function Get-UserLogonActivityErrorMessage {
Param(
[AllowNull()]
[object]$ErrorRecord,
[string]$FallbackMessage = 'Unknown error.'
)
$Message = ''
If ($null -ne $ErrorRecord) {
If ($null -ne $ErrorRecord.Exception) {
$Message = [string]$ErrorRecord.Exception.Message
}
If ([string]::IsNullOrWhiteSpace($Message)) {
$Message = [string]$ErrorRecord
}
}
If ([string]::IsNullOrWhiteSpace($Message)) {
$Message = $FallbackMessage
}
Return $Message
}
$StartHasValue = ($null -ne $StartVariable -and (Test-ActivityDateRangeValue -Value $StartVariable.Value))
$EndHasValue = ($null -ne $EndVariable -and (Test-ActivityDateRangeValue -Value $EndVariable.Value))
@@ -572,9 +599,18 @@ Function Get-UniqueUserLogonActivity {
Function Write-UserLogonActivityOutput {
Param(
[AllowNull()]
[object[]]$ActivityEvents
[object[]]$ActivityEvents,
[Parameter(Mandatory=$true)]
[DateTimeOffset]$StartDateTime,
[Parameter(Mandatory=$true)]
[DateTimeOffset]$EndDateTime
)
Write-Output "Search window: $($StartDateTime.LocalDateTime.ToString('yyyy-MM-dd HH:mm:ss')) through $($EndDateTime.LocalDateTime.ToString('yyyy-MM-dd HH:mm:ss'))"
Write-Output ''
$Rows = @($ActivityEvents | Select-Object Date,Time,User,Activity,Source,Details)
If ($Rows.Count -eq 0) {
@@ -585,13 +621,38 @@ Function Write-UserLogonActivityOutput {
Write-Output (($Rows | Format-Table -AutoSize | Out-String -Width 240).TrimEnd())
}
Function Test-RedundantSessionReconnectUnlock {
Param(
[Parameter(Mandatory=$true)]
[object]$ActivityEvent,
[AllowNull()]
[object[]]$ActivityEvents
)
If ($ActivityEvent.Activity -ne 'unlock' -or $ActivityEvent.Source -ne 'Security 4624 type 7') {
Return $false
}
ForEach ($CandidateEvent in @($ActivityEvents)) {
If (
$CandidateEvent.Activity -eq 'session reconnect' -and
[Math]::Abs(($CandidateEvent.TimeCreated - $ActivityEvent.TimeCreated).TotalSeconds) -le 5
) {
Return $true
}
}
Return $false
}
Function Get-PossibleUseWindow {
Param(
[AllowNull()]
[object[]]$ActivityEvents
)
$OpenWindows = @{}
$OpenWindow = $null
$UseWindows = New-Object System.Collections.Generic.List[object]
$OpeningActivities = @('logon', 'unlock', 'remote logon', 'session reconnect', 'screensaver dismiss')
$ImpliedClosureDescriptions = @{
@@ -600,19 +661,19 @@ Function Get-PossibleUseWindow {
'screensaver dismiss' = 'implied prior screensaver before'
}
ForEach ($ActivityEvent in (@($ActivityEvents) | Where-Object { $null -ne $_ } | Sort-Object -Property TimeCreated)) {
$OrderedActivityEvents = @($ActivityEvents | Where-Object { $null -ne $_ } | Sort-Object -Property TimeCreated)
ForEach ($ActivityEvent in $OrderedActivityEvents) {
$User = [string]$ActivityEvent.User
$UserKey = [string]$ActivityEvent.UserKey
$Activity = [string]$ActivityEvent.Activity
$Source = [string]$ActivityEvent.Source
If ([string]::IsNullOrWhiteSpace($UserKey)) {
$UserKey = Get-UserLogonActivityKey -Sid $null -User $User
If (Test-RedundantSessionReconnectUnlock -ActivityEvent $ActivityEvent -ActivityEvents $OrderedActivityEvents) {
Continue
}
If ($Activity -in @('sleep', 'shutdown', 'restart')) {
ForEach ($OpenUserKey in @($OpenWindows.Keys)) {
$OpenWindow = $OpenWindows[$OpenUserKey]
If ($Activity -in @('logoff', 'lock', 'session disconnect', 'sleep', 'shutdown', 'restart')) {
If ($null -ne $OpenWindow) {
$UseWindows.Add([PSCustomObject]@{
StartTime = $OpenWindow.StartTime
Start = $OpenWindow.StartTime.ToString('yyyy-MM-dd HH:mm:ss')
@@ -621,7 +682,7 @@ Function Get-PossibleUseWindow {
StartedBy = $OpenWindow.StartedBy
EndedBy = "${Activity} / ${Source}"
}) | Out-Null
$OpenWindows.Remove($OpenUserKey)
$OpenWindow = $null
}
Continue
@@ -632,8 +693,7 @@ Function Get-PossibleUseWindow {
}
If ($Activity -in $OpeningActivities) {
If ($OpenWindows.ContainsKey($UserKey) -and $ImpliedClosureDescriptions.ContainsKey($Activity)) {
$OpenWindow = $OpenWindows[$UserKey]
If ($null -ne $OpenWindow -and $ImpliedClosureDescriptions.ContainsKey($Activity)) {
$UseWindows.Add([PSCustomObject]@{
StartTime = $OpenWindow.StartTime
Start = $OpenWindow.StartTime.ToString('yyyy-MM-dd HH:mm:ss')
@@ -642,35 +702,20 @@ Function Get-PossibleUseWindow {
StartedBy = $OpenWindow.StartedBy
EndedBy = "$($ImpliedClosureDescriptions[$Activity]) ${Activity} / ${Source}"
}) | Out-Null
$OpenWindows.Remove($UserKey)
$OpenWindow = $null
}
If (-not $OpenWindows.ContainsKey($UserKey)) {
$OpenWindows[$UserKey] = [PSCustomObject]@{
If ($null -eq $OpenWindow) {
$OpenWindow = [PSCustomObject]@{
StartTime = $ActivityEvent.TimeCreated
User = $User
StartedBy = "${Activity} / ${Source}"
}
}
}
ElseIf ($Activity -in @('logoff', 'lock', 'session disconnect')) {
If ($OpenWindows.ContainsKey($UserKey)) {
$OpenWindow = $OpenWindows[$UserKey]
$UseWindows.Add([PSCustomObject]@{
StartTime = $OpenWindow.StartTime
Start = $OpenWindow.StartTime.ToString('yyyy-MM-dd HH:mm:ss')
End = $ActivityEvent.TimeCreated.ToString('yyyy-MM-dd HH:mm:ss')
User = $OpenWindow.User
StartedBy = $OpenWindow.StartedBy
EndedBy = "${Activity} / ${Source}"
}) | Out-Null
$OpenWindows.Remove($UserKey)
}
}
}
ForEach ($OpenUserKey in @($OpenWindows.Keys)) {
$OpenWindow = $OpenWindows[$OpenUserKey]
If ($null -ne $OpenWindow) {
$UseWindows.Add([PSCustomObject]@{
StartTime = $OpenWindow.StartTime
Start = $OpenWindow.StartTime.ToString('yyyy-MM-dd HH:mm:ss')
@@ -769,7 +814,7 @@ Try {
}
}
Catch {
Write-Error $_.Exception.Message
Write-Error (Get-UserLogonActivityErrorMessage -ErrorRecord $_ -FallbackMessage 'Unable to resolve the activity date range.')
Exit 1
}
@@ -816,5 +861,12 @@ ForEach ($PowerFilter in $PowerFilters) {
}
$OutputEvents = @(Get-UniqueUserLogonActivity -ActivityEvents $ActivityEvents | Sort-Object -Property TimeCreated)
Write-UserLogonActivityOutput -ActivityEvents $OutputEvents
Write-PossibleUseWindowOutput -ActivityEvents $OutputEvents
Write-UserLogonActivityOutput -ActivityEvents $OutputEvents -StartDateTime $StartDateTime -EndDateTime $EndDateTime
Try {
Write-PossibleUseWindowOutput -ActivityEvents $OutputEvents
}
Catch {
$PossibleUseWindowError = Get-UserLogonActivityErrorMessage -ErrorRecord $_ -FallbackMessage 'Unable to infer possible use windows.'
Write-Output ''
Write-Output "Possible use windows inferred from returned events: unavailable. ${PossibleUseWindowError}"
}