I am working on a try/catch/finally script to do some error reporting of files that don't exist. Yes, I am working on Log4j. This is what I have so far.
$fileList = Get-Content "blah blah"
foreach ($file in $fileList)
{
try {
Get-Item $file
Set-ItemProperty $file -Name IsReadOnly -Value $false
zip -d $file org/apache/logging/log4j/core/lookup/JndiLookup.class
Set-ItemProperty $file -Name IsReadOnly -Value $true
}
catch
{
Write-Error "$file not found."
}
finally
{
$null = $errorreport
}
}
$errorreport | Out-File "blah blah.csv"
For some reason, it puts jibberish into the output file and won't write the files into the csv that do not exist or the machine is not on. My guess is that it has something to do with the catch part but I can't figure it out.
Any help with this would be appreciated as I am a newbie when it comes to try/catch/finally things.
Thanks much!
CodePudding user response:
Tugger,
You need to add an -ErrorAction Stop switch to your Get-Item. Here's a test program to demonstrate.
Try {
Get-Item -Path "G:\Test\Junkfile.txt"
"No Error Detected"
}
Catch { "Error Detected!"}
Finally {"I'm done here."}
Sample Output:
Get-Item : Cannot find path 'G:\Test\Junkfile.txt' because it does not exist.
At line:3 char:4
Get-Item -Path "G:\Test\Junkfile.txt"
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
CategoryInfo : ObjectNotFound: (G:\Test\Junkfile.txt:String) [G
et-Item], ItemNotFoundException
FullyQualifiedErrorId : PathNotFound,Microsoft.PowerShell.Commands.GetIt
emCommand
No Error Detected
I'm done here.
It you then add the -ErrorAction Stop to the Get-Item line you get:
Error Detected!
I'm done here.
CodePudding user response:
As RetiredGeek explains, you need to use -ErrorAction Stop to capture both terminating and non-terminating errors in the catch block.
You don't need the finally block and I would suggest to output an object inside the catch so you can write that to a proper CSV fie afterwards:
$fileList = Get-Content "X:\blah blah.txt"
# loop through the file paths and capture error messages in a variable
$errorreport = foreach ($file in $fileList) {
try {
$fileObject = Get-Item $file -ErrorAction Stop # enters the catch block on errors
$isReadOnly = $fileObject.IsReadOnly
$fileObject.IsReadOnly = $false
# I cannot check if this is correct...
zip -d $file org/apache/logging/log4j/core/lookup/JndiLookup.class
$fileObject.IsReadOnly = $isReadOnly
}
catch {
# in here, the $_ automatic variable represents the actual exception
Write-Host "Error processing '$file': $($_.Exception.Message)" -ForegroundColor Red
# output an object with the file and exception message for the CSV
[PsCustomObject]@{
File = $file
Error = $_.Exception.Message
}
}
}
# write the error report as proper CSV file
$errorreport | Export-Csv -Path "X:\blah blah.csv" -NoTypeInformation
CodePudding user response:
I am not a pro and not sure this will help but it is easier to do this in an answer section.
$fileList = Get-Content "blah blah"
foreach ($file in $fileList) {
try {
Get-Item $file
Set-ItemProperty $file -Name IsReadOnly -Value $false
zip -d $file org/apache/logging/log4j/core/lookup/JndiLookup.class
Set-ItemProperty $file -Name IsReadOnly -Value $true
$errorreport = [PSCustomObject]@{
FileName = $file
}
}
catch {
Write-Error "$file not found."
}
finally {
$null = $errorreport
}
}
If ($errorreport) {
$errorreport | Out-File "blah blah.csv"
}
Else {
write-error "Problem"
}
The key part you are missing is you are not putting anything to export into $ErrorReport
What are your goals?
What are you trying to report?
my answer might not be great because you haven't given us enough direction.
If i was to do something like you are i would do this as follows.
$fileList = Get-Content "blah blah"
$Result = $fileList | ForEach-Object {
$null = $errorreport
try {
Get-Item $_
Set-ItemProperty $_ -Name IsReadOnly -Value $false
zip -d $_ org/apache/logging/log4j/core/lookup/JndiLookup.class
Set-ItemProperty $_ -Name IsReadOnly -Value $true
}
catch {
Write-Error "$_ not found."
$errorreport = $true
}
[PSCustomObject]@{
FileName = $_
Error = $errorreport
}
}
$Result | Out-File "blah blah.csv" -NoTypeInformation
================Only Errors export if any. ==========below
$fileList = $null
$fileList = Get-Content "blah blah"
$Result = $null
$Result = $fileList | ForEach-Object {
$null = $errorreport
try {
Get-Item $_
Set-ItemProperty $_ -Name IsReadOnly -Value $false
zip -d $_ org/apache/logging/log4j/core/lookup/JndiLookup.class
Set-ItemProperty $_ -Name IsReadOnly -Value $true
}
catch {
Write-Error "$_ not found."
$errorreport = $true
[PSCustomObject]@{
FileName = $_
Error = $errorreport
}
}
}
If ($Result) {
$Result | Out-File "blah blah.csv" -NoTypeInformation
}
Else {
Write-host "No errors found"
}
The others above me probably did this better
