3

I have a PowerShell script that gets a list of file names from a file, searches a folder for the file names, archives them, and then does other stuff.

#make non-terminating errors behave like terminating errors (at script level)
$ErrorActionPreference = "Stop"

#set the folder that has the list and the files
$some_path = "D:\some_folder\"
$archive = "D:\archive\"

#set the list file name
$file_list = $some_path + "file_list.txt"

#get the files that I'm searching for from this list file
$files_to_retrieve = Select String -Path $file_list -Pattern "something" | Select-Object Line

#get the number of files for this search string
$n = $file_list.Length - 1

#seed the while loop counter
$i = 0

#while loop to archive and modify the files
While ($i -le $n)
{
    #set the current file name
    $current_file = $path + $files_to_retrieve[$i].Line

    try
    {
        Copy-Item -Path $current_file -Destination $archive_path
    }
    catch
    {
        Write-Host ("file " + $files_to_retrieve[$i].Line + " not found")
    }

    $data = Get-Content $current_file

    #do modifications here
}

The try-catch isn't working as expected. I have a file name in the file list that is not present in $some_path. I was expecting try-catch to stop the execution and do the Write-Host. Instead, it doesn't run the Write-Host and continues to the $data = Get-Content $current_file step, which is throwing a terminating error because the path doesn't exist for the missing file. How can I fix this?

3
  • I would recommend you to put a write-host output into your try block and check whether the file that is not present is realy tried to get copied. Commented Oct 31, 2015 at 23:02
  • I just put this code outside of the current While loop and into its own While loop. (If files are not existent when they should be, I don't want to even attempt to modify them.) In this separate While loop, I put a Write-Host in the try block. The Write-Host displays. So, the try is indeed being attempted. The Write-Host in the catch also displays. That tells me that try is indeed encountering an error. If I put an Exit (non-zero) at the end of the catch, the script stops. If I don't, it continues with the next step in the While loop. Commented Nov 1, 2015 at 20:11
  • Possible duplicate of Try/catch does not seem to have an effect Commented Jul 15, 2017 at 13:29

1 Answer 1

6

Your first problem is the try/catch as you know. Taking a brief look at the documentation for about_Try_Catch_Finally you will see that..

Use Try, Catch, and Finally blocks to respond to or handle terminating errors in scripts.

Your Copy-Item line is not throwing a terminating error. We fix that with the common parameter -ErrorAction

Copy-Item -Path $current_file -Destination $archive_path -ErrorAction Stop

So if there is a problem then the Catch block should be called. Assuming that was the real issue there.


You have another issue I think as well that might just be a typo. I see the following snippet more than once.

$file_list[$i].Line

Earlier you have declared $file_list as "D:\some_folder\file_list.txt" which is a string. I think what you meant to have is below. The above code would be null since string dont have a line property. But the return from Select-String can!

$files_to_retrieve[$i].Line
Sign up to request clarification or add additional context in comments.

7 Comments

In addition to the above : I sometimes also need to set the -WarningAction variable to stop (causing a terminating error) to catch warnings in Powershell since some "errors" are logged as warnings in some Powershell CMDlets.
Doesn't setting $ErrorActionPreference = "Stop" at the script level negate the need to set -ErrorAction Stop in every try-catch?
@Matt: You are correct about my typo. I meant to write $files_to_retrieve[$i].Line. I have updated the post.
Also, I tried the -ErrorAction Stop after the Copy-Item. It's not working. When I run the Copy-Item outside of the script, it throws a terminating error there. But, when I run the script, it writes the statement in my catch (indicating that the catch is indeed being called), but doesn't actually terminate there. It attempts the Get-Content and throws the terminating error there. I suspect something about it being contained in my while loop is making it jump to the next cmdlet.
@user3100444 the catch is meant for you to address the error state. It wont stop the script from executing once it completes. In your code $data = Get-Content $current_file will always execute. If you don't want it that way you need to change your code
|

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.