Forum Discussion
Validating PowerShell operations - Delete file
- Jun 08, 2022
Hi, Rob.
The Try..Catch method mentioned by Harm_Veenstra is the best (though there's a good chance the "catch" won't be used since ErrorAction defaults to "Continue" instead of "Stop".)
However, since you mentioned "efficient" and "no need to check the file system", here are some minor adjustments that deliver against those requirements.
- Avoid storing results in variables unless it's unavoidable;
- Leverage the -ErrorAction:Stop parameter.
Point 1 allows scripts to scale up significantly better through not churning memory and allowing the GC (garbage collector) to release objects earlier, while point 2 allows you to avoid checking the file system after the Remove-Item.
I've spaced it out here for readability, but really, this could be a one-liner.
Get-ChildItem -Path "C:\Temp\" -Filter "*.jpg" | ForEach-Object { try { $FilePath = $_.FullName; Remove-Item -Path $FilePath -ErrorAction:Stop; "Deleted $FilePath."; } catch { "Failed to delete $FilePath."; } }
Cheers,
Lain
Edited to correct a typo.
If you set ErrorAction:Stop, will that terminate the script execution? I need the script to attempt deleting all files found and report if it succeeded or not.
For example, if Get-ChildItem collects 5 files, I need the script to attempt deleting all of these while tracking if an error occurred.
I am trying our both yours and Harm_Veenstra's code to see what works best.
Thank you!
Hey, Rob.
ErrorAction:Stop only causes execution of the current scope to exit.
When used in conjunction with the try...catch block, it will only halt processing within the "try" block and jump down to the "catch" block - which is what you want.
Only if ErrorAction:Stop were used in the main script body and outside of a try...catch block would it cause the script to exit - which is still useful in a lot of situations where subsequent actions depend on former ones completing successfully.
The default value for ErrorAction within PowerShell is "continue".
When you encounter an error under "continue" mode, the error is shown in red text - as you're accustomed to seeing - but the flow of execution is not interrupted, meaning execution simply moves onto the next line.
Using my code block as the example, if Remove-Item (on line 6) generates an error, execution will continue to line 7 as if nothing failed. We will never get into the catch block to run line 11 - which is what we actually wanted to happen.
By changing the ErrorAction to Stop, the error is still reported above in red text, but additionally, PowerShell honours the exception thrown by Remove-Item and jumps to the catch block, meaning line 11 finally gets used properly.
This is why if you do not specify ErrorAction:Stop, the catch block remains unused.
Try it yourself with the following basic test. The statement in the catch block never gets executed despite the error being reported.
try { Get-Item -Path abc:; "Life is good. No errors to see here, right?"; } catch { "What are you smoking?" }
And now again, but this time with ErrorAction:Stop.
try { Get-Item -Path abc: -ErrorAction:Stop; "Life is good. No errors to see here, right?"; } catch { "What are you smoking?" }
Here's the output from both purely for reference. You can see the second example does what's expected.
Cheers,
Lain