Captured data in variable not listed in final out-file .txt output...

Hi all,

I wrote the following script to pull event IDs relating to CVE-2020-1472 which works fine, except it does not write the value of the $Err variable to my final text export

Running the script in ISE I can view the content of $Err and see its value in the final collection but for some reason it will not appear in my final export, I thought it was due to the variable being an object rather than a string but this seems to not be the case can anyone help?

import-module activedirectory
$Results = @()
$ID = 5827,5828,5829,5830,5831
$OutFile = Join-Path "$env:USERPROFILE"Desktop""\"$env:USERDNSDOMAIN"-ServerEventIDList-"$(get-date -f ddMMyyyy)".txt""
#$ErrorActionPreference = 'continue'
$Date = (Get-Date).AddDays(-60)
$Servers = Get-ADDomainController -filter * | select hostname | foreach {$_.hostname}
foreach ($Server in $Servers){
Write-Host 'Checking System event logs of server'$Server -ForegroundColor Cyan
try{
$GetEvent = Get-WinEvent -FilterHashtable @{LogName='System'; StartTime=$Date; Id= $ID } -computername $Server -ErrorAction Stop
write-host $EventDetail -ForegroundColor red
foreach($ev in $GetEvent){
$EventDetail = [PScustomObject] @{
"Server" = $Server
"EventID" = $GetEvent.Id
"EventDetail" = $GetEvent.message}
$Results += $EventDetail
}
}
catch [Exception] {
if ($_.Exception -match "No events were found that match the specified selection criteria"){
$Err = ($_.exception.message)
$ErrorDetail = [PScustomObject] @{
"Server" = $Server
"EventID" = $ID
"Error" = $Err}
write-host 'No event Id:'$ID' was found within the system logs of '$Server -ForegroundColor green
$Results += $ErrorDetail
}
}
}
$Results | out-file $OutFile

Thanks!

lines 16 and 17 should reference $ev not $GetEvent

Thank you Sam,

I have corrected those lines and the script runs as expected for the first part of the data capture

However, I cannot understand why after running the script the values $ErrorDetail and $Err both contain the exception.message value as a string but it is not placed into my final txt file?

import-module activedirectory
$Results = @()
$ID = 5827,5828,5829,5830,5831
$OutFile = Join-Path "$env:USERPROFILE"Desktop""\"$env:USERDNSDOMAIN"-ServerEventIDList-"$(get-date -f ddMMyyyy)".txt""
$Date = (Get-Date).AddDays(-60)
$Servers = Get-ADDomainController -filter * | select -ExpandProperty hostname 
foreach ($Server in $Servers){
    Write-Host 'Checking System event logs of server'$Server -ForegroundColor Cyan
        try{
            $GetEvent = Get-WinEvent -FilterHashtable @{LogName='System'; StartTime=$Date; Id= $ID } -computername $Server -ErrorAction Stop
            write-host $EventDetail -ForegroundColor red
            foreach($Ev in $GetEvent){
            $EventDetail = [PScustomObject] @{
                "Server" = $Server
                "EventID" = $Ev.Id
                "EventDetail" = $Ev.message
            }
            $Results += $EventDetail
                                                                                     }
       }
       catch [Exception] {
           if ($_.Exception -match "No events were found that match the specified selection criteria"){
               $Err = ($_.exception.message)
               $ErrorDetail = [PScustomObject] @{
                    "Server" = $Server
                    "EventID" = $ID
                    "Error" = $Err
               }
               write-host 'No event Id:'$ID' was found within the system logs of '$Server -ForegroundColor green
               $Results += $ErrorDetail
           }
       }
}
$Results | out-file $OutFile

Try the code below. Not sure why [Exception] is specified in the catch unless you are catching a named exception the catch catches exceptions and why you are only catching an exception if no results are returned as you want to identify other issues with data collection. When you have the data collected, you can simply filter the exceptions (e.g. $results | Where{$_.EventDetail -like “No events were found that match the specified selection criteria”}). The results object should have the same schema Server, EventId, EventDetail and you can just put a filter phrase for Errors, like [ERROR] or something else unique. The results can bubble up to the $results variable rather than += operations. Lastly, you go through all of the work of collecting the data into an object and then write to a file as plain text, why not export as a CSV to maintain the structure?

Import-Module activedirectory

$ID = 5827,5828,5829,5830,5831
$OutFile = Join-Path "$env:USERPROFILE"Desktop""\"$env:USERDNSDOMAIN"-ServerEventIDList-"$(get-date -f ddMMyyyy)".txt""
#$ErrorActionPreference = 'continue'
$Date = (Get-Date).AddDays(-60)
$Servers = Get-ADDomainController -Filter * | Select-Object -ExpandProperty HostName

$results = foreach ($Server in $Servers){
    Write-Host 'Checking System event logs of server'$Server -ForegroundColor Cyan
    try{
        $GetEvent = Get-WinEvent -FilterHashtable @{LogName='System'; StartTime=$Date; Id= $ID } -computername $Server -ErrorAction Stop
        write-host $EventDetail -ForegroundColor red
        foreach($ev in $GetEvent){
        
            [pscustomObject] @{
                "Server"      = $Server
                "EventID"     = $ev.Id
                "EventDetail" = $ev.message
            }
        }
    }
    catch {
        #Not sure why you need this if.  If an exception occurs, why would you not want to capture what the error was?
        #if ($_.Exception.Message -like "*No events were found that match the specified selection criteria*"){
            
            [pscustomObject] @{
                "Server"  = $Server
                "EventID" = $ID
                "EventDetail"   = '[ERROR] - {0}' -f $_.exception.message
            }

            write-host 'No event Id:'$ID' was found within the system logs of '$Server -ForegroundColor green
        #}
    }
}

$Results | Export-Csv -Path $OutFile -NoTypeInformation

Thank you Rob for your detailed explanation, I see now how the collections do not need to be assigned to a variable

Also I agree with your statement that I would indeed want to collect all errors

Thanks for all of your help guys!