Remove-Item logging help

This topic contains 5 replies, has 3 voices, and was last updated by Profile photo of Troy Oosterwijk Troy Oosterwijk 2 years, 2 months ago.

  • Author
    Posts
  • #19144
    Profile photo of Troy Oosterwijk
    Troy Oosterwijk
    Participant

    Hello all,

    I was hoping to find some help regarding a line of script I've written.

    For my home situation, I've brewed together something that at one point, tries to delete some obsolete files (in this case .jpg files in my Music folder):

    get-childitem D:\Music\*.jpg -recurse -force| foreach ($_) {remove-item $_.fullname; Add-Content $LogFile "`nDeleting file: $_"} 

    For this, I also wanted the line to log exactly which files have been deleted with the part:

    Add-Content $LogFile

    This works just the fine. The variable LogFile contains all information I need, except for one thing....
    Whenever a file can't be deleted (because for example lack of permissions), the log will still show "Deleting file: something.jpg".

    Is it possible to also include the failed attempts at deleting a file, while still keeping the line as simple as possible?

    Thanks in advance,

    T.O.

  • #19145
    Profile photo of Dave Wyatt
    Dave Wyatt
    Moderator

    You'd need to use some sort of error detection code. In this case, a try/catch would be most appropriate. If you want to keep it all crammed onto one line, it might look something like this:

    Get-ChildItem D:\Music\*.jpg -recurse -force| ForEach-Object { $file = $_; try { Remove-Item $file.fullname -ErrorAction Stop; Add-Content $LogFile "`nDeleting file: $file" } catch { Add-Content $LogFile "`nError deleting file: $file, $_" } }
    

    Personally, I would prefer to split this onto multiple lines to make it easier to read, though:

    Get-ChildItem D:\Music\*.jpg -Recurse -Force |
    ForEach-Object {
        $file = $_
        try {
            Remove-Item $file.fullname -ErrorAction Stop
            Add-Content $LogFile "`nDeleting file: $file"
        } catch {
            Add-Content $LogFile "`nError deleting file: $file, $_"
        }
    }
    
  • #19146
    Profile photo of Sam Boutros
    Sam Boutros
    Participant

    Is this what you're looking for?

    Get-ChildItem D:\Music\*.jpg -Recurse -Force -File | % {
        try {
            Remove-Item -Path $_.fullname -Force -Confirm:$false -ErrorAction Stop
            "Deleted file: $($_.fullname)" | Out-File .\LogFile.txt -Append
        } catch {
            "Failed to delete file: $($_.fullname)" | Out-File .\LogFile.txt -Append        
        }
    }
    
  • #19148
    Profile photo of Dave Wyatt
    Dave Wyatt
    Moderator

    There's a good "gotcha" to be aware of in that code, Sam. When you enter a catch block, the $_ variable is overwritten to contain the terminating error that was caught. That's why I saved the value of $_ as of the beginning of the ForEach-Object block into another variable called $file first, in my example.

  • #19149
    Profile photo of Sam Boutros
    Sam Boutros
    Participant

    That's excellent to know Dave, thanks!

    We can use pipeline variable also (PS V4) like:

    Get-ChildItem D:\Music\*.jpg -Recurse -Force -File -PipelineVariable File | % {
        try {
            Remove-Item -Path $File.fullname -Force -Confirm:$false -ErrorAction Stop
            "Deleted file: $($File.fullname)" | Out-File .\LogFile.txt -Append
        } catch {
            "Failed to delete file: $($File.fullname)" | Out-File .\LogFile.txt -Append        
        }
    }
    
  • #19152
    Profile photo of Troy Oosterwijk
    Troy Oosterwijk
    Participant

    Thank you for your replies!

    Indeed the try/catch method is working perfectly. In the end, I've sacrificed my one-line wishes for a good working script.
    Sam&Dave, thank you for your help with this.

    Regards,

    T.O.

You must be logged in to reply to this topic.